-7
CREATE PROCEDURE P1 (
    IN input TEXT
    , IN `delimiter` VARCHAR(10)
    , IN `column1` VARCHAR(10)
    , IN `value1` VARCHAR(10)
    )
BEGIN


    SET @a = column1;
    SET @b = value1;

    select @a,@b;

    SET @c = CONCAT('INSERT INTO SplitValues2(',@a,') VALUES (',@b,')');

    select @c;
    PREPARE stmt FROM @c;

    select stmt;
    EXECUTE stmt;

 END
4

1 に答える 1

2

引用符で囲まれていない文字列を準備済みステートメントに連結しています。次のように呼び出すとP1します。

CALL P1('qux', 'foo', 'bar');

次に@c、次の文字列が含まれます。

INSERT INTO SplitValues2(foo) VALUES (bar)

fooという名前の列と という名前の他の識別子を参照しているため、これはおそらくあなたが望んでいたものではありませんbar。MySQL のQUOTE()関数を使用して、文字列値を適切に引用することを検討してください。

SET @c = CONCAT('INSERT INTO SplitValues2(',@a,') VALUES (',QUOTE(@b),')');

または、実行時に渡されるように、準備されたステートメント内の変数をパラメーター化することをお勧めします。

SET @c = CONCAT('INSERT INTO SplitValues2(',@a,') VALUES (?)');
PREPARE stmt FROM @c;
EXECUTE stmt USING @b;

SQL 識別子 (列名など) をパラメータ化することも、 を使用してそのような識別子を引用することもできないことに注意してくださいQUOTE()。したがって、SQL インジェクション攻撃を回避するには、手動でクォートしてエスケープする必要があります。

SET @c = CONCAT('INSERT INTO SplitValues2(`',REPLACE(@a,'`','``'),'` VALUES (?)');
于 2012-06-11T10:21:23.557 に答える