2011-10-28 145 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