2011-10-28 25 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フィールドに格納される。我々は2つのDEALLOCATE間の線を変更する場合は、これにディレクティブをPREPARE:

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

を私たちは「近く文の構文をチェックすることを教えてくれるのエラーを取得しますか? VALUES(5) '。

テーブル名にパラメータマーカーを代用することはできませんか?私はSELECTの行に沿って何かをやってみたことがありませんか? FROM Foo 'がまだ動作するかどうか確認してください。また、重要かどうかわかりませんが、コマンドラインではなく、MySQL Workbench 5.2.35 CEを使用してこれを試しています。

プロシージャーATM内でプリペアドステートメントとしてクエリを実行する必要は特にありません。必要な場合は、正しい構文を使用していることを確認してください。

答えて

2

パラメータ '?'識別子には使用できません。最初の変種を使用してください。参照から - パラメータ・マーカーは、SQLキーワード、識別子などではなく、データ値が表示される場所でのみ使用できます。

1

テーブル名にパラメータマーカーを代用することはできませんか?

いいえ、不可能です。この機能が必要だと思われる場合は、テーブルデザインが悪いという兆候かもしれません。

実際にが実行時にテーブルを指定する必要がある場合は、動的SQLを使用できますが、SQLインジェクションの脆弱性を導入しないように注意してください。

+0

興味深い... INSERTステートメントは特に重要ではありませんでした。私はいくつかの一般的なタスクのためのいくつかの汎用ストアドプロシージャを作成したいと考えていました。具体的には、[このページ](http://www.artfulsoftware.com/mysqlbook/sampler/mysqled1ch20.html)のPersonName関数の行に沿って、特定のテーブルに結び付けられていないものを適用したいと考えました。私はそれがなぜ悪い考えになるのか理解することができます。 – xobicvap