IN
句が空のSQLクエリを実行するとどうなりますか?
例えば:
SELECT user WHERE id IN ();
MySQLはこれを期待どおりに処理します(つまり、常にfalse)。そうでない場合、IN
句を動的に構築するときに、アプリケーションはこのケースをどのように処理できますか?
IN
リストを動的に構築しているアプリケーションがあり、それが空になる可能性がある場合、私は時々、リストを不可能な値で初期化して追加します。例えば。ユーザー名のリストの場合、空の文字列から始めます。これはユーザー名ではないためです。 auto_increment IDの場合、実際の値は常に正であるため、-1を使用します。
不可能な値がないためにこれが実行可能でない場合は、WHERE
句にAND column IN ($values)
式を含めるかどうかを決定する条件を使用する必要があります。
有効な構文を使用したクエリの最も近い近似は次のとおりです。
SELECT user FROM tbl1 WHERE id IN (SELECT id FROM tbl1 WHERE FALSE);
これは無条件に空の結果セットを返します。括弧内のサブクエリは常に空のセットを返します。前述のように、空のセットには値が含まれていないため、空のセットには値が見つかりません。
これにより、結果も0になります。
SELECT id FROM User
WHERE id IN (NULL);
MYSQL 5.6で試しました
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
}
常に偽のステートメントを使用する
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')
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インジェクションから保護されます。