web-dev-qa-db-ja.com

MySQLの空のIN句パラメーターリスト

IN句が空のSQLクエリを実行するとどうなりますか?

例えば:

SELECT user WHERE id IN ();

MySQLはこれを期待どおりに処理します(つまり、常にfalse)。そうでない場合、IN句を動的に構築するときに、アプリケーションはこのケースをどのように処理できますか?

54
Wiz

INリストを動的に構築しているアプリケーションがあり、それが空になる可能性がある場合、私は時々、リストを不可能な値で初期化して追加します。例えば。ユーザー名のリストの場合、空の文字列から始めます。これはユーザー名ではないためです。 auto_increment IDの場合、実際の値は常に正であるため、-1を使用します。

不可能な値がないためにこれが実行可能でない場合は、WHERE句にAND column IN ($values)式を含めるかどうかを決定する条件を使用する必要があります。

48
Barmar

有効な構文を使用したクエリの最も近い近似は次のとおりです。

SELECT user FROM tbl1 WHERE id IN (SELECT id FROM tbl1 WHERE FALSE);

これは無条件に空の結果セットを返します。括弧内のサブクエリは常に空のセットを返します。前述のように、空のセットには値が含まれていないため、空のセットには値が見つかりません。

12
Asad Saeeduddin

これにより、結果も0になります。

SELECT id FROM User
WHERE id IN (NULL);

MYSQL 5.6で試しました

8
Pavel Shkleinik

Id(1,2,3、..)にAUTO_INCREMENTを使用し、配列が空の場合、1つのアイテム[0]を追加できます。だからそれは

if (empty($arr)) {
   $arr[] = 0;
}

SELECT user WHERE id IN (0);

また、mysqlの解析エラーはありません。このケースは、サブクエリで非常に役立ちます-メインクエリがサブクエリの結果に依存しない場合。


より良い方法-配列が空の場合、クエリを呼び出さないでください。

$data = null;
if (!empty($arr)) {
    $data = ... call query
}
4

常に偽のステートメントを使用する

SQLを作成する前に、配列サイズを確認してください。サイズが0の場合、次のように1 = 2としてwhereステートメントを生成します。

SELECT * FROM USERS WHERE name in () 

になる

SELECT * FROM USERS WHERE 1 = 2 

空の配列で「not in」の場合、次のように常に真のステートメントを生成します。

SELECT * FROM USERS WHERE name not in () 

になる

SELECT * FROM USERS WHERE 1 = 1

これは、より複雑なクエリで次のように機能するはずです。

SELECT * FROM USERS WHERE (name in () OR name = 'Alice') 

になる

SELECT * FROM USERS WHERE (1 = 2 OR name = 'Alice') 
3
Jus12

INが空の場合でもクエリを実行する必要があると思います。たとえば、LEFT JOIN ... ON ... AND IN ()を使用します。

アプリケーション層でINを既に動的に構築しているので、そこで空のケースを処理します。

PHPの基本的な例を次に示します

$condition = 'FALSE' // Could feasibly want TRUE under different circumstances
if($values){
   $inParams = **dynamically generated IN parameters from $values**;
   $condition = 'IN (' . $inParams . ')';
}

$sql = 'SELECT * FROM `user` WHERE '.$condition;

空のINを使用してクエリを実行する必要がない場合は、しないでください。データベースへの旅行を節約しましょう!

NBまだ行っていない場合は、単に生で連結するのではなく、INパラメーターを適切にバインドして、長い道のりをたどる関数をビルド/使用しますSQL。これにより、生データでSQLインジェクションが使用されている場合に、SQLインジェクションから保護されます。

1
Arth