logo

パレット - カラフルに🎨

Palette — ビジュアルページビルダー、デザインの専門知識は不要です。

ライブデモ パレットをダウンロード

Scroll
08/05/2020, by maria

動的クエリとは、明示的なクエリ文字列として提供されるのではなく、Drupalによって動的に作成されるクエリを指します。すべての挿入、更新、削除、マージクエリは動的である必要があります。選択クエリは静的または動的にすることができます。したがって、「動的クエリ」は通常、動的SELECTクエリを指します。

注:selectクエリの使用の90%は静的クエリになります。パフォーマンスが重要なパスでは、パフォーマンス上の理由からselect()の代わりにquery()を使用する必要があります。動的クエリは、クエリの一部が異なる場合(例:コンテキストに応じてWHERE条件を追加する)または変更可能である必要がある場合にのみ使用します。

動的に作成されるすべてのクエリは、対応するデータベース接続オブジェクトから要求されたクエリオブジェクトを使用して作成されます。静的クエリと同様に、圧倒的多数の場合、プロシージャルラッパーをクエリオブジェクトに使用できます。ただし、その後のクエリディレクティブは、クエリオブジェクトに対して呼び出されるメソッドの形式を取ります。

動的選択クエリは、select()メソッドを使用して次のように開始します:

$database = \Drupal::database();
$query = $database->select('mytable', 'mt', $options);

この場合、mytableはクエリのベーステーブルです。FROMステートメントの後の最初のテーブルです。その周りに中括弧は必要ないことに注意してください。クエリビルダーが自動的に処理します。2番目のパラメーターはテーブルのエイリアスです。指定しない場合は、テーブル名が使用されます。$options配列はオプションであり、静的クエリの$options配列と同じです。

$database->select()呼び出しによって返される値は、Select型のオブジェクトです。したがって、この呼び出し後の$query変数の値のタイプはSelect型のオブジェクトです。このオブジェクトには、fields()、joins()、group()などのメソッドの完全なリストがあり、クエリをさらに定義するために呼び出すことができます。

動的選択クエリは非常に単純なものから非常に複雑なものまであります。以下では、単純なクエリを構成する個々の部分を見ていきます。次のページでは、結合などのより複雑なメソッドを見ていきます。

全体像

これはユーザーテーブルの比較的単純なクエリです。

次の静的クエリとほぼ同等の動的クエリを作成するとします:

$result = $database->query("SELECT uid, name, status, created, access FROM {users} u WHERE uid <> 0 LIMIT 50 OFFSET 0");

動的同等物は次のように始まります:

// Create an object of type Select.
$database = \Drupal::database();
$query = $database->select('users', 'u');
 
// Add extra detail to this query object: a condition, fields and a range.
$query->condition('u.uid', 0, '<>');
$query->fields('u', ['uid', 'name', 'status', 'created', 'access']);
$query->range(0, 50);

これは、$queryオブジェクトの複数のメソッドを同時に呼び出すために使用される省略構文で書かれることがよくあります。したがって、上記のコードは次のように書かれることがよくあります:

// Create an object of type Select.
$query = $database->select('users', 'u');
 
// Add extra detail to this query object: a condition, fields and a range.
$query->condition('u.uid', 0, '<>')
  ->fields('u', ['uid', 'name', 'status', 'created', 'access'])
  ->range(0, 50);

実際、$database->select()呼び出しを結果オブジェクトのメソッド呼び出しに直接チェーンすることで、コードをさらに1ステップ簡略化できます(頻繁に行われます)。これにより、次のようになります:

// Create an object of type Select and directly add extra detail
// to this query object: a condition, fields and a range.
$query = $database->select('users', 'u')
  ->condition('u.uid', 0, '<>')
  ->fields('u', ['uid', 'name', 'status', 'created', 'access'])
  ->range(0, 50);

これは、ユーザー管理ページで使用されるクエリの簡略化された形式であり、さらに調べるために参照できます。

クエリの実行

クエリが構築されたら、execute()メソッドを呼び出してクエリをコンパイルして実行します。

$result = $query->execute();

execute()メソッドは、$database->query()関数によって返されるオブジェクトと同一の結果セット/ステートメントオブジェクトを返し、まったく同じ方法で反復または取得できます:

$result = $query->execute();
foreach ($result as $record) {
  // Do something with each $record.
}

注:複数列の動的クエリで次のメソッドを使用する場合は注意してください:

これらのメソッドは現在、テーブルエイリアスではなく、数値の列インデックス(0、1、2など)を必要とします。ただし、現在クエリビルダーは返されるフィールドの特定の順序を保証しないため、データ列が期待する順序にならない場合があります。特に、式は最初にクエリに追加した場合でも、常にフィールドの後に追加されます。(この問題は、指定した順序でデータ列を常に返す静的クエリには適用されません。)

デバッグ

クエリオブジェクトがライフサイクルの特定の時点で使用するSQLクエリを調べるには、クエリオブジェクトを出力します。引数を確認するには、arguments()メソッドによって返される配列を確認します:

echo $query;
print_r($query->__toString());
print_r($query->arguments());