2011-12-02 6 views
1

私は、ストアドプロシージャ内のテーブル名として変数を使用しようとしていますが、実際のテーブル名ではなく文字列リテラルとして使用しています。どうしてこれなの?私はこれをやっていなければならない別の方法がありますか?ストアドプロシージャのテーブル名として変数を使用できないのはなぜですか?

DROP PROCEDURE IF EXISTS settonull; 

DELIMITER // 

CREATE PROCEDURE settonull() 
BEGIN 
    DECLARE done INT DEFAULT FALSE; 
    DECLARE _tablename VARCHAR(255); 
    DECLARE _columnname VARCHAR(255); 
    DECLARE cur1 CURSOR FOR SELECT CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) AS table_name, COLUMN_NAME AS column_name FROM information_schema.COLUMNS WHERE IS_NULLABLE = 'YES' AND TABLE_SCHEMA = 'blip_notify' AND table_name = 'notify_queue' LIMIT 1; 

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 

    OPEN cur1; 

    read_loop: LOOP 
    FETCH cur1 INTO _tablename, _columnname; 

    IF done THEN 
     LEAVE read_loop; 
    END IF; 

    UPDATE _tablename SET _columnname = NULL WHERE LENGTH(TRIM(_columnname)) = 0; 

    END LOOP; 

    CLOSE cur1; 
END// 

DELIMITER ; 

CALL settonull(); 

出力:

0 row(s) affected, 1 warning(s) 

Execution Time : 0 sec 
Transfer Time : 1.094 sec 
Total Time  : 1.095 sec 

Note Code : 1305 
PROCEDURE settonull does not exist 
--------------------------------------------------- 

0 row(s) affected 

Execution Time : 0.002 sec 
Transfer Time : 1.011 sec 
Total Time  : 1.014 sec 
--------------------------------------------------- 

Query: call settonull() 

Error Code: 1146 
Table 'blip_notify._tablename' doesn't exist 

Execution Time : 0 sec 
Transfer Time : 0 sec 
Total Time  : 0.003 sec 
--------------------------------------------------- 
+0

http://stackoverflow.com/questions/8362245/updating-empty-string-to-null-for-entire-databaseを解決するために私がこれを試していたことに注意してください。 – hafichuk

答えて

6

動的SQLを使用する必要があります。ええ、うー。

SET @s = CONCAT('UPDATE ', _tablename, ' SET ', _columnname, ' = NULL WHERE LENGTH(TRIM(', _columnname, ')) = 0'); 
PREPARE stmt FROM @s; 
EXECUTE stmt; 
3

変数には、テーブル識別子ではなく文字列値(または他のデータ型)が含まれます。

SQLクエリの各部分を文字列として連結し、その文字列をSQL文としてPREPARE and EXECUTEに連結すると、ストアドプロシージャで必要な処理を実行できます。

しかしFWIW、私はPHPでそれをやるだけです。

mysql_real_escape_string()のようなエスケープ機能はテーブル名に役立たないので、SQLクエリにテーブル名を動的に追加するときにSQLインジェクションの脆弱性にも注意してください。私のプレゼンテーションSQL Injection Myths and Fallaciesの "ホワイトリストマップ"の私の解決策を見てください。

関連する問題