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

インプロデュースされた配列をmysqlのプリペアドステートメントにバインドする際の問題

    手間を省いて、あなたがやろうとしていることはとにかくうまくいかないことを教えてあげましょう。 IN()にバインドしているパラメータは1つだけです 関数呼び出し。あなたは考える カンマ区切りのリストを渡しますが、実際には1つの値として扱われるカンマ区切りの文字列のみを渡します。 。これは、1つのレコードを検索することを意味します 値は「' [email protected] '、' [email protected] [email protected] に一致するレコードの代わりに「」 "または" [email protected] "。

    これを克服するには、次のことを行う必要があります。

    1. タイプ文字列を動的に生成します
    2. call_user_func_array()<を使用します/ code> パラメータをバインドするには

    次のようにtypes文字列を生成できます:

    $types = str_repeat('s', count($selected));
    

    これは、 sの文字列を作成するだけです。 これは、配列内の要素の数と同じ数の文字です。

    次に、 call_user_func_array()を使用してパラメーターをバインドします。 このように( IN()の括弧を元に戻したことに注意してください 関数):

    if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN (?)")) {
        call_user_func_array(array($stmt, "bind_param"), array_merge($types, $selected));
    

    ただし、これを試してみると、 mysqli_stmt ::bind_param()に関するエラーが発生します。 パラメータ2が参照によって渡されることを期待しています:

    これはちょっと面倒ですが、回避するのに十分簡単です。これを回避するには、次の関数を使用できます。

    function refValues($arr){ 
        $refs = array(); 
        foreach($arr as $key => $value) 
            $refs[$key] = &$arr[$key]; 
        return $refs; 
    } 
    

    $ selectedの値への参照である値の配列を作成するだけです。 配列。これは、 mysqli_stmt ::bind_param()を作成するのに十分です。 幸せ:

    if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN (?)")) {
        call_user_func_array(array($stmt, "bind_param"), array_merge($types, refValues($selected)));
    

    編集

    PHP 5.6以降、 ...を使用できるようになりました これをさらに簡単にする演算子:

    $stmt->bind_param($types, ...$selected);
    



    1. Oracle Cloud:自律型トランザクション処理(ATP)データベースの作成

    2. SQLServer2005の階層クエリ

    3. テーブル値パラメータをC#からOracleストアドプロシージャに渡す方法

    4. 冗長インデックスを見つけるためのT-SQL