PHP Conference Nagoya 2025

oci_execute

(PHP 5, PHP 7, PHP 8, PECL OCI8 >= 1.1.0)

oci_execute文を実行する

説明

oci_execute(resource $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 変更を自動的にはコミットしません

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) : "&nbsp;") . "</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);
}
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() をコールすると、 それ以前の未コミットのトランザクションをコミットします。

CREATEDROP といった Oracle の DDL は、未コミットのトランザクションを自動的にコミットします。

注意:

oci_execute() 関数は 通常はステートメントをデータベースに送信するので、 ステートメントの構文エラーなどを特定することもできます。 軽量なローカル版の oci_parse() ではこれはできません。

参考

  • oci_parse() - 実行のために Oracle の文をパースする

add a note

User Contributed Notes 1 note

up
3
tower98 at gmail dot com
14 years ago
Notice (PHP 5.2.12-pl0-gentoo):
You can parse empty query, you can execute empty query (returns true), but you cannot fetch data from empty query. So, if you provide query as variable, make sure it isn't empty.

<?php
$q
= oci_parse($c, "");
if(
$q != false){
// parsing empty query != false
if(oci_execute($q){
// executing empty query != false
if(oci_fetch_all($q, $data, 0, -1, OCI_FETCHSTATEMENT_BY_ROW) == false){
// but fetching executed empty query results in error (ORA-24338: statement handle not executed)
$e = oci_error($q);
echo
$e['message'];
}
}
else{
$e = oci_error($q);
echo
$e['message'];
}
}
else{
$e = oci_error($link);
echo
$e['message'];
}
?>
To Top