(PHP 5, PHP 7, PHP 8, PECL OCI8 >= 1.1.0)
oci_execute — 文を実行する
$statement
, int $mode
= OCI_COMMIT_ON_SUCCESS
): bool
oci_parse() が返した
statement
を実行します。
実行後、INSERT
文などの場合はデフォルトでデータをデータベースにコミットします。
SELECT
文などの場合は問い合わせを実行します。
問い合わせの結果をその後 PHP で取得するには
oci_fetch_array() などの関数を使います。
一度パースした文は何度でも実行することができ、
これを使えば毎回パースするコストを節約することができます。
この方法は、oci_bind_by_name() でデータをバインドした
INSERT
文で一般的に使われています。
statement
有効な OCI ステートメント ID。
mode
オプションの二番目のパラメータは、次の定数のいずれかとなります。
定数 | 説明 |
---|---|
OCI_COMMIT_ON_SUCCESS |
ステートメントの実行に成功すると、 この接続においてまだ確定していない変更をすべてコミットします。 これがデフォルトです。 |
OCI_DESCRIBE_ONLY |
oci_field_name() 関数などでクエリのメタデータを使えるようにしますが、 結果セットは作りません。続けて oci_fetch_array() などをコールすると失敗します。 |
OCI_NO_AUTO_COMMIT |
変更を自動的にはコミットしません。PHP
5.3.2 (PECL OCI8 1.4) より前のバージョンでは
OCI_DEFAULT を使います。これは、
OCI_NO_AUTO_COMMIT と同じ意味です。 |
OCI_NO_AUTO_COMMIT
モードを使うとトランザクションを開始あるいは続行します。
接続を閉じたりスクリプトが終了したりしたときに、
トランザクションは自動的にロールバックされます。
トランザクションをコミットするには
oci_commit() を、破棄するには
oci_rollback() をコールします。
データを追加したり更新したりする際には、 リレーショナルデータの一貫性やパフォーマンスなどを考慮して トランザクションを使うことを推奨します。
OCI_NO_AUTO_COMMIT
モードを使った文を実行した後に
oci_commit()
あるいは oci_rollback() をコールしなかった場合、
たとえデータが変更されていなくても
スクリプトの終了時に OCI8 がロールバックを実行します。
不要なロールバックを避けるために、多くのスクリプトはクエリや PL/SQL で
OCI_NO_AUTO_COMMIT
モードを使いません。
同じスクリプトの中で異なるモードで
oci_execute() を実行する場合は、
アプリケーション内で適切なトランザクションの一貫性を確保するよう注意しましょう。
成功した場合に true
を、失敗した場合に false
を返します。
例1 oci_execute() での問い合わせの例
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
$stid = oci_parse($conn, 'SELECT * FROM employees');
oci_execute($stid);
echo "<table border='1'>\n";
while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
echo "<tr>\n";
foreach ($row as $item) {
echo " <td>" . ($item !== null ? htmlentities($item, ENT_QUOTES) : " ") . "</td>\n";
}
echo "</tr>\n";
}
echo "</table>\n";
?>
例2 モードを指定せずに oci_execute() を実行する例
<?php
// 実行する前にテーブルを作成します。
// CREATE TABLE MYTABLE (col1 NUMBER);
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
$stid = oci_parse($conn, 'INSERT INTO mytab (col1) VALUES (123)');
oci_execute($stid); // 結果はコミットされ、他のユーザーからもすぐに見えるようになります
?>
例3 oci_execute() で OCI_NO_AUTO_COMMIT
を使う例
<?php
// 実行する前にテーブルを作成します。
// CREATE TABLE MYTABLE (col1 NUMBER);
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
$stid = oci_parse($conn, 'INSERT INTO mytab (col1) VALUES (:bv)');
oci_bind_by_name($stid, ':bv', $i, 10);
for ($i = 1; $i <= 5; ++$i) {
oci_execute($stid, OCI_NO_AUTO_COMMIT); // PHP <= 5.3.1 の場合は OCI_DEFAULT を使います
}
oci_commit($conn); // 新しい値 1, 2, 3, 4, 5 をすべてコミットします
?>
例4 oci_execute() でさまざまなコミットモードを使う例
<?php
// 実行する前にテーブルを作成します。
// CREATE TABLE MYTABLE (col1 NUMBER);
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
$stid = oci_parse($conn, 'INSERT INTO mytab (col1) VALUES (123)');
oci_execute($stid, OCI_NO_AUTO_COMMIT); // データはコミットされません
$stid = oci_parse($conn, 'INSERT INTO mytab (col1) VALUES (456)');
oci_execute($stid); // 123 と 456 が両方コミットされます
?>
例5 oci_execute() で
OCI_DESCRIBE_ONLY
を使う例
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
$stid = oci_parse($conn, 'SELECT * FROM locations');
oci_execute($s, OCI_DESCRIBE_ONLY);
for ($i = 1; $i <= oci_num_fields($stid); ++$i) {
echo oci_field_name($stid, $i) . "<br>\n";
}
?>
注意:
トランザクションは接続を閉じたとき、 もしくはスクリプトの終了時のいずれの場合でも すぐに自動的にロールバックされます。 トランザクションをコミットするには oci_commit() をコールする必要があります。
OCI_COMMIT_ON_SUCCESS
モードを指定するか、 あるいはデフォルトの状態で oci_execute() をコールすると、 それ以前の未コミットのトランザクションをコミットします。
CREATE
やDROP
といった Oracle の DDL は、未コミットのトランザクションを自動的にコミットします。
注意:
oci_execute() 関数は 通常はステートメントをデータベースに送信するので、 ステートメントの構文エラーなどを特定することもできます。 軽量なローカル版の oci_parse() ではこれはできません。