ConFoo: Call for paper is now Open

oci_execute

(PHP 5, PECL OCI8 >= 1.1.0)

oci_execute文を実行する

説明

bool oci_execute ( resource $statement [, int $mode = OCI_COMMIT_ON_SUCCESS ] )

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($stidOCI_ASSOC+OCI_RETURN_NULLS)) {
    echo 
"<tr>\n";
    foreach (
$row as $item) {
        echo 
"    <td>" . ($item !== null htmlentities($itemENT_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'$i10);
for (
$i 1$i <= 5; ++$i) {
    
oci_execute($stidOCI_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($stidOCI_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($sOCI_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 add a note

User Contributed Notes 2 notes

up
0
filipesampaio at hotmail dot com
3 years ago
Just to write it down. I was trying to do a simple SELECT on a Caché (http://www.intersystems.com/cache/) table through an Oracle dblink, but always received the error "ORA-01002: fetch out of sequence". The solution was using OCI_NO_AUTO_COMMIT on the oci_execute function.
up
0
tower98 at gmail dot com
4 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