Drupal 7 でのデータベース操作 - レッスン 12 - クエリ条件(WHERE、HAVING、LIKE)
クエリの WHERE 句を使うと、特定の条件を満たすレコードだけを選択できます――たとえば、2 週間前より後に作成されたノードや、「Drupal」という語を含むタクソノミー用語などです。SQL では、SELECT、UPDATE、DELETE クエリで条件を指定するために WHERE と HAVING を使います。Drupal の動的クエリには、クエリ条件を扱う組み込みの仕組みがあり、SELECT、UPDATE、DELETE の操作で同じように機能します。
条件式の概念
条件は、制約を定義する特別な式として表されます。
条件の結合
各条件は、論理演算子 AND と OR を使って組み合わせた複数の条件式で構成できます。
条件オブジェクト
Drupal は各条件フラグメントを QueryCondition クラスのインスタンスとして表します。すべての条件オブジェクトは QueryCondition インスタンスです。
SQL クエリの例:
SELECT FROM {mytable} WHERE (a = 1 AND b = 'foo' OR (c = 'bar'))
条件式:
WHERE (a = 1 AND b = 'foo' OR (c = 'bar'))
条件の部分:
(a = 1 AND b = 'foo' OR (c = 'bar'))
(c = 'bar')
演算子:
AND, OR
SELECT、UPDATE、DELETE クエリは QueryConditionalInterface を実装しており、これが条件関連のメソッドを提供します。これらは QueryCondition オブジェクトにラップされます。QueryCondition クラスは直接使うこともできます。
各式はデフォルトで AND で結合されます。複数のフラグメントは、グループ化構文を使って OR で結合できます。
API
クエリオブジェクトに条件を設定する主なメソッドは 2 つあります:
$query->condition($field, $value = NULL, $operator = '=');
このメソッドは基本的な比較条件を定義します。=、<、>=、LIKE などの比較演算子と一緒に使います。演算子を指定しない場合、デフォルトは = です。たとえば:
$query->condition('myfield', $value);
// Becomes: myfield = :value
もう一つのメソッドは:
$query->where($snippet, $args = array());
where() メソッドは、プレースホルダー付きの生の SQL スニペットを許可します。condition() よりは好ましくありませんが、複雑またはカスタムの SQL を書くときに役立ちます。
配列を使った条件
複数の値でフィルタリングするには、値の配列を渡せます。よく使われる SQL 演算子は IN と BETWEEN です。
$query->condition('myfield', array(1, 2, 3), 'IN');
// Becomes: myfield IN (:db_placeholder_1, :db_placeholder_2, :db_placeholder_3)
値の範囲には BETWEEN を使います:
$query->condition('myfield', array(5, 10), 'BETWEEN');
// Becomes: myfield BETWEEN :db_placeholder_1 AND :db_placeholder_2
ネストした条件
condition() の最初のパラメーターは、それ自体が別の条件オブジェクトになれます。これにより、AND と OR 演算子を組み合わせた複雑なネストクエリが可能になります。
新しい条件オブジェクトを作成するには db_condition() を使います。db_or()、db_and()、db_xor() のようなヘルパーも使えます。たとえば:
$query
->condition('field1', array(1, 2), 'IN')
->condition(db_or()->condition('field2', 5)->condition('field3', 6));
// Becomes:
// (field1 IN (:db_placeholder_1, :db_placeholder_2) AND (field2 = :db_placeholder3 OR field3 = :db_placeholder_4))
NULL 条件
NULL 値をチェックするには、次を使います:
$query->isNull('myfield');
// Becomes: myfield IS NULL
$query->isNotNull('myfield');
// Becomes: myfield IS NOT NULL
注意: condition('myfield', NULL) は非推奨です。代わりに isNull() または isNotNull() を使ってください。
サブクエリ
condition() メソッドは、db_select() が返す SelectQuery クラスを使って、値としてのサブクエリをサポートします。select() を直接呼び出す代わりに、そのオブジェクトを condition() のパラメーターとして渡します。
サブクエリは、小さな 1 フィールドの条件に理想的です。より複雑なケースでは、サブクエリの使用を避け、条件チェーンにとどめてください。
例
db_delete()
db_delete('sessions')
->condition('timestamp', REQUEST_TIME - $lifetime, '')
->execute();
// DELETE FROM {sessions} WHERE (timestamp 1228713473)
db_update()
db_update('sessions')
->fields(array('sid' => session_id()))
->condition('sid', $old_session_id)
->execute();
// UPDATE {sessions} SET sid = 'abcde' WHERE (sid = 'fghij');
OR 条件付きの db_delete()
$or = db_or()->condition('tid1', 5)->condition('tid2', 6);
db_delete('term_relation')->condition($or)->execute();
// DELETE FROM {term_relation} WHERE ((tid1 = 5 OR tid2 = 6))