Drupal 7 でのデータベース操作 - レッスン 8 - 挿入クエリ(INSERT INTO)
挿入クエリは常にクエリビルダーを使うべきです。一部のデータベースは LOB(Large Object、MySQL の text など)や BLOB(Binary Large Object)フィールドに特別なハンドラーを必要とするため、個々の DB ドライバーがこれらのハンドラーを実装できるように抽象化レイヤーが必要です。
挿入クエリは db_insert() 関数で始まります:
この挿入クエリは、node テーブルに 1 つ以上のレコードを挿入するクエリオブジェクトを作成します。波括弧は不要であることに注意してください――クエリビルダーが自動的にテーブル名を処理します。
挿入クエリは fluent API を使います。つまり、(execute() を含む)すべてのメソッドがオブジェクト自体を返し、メソッドチェーンを可能にします。
挿入クエリは、さまざまなユースケースに応じたさまざまなパターンをサポートします。一般的なワークフローでは、挿入するフィールドと値を定義します。一般的なパターンを以下で説明します。
コンパクト形式
ほとんどの挿入クエリで好ましい形式はコンパクト形式です:
fields(array(
'title' => 'Example',
'uid' => 1,
'created' => REQUEST_TIME,
))
->execute();
?>
このクエリは次と同等です:
INSERT INTO {node} (title, uid, created) VALUES ('Example', 1, 1221717405);
このスニペットはキーと挿入する値を結びつけます。
この行は、node テーブル用の新しい挿入クエリオブジェクトを作成します。
fields(array(
'title' => 'Example',
'uid' => 1,
'created' => REQUEST_TIME,
))
?>
fields() メソッドはいくつかのパラメーターを取りますが、最も一般的には単一の連想配列です。配列のキーは挿入先の列で、値は挿入するデータです。
execute();
?>
他のメソッドとは異なり、execute() は挿入で使われた自動採番の値を返します。node テーブルの場合、これは nid になります。自動採番フィールドが存在しない場合、返される値は未定義であり、信頼すべきではありません。通常のケースでは、これが挿入クエリで好ましいメソッドです。
退化形式
fields(array('title', 'uid', 'created'))
->values(array(
'title' => 'Example',
'uid' => 1,
'created' => REQUEST_TIME,
))
->execute();
?>
このクエリは、上記のコンパクト形式と同じ結果になります。
fields(array('title', 'uid', 'created'))
?>
fields() をインデックス配列で呼び出すと、値を割り当てずに挿入クエリで使う列を定義します。これはマルチ挿入クエリに役立ちます。
values(array(
'title' => 'Example',
'uid' => 1,
'created' => REQUEST_TIME,
))
?>
values() メソッドは、フィールド名と挿入する値の連想配列を提供します。インデックス配列を取ることもできますが、その場合、順序は先に定義したフィールドリストと一致しなければなりません。読みやすさのため、連想配列が好まれます。fields() と values() を分けるのは、通常マルチ挿入でのみ必要です。
マルチ挿入形式
挿入クエリオブジェクトは、複数の値のセットを取ることもでき、バッチ処理のために values() を繰り返し呼び出します。これにより DB との互換性が確保され、一括挿入を使ってパフォーマンスが向上します。
'Example',
'uid' => 1,
'created' => REQUEST_TIME,
),
array(
'title' => 'Example 2',
'uid' => 1,
'created' => REQUEST_TIME,
),
array(
'title' => 'Example 3',
'uid' => 2,
'created' => REQUEST_TIME,
),
);
$query = db_insert('node')->fields(array('title', 'uid', 'created'));
foreach ($values as $record) {
$query->values($record);
}
$query->execute();
?>
この例は、効率的なマルチ挿入構文を使って 3 つのレコードを挿入します。挿入オブジェクトを変数に格納して反復し、各セットに対して values() を呼び出していることに注意してください。
これは次の結果になります:
INSERT INTO {node} (title, uid, created) VALUES ('Example', 1, 1221717405);
INSERT INTO {node} (title, uid, created) VALUES ('Example2', 1, 1221717405);
INSERT INTO {node} (title, uid, created) VALUES ('Example3', 2, 1221717405);
マルチ挿入における execute() の戻り値は未定義であり、DB ドライバーによって異なるため、信頼すべきではないことに注意してください。
SELECT からの挿入(集計テーブル)
SELECT を使って別のテーブルからテーブルを埋めるには、PHP で取得して手動で挿入するか、INSERT INTO ... SELECT スタイルのクエリを使えます。
例:システム内のすべてのノードから nid と username で mytable を埋めます。
Drupal 6:
Drupal 7:
join('users', 'u', 'n.uid = u.uid');
// Add the fields we want.
$query->addField('n','nid');
$query->addField('u','name');
// Add a condition to only get page nodes.
$query->condition('type', 'page');
// Perform the insert.
db_insert('mytable')
->from($query)
->execute();
?>
デフォルト値
通常、フィールドに値が提供されず、テーブルがデフォルトを定義している場合、DB は静かにデフォルトを挿入します。ただし、必要に応じて(たとえばデフォルトのみを挿入する場合)、useDefaults() を使ってデフォルト値を明示的に要求できます。
useDefaults(array('field1', 'field2'));
?>
これは、field1 と field2 にデフォルト値を使うようクエリに強制します。注意:同じフィールドを useDefaults() と fields() または values() の両方で定義すると、エラーになります。