autoPrepare & autoExecute

autoPrepare & autoExecute -- SQL 文を自動的に準備・実行する

説明

目的

autoPrepare() および autoExecute() は、うんざりするような INSERTUPDATEDELETESELECT 文を書く手間を軽減します。 これらの SQL 文を使用していると、例えばテーブルにフィールドを追加した場合などの メンテナンスが大変ですよね? autoPrepare() および autoExecute() を使用するには、 Extended モジュールを 使用する必要があります。

'user' テーブルに次の 3 つのフィールド (id, name そして country) があるとしましょう。 きっと、こんな SQL クエリを書くことになるでしょう。
INSERT INTO table (id, name, country) VALUES (?, ?, ?)
UPDATE table SET id=?, name=?, country=? WHERE ...
ここでフィールドを追加 (例えば 'birthYear' など) したとすると、 クエリを書き直さなければなりません。これはうんざりするような作業であり、 (ひとつだけクエリの修正を忘れてしまうなどの) バグの元となります。

autoPrepare

autoPrepare() を使用すると、insert や update、delete そして select といったクエリを書く必要がなくなります。例を見てみましょう。
<?php
// すでに $mdb2 という名前の MDB2 オブジェクトが存在するものとします
$table_name   = 'user';
$table_fields = array('id', 'name', 'country');
$types = array('integer', 'text', 'text');

$mdb2->loadModule('Extended');
$sth = $mdb2->extended->autoPrepare($table_name, $table_fields,
                        MDB2_AUTOQUERY_INSERT, null, $types);

if (PEAR::isError($sth)) {
    die($sth->getMessage());
}
?>
この例では、 autoPrepare() は以下の SQL クエリを作成します。
INSERT INTO user (id, name, country) VALUES (?, ?, ?)
それから、そのクエリを用いて prepare() をコールします。

レコードを追加するには execute() あるいは executeMultiple() を次のように使用します。
<?php
// ... 上の例からの続きです ...
$table_values = array(1, 'Fabien', 'France');

$res =& $sth->execute($table_values);

if (PEAR::isError($res)) {
    die($res->getMessage());
}
?>
どうです? SQL の INSERT 文を一切書く必要がないのです! そしてこれは UPDATEDELETE でも同様に動作します。ただし、柔軟性を確保するため、クエリの WHERE 句だけは書かなければなりません。 例えばこのようになります。
<?php
// すでに $mdb2 という名前の MDB2 オブジェクトが存在するものとします
$table_name   = 'user';

$mdb2->loadModule('Extended');
$sth = $mdb2->extended->autoPrepare($table_name, null,
                        MDB2_AUTOQUERY_DELETE, 'id = '.$mdb2->quote(1, 'integer'));

if (PEAR::isError($sth)) {
    die($sth->getMessage());
}

$res =& $mdb2->execute($sth, $table_values);

if (PEAR::isError($res)) {
    die($res->getMessage());
}
?>
autoPrepare() は、次のようなクエリを作成します。
UPDATE user SET name=?, country=? WHERE id=1
それから、そのクエリを使用して prepare() をコールします。

注意しなければならないのは、もし WHERE 句を指定しなければ、 テーブルの全レコードが更新されてしまうということです。

autoExecute

insert、update、delete あるいは select クエリを実行する最も簡単な方法が、 autoExecute() をコールすることです。 これは autoPrepare() execute() を組み合わせたものです。

必要なのは連想配列だけです。連想配列のキーにフィールド名、 対応する値としてそのフィールドの値を指定します。 これは、insert や update クエリの場合にのみ影響します。 例を見てみましょう。
<?php
// すでに $mdb2 という名前の MDB2 オブジェクトが存在するものとします
$table_name = 'user';

$fields_values = array(
    'id'      => 1,
    'name'    => 'Fabien',
    'country' => 'France'
);
$types = array('integer', 'text', 'text');

$mdb2->loadModule('Extended');
$affectedRows = $mdb2->extended->autoExecute($table_name, $fields_values,
                        MDB2_AUTOQUERY_INSERT, null, $types);

if (PEAR::isError($affectedRows)) {
    die($affectedRows->getMessage());
}
?>
たったこれだけです! これで、次のクエリが作成され、そして実行されます。
INSERT INTO user (id, name, country)
  VALUES (1, 'Fabien', 'France')

UPDATE クエリについても同様です。
<?php
// すでに $mdb2 という名前の MDB2 オブジェクトが存在するものとします
$table_name = 'user';

$fields_values = array(
    'name'    => 'Fabien',
    'country' => 'France'
);
$types = array('text', 'text');

$mdb2->loadModule('Extended');
$affectedRows = $mdb2->extended->autoExecute($table_name, $fields_values,
                        MDB2_AUTOQUERY_UPDATE, 'id = '.$mdb2->quote(1, 'integer'), $types);

if (PEAR::isError($affectedRows)) {
    die($affectedRows->getMessage());
}
?>
これで、以下のクエリが作成され、そして実行されます。
UPDATE user SET name='Fabien', country='France'
  WHERE id = 1

注意しなければならないのは、もし WHERE 句を指定しなければ、 テーブルの全レコードが更新されてしまうということです。

これが DELETE クエリの例です。
<?php
// すでに $mdb2 という名前の MDB2 オブジェクトが存在するものとします
$table_name = 'user';

$mdb2->loadModule('Extended');
$affectedRows = $mdb2->extended->autoExecute($table_name, null,
                        MDB2_AUTOQUERY_DELETE, 'id = '.$mdb2->quote(1, 'integer'));

if (PEAR::isError($affectedRows)) {
    die($affectedRows->getMessage());
}

?>
これで、以下のクエリが作成され、そして実行されます。
DELETE FROM user WHERE id = 1

最後に SELECT クエリの例を見てみましょう。
<?php
// すでに $mdb2 という名前の MDB2 オブジェクトが存在するものとします
$table_name = 'user';

// 配列を指定しない場合は、'*' を使用してすべてのフィールドを取得します。
// その場合、この変数を true に設定すると自動的に型の判別を行います。
$result_types = array(
    'name'    => 'text',
    'country' => 'text'
);

$mdb2->loadModule('Extended');
$res = $mdb2->extended->autoExecute($table_name, null,
                        MDB2_AUTOQUERY_SELECT, 'id = '.$mdb2->quote(1, 'integer'),
                        null, true, $result_types);

if (PEAR::isError($res)) {
    die($res->getMessage());
}

$row = $res->fetchRow();

?>
これで、以下のクエリが作成され、そして実行されます。
SELECT name, country FROM user WHERE id = 1

警告

$data に渡す値はリテラルでなければなりません。 SQL の関数 (例えば CURDATE() など) を使用しないでください。 実行時に使用する SQL 関数は、プリペアドステートメントに 埋め込んでおく必要があります。

参照

"導入 - モジュール"