sql >> データベース >  >> RDS >> Mysql

MySQLストアドプロシージャプリペアドステートメント(動的SQL)パラメータ化

    EXECUTE ステートメントには固定の引数リストを指定する必要があるため、およびを準備する必要があります。 IF / THEN / ELSEでステートメントを実行します ブロック。

    IF articlesModule = 1 THEN
        SET @query = ... UNION ...
        PREPARE stmt FROM @query;
        EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
    ELSE
        SET @query = ...; /* no UNION */
        PREPARE stmt FROM @query;
        EXECUTE stmt USING @searchWordIn, @searchWordIn;
    END IF;
    

    MySQLストアドプロシージャ言語の限られた範囲でこれを解決する方法がわかりません。私にとって、ストアドプロシージャで動的SQLを使用しないもう1つの理由があります。

    コメントを再確認してください:

    なるほど... CASE ステートメント IF / THEN / ELSEの代わりに 、ただし、クエリ文字列には2 =128の潜在的な異なるケースがあります。これは、これらの7つのモジュールのいずれかが検索されるかどうかを想定しているためです。

    クエリパラメータを使用できるようにする別の方法は、 UNIONの使用を忘れることです。 、代わりに、最大7つの個別の SELECTを実行するようにプロシージャを記述します。 クエリを実行し、それらすべてを複数の結果セットとして返します 。これは、ストアドプロシージャが実行することを目的としています。ただし、各結果セットを順番にフェッチするには、PHPレイヤーにコードを記述する必要があります。つまり、結果セットをループし、そのループ内で、現在の結果セットの行をループします。 PDO ::nextRowset() の例を参照してください。 または mysqli ::next_result() 。

    いいえ、そうすると安全ではありません! PHPのクエリパラメータを使用して文字列をCALLWEBSITE_mainSearch(?)に渡します 次に、そのパラメータ値をプロシージャ内の別の文字列に連結し、動的SQL解析および実行を実行すると、SQLインジェクションから保護するのに役立ちません。クエリパラメータを使用しても、パラメータ値が「安全」になるわけではなく、SQL解析フェーズからそれらの値を分離するだけです。

    MySQLの組み込み関数 QUOTE() 文字列を連結するとき。 QUOTE() mysql_real_escape_string()のように、特殊文字をエスケープします 。 PDO ::quote()

    SET @query = CONCAT(@query, 'SELECT blockName AS itemName, blockPath AS seoName, 
      blockID AS itemID, MATCH(blockName, blockBody) AGAINST (',
      QUOTE(searchWordIn), ') AS relevance, \'block\' AS itemType 
      FROM content_blocks WHERE MATCH(blockName, blockBody) AGAINST (',
      QUOTE(searchWordIn),')') ;
    

    更新:もう1つの選択肢: UNIONを使用する さらにサブクエリを追加し、モジュールの数を保持します。次に、 CASEを使用します 累積カウントに基づいて異なる数のパラメータを使用して、準備されたクエリを実行します。

    SET @n = 0;
    IF articlesModule = 1 THEN
        SET @query = ... UNION ...
        SET @n = @n+1;
    END IF;
    
    IF newsModule = 1 THEN
        SET @query = ... UNION ...
        SET @n = @n+1;
    END IF;
    
    ... and similar for the other 5 modules ...
    
    PREPARE stmt FROM @query;
    
    CASE @n
    WHEN 1:
        EXECUTE stmt USING @searchWordIn, @searchWordIn;
    WHEN 2:
        EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
    WHEN 3:
        EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
          @searchWordIn, @searchWordIn;
    WHEN 4:
        EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
          @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
    WHEN 5:
        EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
          @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
          @searchWordIn, @searchWordIn;
    WHEN 6:
        EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
          @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
          @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
    WHEN 7:
        EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
          @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
          @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn, 
          @searchWordIn, @searchWordIn;
    END;
    



    1. SQLサーバーで正規表現を使用する方法は?

    2. シャーロットでのPASSサミットに参加しますか?

    3. データの解析中にエラーが発生しましたorg.json.jsonexception文字0での入力の終わり

    4. SQLServerCEでの一括挿入