2011-10-28 103 views
1

我今天通过this section of the MySQL documentation了解到准备好的语句不能在存储函数中执行,但是从MySQL版本5.0.13开始,它们可以在存储过程中执行。mysql存储过程奇怪

今天我正在把一个存储过程放在一起,并认为最初尝试在INSERT语句中做一个准备语句可能很有趣。然而,尽管这应该是可能的(我正在使用MySQL 5.5.14),但?语句字符串中的参数标记导致MySQL引发语法错误。

我使用与用于准备好的INSERT语句相同的语法完成了一些简化示例。我希望我只是有一个语法错误,我没有抓到。下面的第一个块是可以使用的过程,即它使用标准CONCAT(您的查询字符串)语法。

DROP PROCEDURE IF EXISTS TestConc; 
DELIMITER $$ 

CREATE Procedure TestConc() 
BEGIN 
    SET @sql := CONCAT('CREATE TABLE Foo (FooID INT) ENGINE = InnoDB'); 
    PREPARE stmt FROM @sql; 
    EXECUTE stmt; 
    DEALLOCATE PREPARE stmt; 

    SET @tn := 'Foo'; 
    SET @sql := CONCAT('INSERT INTO ', @tn, ' VALUES (5)'); 
    PREPARE stmt FROM @sql; 
    EXECUTE stmt; 
    DEALLOCATE PREPARE stmt; 
END; 
$$ 
DELIMITER ; 

用此代码调用过程后,预期发生; 5存储在新生成的Foo表的FooID字段中。但是,如果我们改变两个DEALLOCATE之间的生产线就能生产指令到这一点:

SET @tn := 'Foo'; 
SET @sql := 'INSERT INTO ? VALUES (5)'; 
PREPARE stmt FROM @sql; 
EXECUTE stmt USING @tn; 

我们得到的是告诉我们要检查语句附近的“语法错误? VALUES(5)'。

是不是可以用参数标记替换表名?我还没有尝试过做'SELECT?从富'看看这是否会工作。另外,我不知道它是否重要,我一直在尝试使用MySQL Workbench 5.2.35 CE,而不是命令行。

我没有任何具体的需要在程序ATM中作为预处理语句运行查询,我只是想确保我有这样做的语法,如果我需要的话。

回答

2

参数'?'不能用于标识符。使用第一个变体。从参考 - 参数标记只能用于出现数据值的地方,而不能用于SQL关键字,标识符等等。

1

是不是可以用参数标记替换表名?

不,这是不可能的。如果你认为你需要这个功能,那可能是你的桌子设计不好的标志。

如果你真的需要在运行时指定表,可以使用动态SQL但注意不要引入SQL注入漏洞。

+0

有趣...... INSERT语句并不特别重要;我希望为一些常见任务创建一些通用存储过程。具体来说,我想根据[本页](http://www.artfulsoftware.com/mysqlbook/sampler/mysqled1ch20.html)上的PersonName函数的行来调整某些内容,使其与特定表格无关。不过,我明白为什么这是一个糟糕的主意。 – xobicvap