サポート » 使い方全般 » SQL文でIN句を使いたいのですが、$wpdb->prepareを使用するとうまくいきません

  • $wpdb->prepareがとても便利で普段使用しているのですが、IN句のときには、どうやら一工夫が必要みたいで、うまく動作してくれません。

    やりたいこと:IDが 1,2,3のいずれかに該当するuserの数をカウント
    $some_ID = ‘1,2,3’;
    $count_user = (int)$wpdb->get_var( $wpdb->prepare( “SELECT COUNT(user) FROM sample_table WHERE ID IN (%s)”, $some_ID ) );

    としたところ、全然IDが1,2,3のuserの数をカウントしてくれませんでした。
    調べると、IN句をprepareする場合、今回ならIDの数だけ%dを使用する必要があるらしく以下のように書きました。

    $some_ID = ‘1,2,3’;
    $count_user = (int)$wpdb->get_var( $wpdb->prepare( “SELECT COUNT(user) FROM sample_table WHERE ID IN (%d,%d,%d)”, $some_ID ) );

    しかし、今回も、IDが1,2,3のuserの数をカウントしてくれませんでした。
    $some_IDのところに、かわりに直接 1,2,3 と入力すると、想定道理にuserの数をカウントしてくれるのですが、
    $some_IDを入れると、1,2,3が、’1,2,3’というひとつの文字列として扱われてしまうようなのです。

    $some_IDを、文字列の’1,2,3’ではなく、数字の 1,2,3 に変換する方法がわかれば、解決するように思うのですが、そのような方法がわからず、困っています。

    どなたか、おわかりになる方がいらっしゃいましたら、どうかお知恵を貸して頂けましたら幸いです。

    何卒、宜しくお願い致します。

2件の返信を表示中 - 1 - 2件目 (全2件中)
  • こんにちは

    この場合は、$wpdb->prepare() を使用しないで、SQL エスケープ処理(値が整数になるように)するのがいいのではないでしょうか。

    $some_ID = '1,2,3';
    
    $ids = implode( ',', array_map( function( $value ) { return (int) $value; }, explode( ',', $some_ID ) ) );
    $count_user = (int) $wpdb->get_var( "SELECT COUNT(user) FROM sample_table WHERE ID IN ($ids)" );

    $wpdb->prepare() を使用する場合は、下記のようになるかなと思います。

    $some_ID = '1,2,3';
    
    $ids = explode( ',', $some_ID );
    $ds = implode( ',', array_fill( 0, count( $ids ), '%d' ) );
    $sql = "SELECT COUNT(user) FROM sample_table WHERE ID IN ($ds)";
    $sql = call_user_func_array( array( $wpdb, 'prepare' ), array_merge( array( $sql ), $ids ) );
    $count_user = (int) $wpdb->get_var( $sql );
    トピック投稿者 yaya777

    (@yaya777)

    本当に有難うございます。
    どのように、そして何年勉強すると、ぱっと上記のようなコードをぱっと思いつけるようになるのでしょうか。。感服致しました。
    重ねて、心より感謝申し上げます、有難うございます。

2件の返信を表示中 - 1 - 2件目 (全2件中)
  • トピック「SQL文でIN句を使いたいのですが、$wpdb->prepareを使用するとうまくいきません」には新たに返信することはできません。