PHP Doku:: Prepares an Oracle statement for execution - function.oci-parse.html

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzDatenbankerweiterungenAnbieterspezifische DatenbankerweiterungenOracle OCI8OCI8 Funktionenoci_parse

Ein Service von Reinhard Neidl - Webprogrammierung.

OCI8 Funktionen

<<oci_num_rows

oci_password_change>>

oci_parse

(PHP 5, PECL OCI8 >= 1.1.0)

oci_parsePrepares an Oracle statement for execution

Beschreibung

resource oci_parse ( resource $connection , string $sql_text )

Prepares sql_text using connection and returns the statement identifier, which can be used with oci_bind_by_name(), oci_execute() and other functions.

Statement identifiers can be freed with oci_free_statement() or by setting the variable to null.

Parameter-Liste

connection

An Oracle connection identifier, returned by oci_connect(), oci_pconnect(), or oci_new_connect().

sql_text

The SQL or PL/SQL statement.

SQL statements should not end with a semi-colon (";"). PL/SQL statements should end with a semi-colon (";").

Rückgabewerte

Returns a statement handle on success, or FALSE on error.

Beispiele

Beispiel #1 oci_parse() example for SQL statements

<?php

$conn 
oci_connect('hr''welcome''localhost/XE');

// Parse the statement. Note there is no final semi-colon in the SQL statement
$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";

?>

Beispiel #2 oci_parse() example for PL/SQL statements

<?php

/*
  Before running the PHP program, create a stored procedure in
  SQL*Plus or SQL Developer:

  CREATE OR REPLACE PROCEDURE myproc(p1 IN NUMBER, p2 OUT NUMBER) AS
  BEGIN
      p2 := p1 * 2;
  END;

*/

$conn oci_connect('hr''welcome''localhost/XE');
if (!
$conn) {
    
$e oci_error();
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$p1 8;

// When parsing PL/SQL programs, there should be a final semi-colon in the string
$stid oci_parse($conn'begin myproc(:p1, :p2); end;');
oci_bind_by_name($stid':p1'$p1);
oci_bind_by_name($stid':p2'$p240);

oci_execute($stid);

print 
"$p2\n";   // prints 16

oci_free_statement($stid);
oci_close($conn);

?>

Anmerkungen

Hinweis:

This function does not validate sql_text. The only way to find out if sql_text is a valid SQL or PL/SQL statement is to execute it.

Hinweis:

In PHP versions before 5.0.0 use ociparse() instead. Der alte Funktionsname kann noch immer verwendet werden, dies ist jedoch veraltet und wird nicht empfohlen.

Siehe auch


6 BenutzerBeiträge:
- Beiträge aktualisieren...
michael dot virnstein at brodos dot de
4.12.2007 17:43
A neat way to parse a query only once per script, if the query is done inside a function:

<?php
function querySomething($conn, $id)
{
    static
$stmt;

    if (
is_null($stmt)) {
       
$stmt = oci_parse($conn, 'select * from t where pk = :id');
    }

   
oci_bind_by_name($stmt, ':id', $id, -1);

   
oci_execute($stmt, OCI_DEFAULT);

    return
oci_fetch_array($stmt, OCI_ASSOC);

}

?>

With the static variable, the statment handle isn't closed after the function has terminated. Very nice for functions that are called e.g. in loops. Unfortunately this only works for static sql. If you have dynamic sql, you can do the following:

<?php

function querySomething($conn, $data)
{
    static
$stmt = array();
   
   
$first = true;
   
   
$query = 'select * from t';

    foreach (
$data as $key => $value) {
        if (
$first) {
           
$first = false;
           
$query .= ' where ';
        } else {
           
$query .= ' and ';
        }
       
       
$query .= "$key = :b$key";
    }
   
   
$queryhash = md5($query);
  
    if (
is_null($stmt[$queryhash])) {
       
$stmt[$queryhash] = oci_parse($conn, $query);   
    }

    foreach (
$data as $key => $value) {
       
// don't use $value, because we bind memory addresses here.
        // this would result in every bind pointing at the same value after foreach
       
oci_bind_by_name($stmt[$queryhash], ":b$key", $data[$key], -1);
    }
   
   
oci_execute($stmt[$queryhash], OCI_DEFAULT);

    return
oci_fetch_array($stmt[$queryhash], OCI_ASSOC);

}

?>

27.01.2006 1:05
one of the most things that is done wrong with oracle is the following.

Cosider:

<?php
$dbh
= ocilogon('user', 'pass', 'db');

for (
$i = 0; $i<=10; $i++) {
   
$sth = ociparse($dbh, 'SELECT * FROM T WHERE x = :x');

   
ocibindbyname($sth, ':x', $i, -1);
   
ociexecute($sth, OCI_DEFAULT);
    if (
ocifetchrow($sth, $row, OCI_ASSOC+OCI_RETURN_NULLS)) {
       
var_dump($row);
    }
}

ocilogoff($dbh);
?>

Problem here is, that you parse the same statement over and over and that'll cost ressources and will introduce many wait events. This problem will increase exponentially with the number of users using your system. That's one of the things besides not using bind variables that will prevent your application from scaling well.

The right approach:

<?php
$dbh
= ocilogon('user', 'pass', 'db');
$sth = ociparse($dbh, 'SELECT * FROM T WHERE x = :x');
for (
$i = 0; $i<=10; $i++) {
   
ocibindbyname($sth, ':x', $i, -1);
   
ociexecute($sth, OCI_DEFAULT);
    if (
ocifetchrow($sth, $row, OCI_ASSOC+OCI_RETURN_NULLS)) {
       
var_dump($row);
    }
}
ocilogoff($dbh);
?>

Now we are parsing the statement once and using it as often as possible.

When your using Oracle, create proper indexes, use bind variables and parse once and execute often. Not doing so will get you into trouble when more than a few users are working with your application simultaneously.
kurt at kovac dot ch
4.05.2004 17:40
For those that are having trouble with error checking, i have noticed on a lot of sites that people are trying to check the statement handle for error messages with OCIParse. Since the statement handle ($sth) is not created yet, you need to check the database handle ($dbh) for any errors with OCIParse. For example:

instead of:

<?php
$stmt
= OCIParse($conn, $query);
if (!
$stmt) {
  
$oerr = OCIError($stmt);
   echo
"Fetch Code 1:".$oerr["message"];
   exit;
}
?>

use:

<?php
$stmt
= OCIParse($conn, $query);
if (!
$stmt) {
  
$oerr = OCIError($conn);
   echo
"Fetch Code 1:".$oerr["message"];
   exit;
}
?>

Hope this helps someone.
jicurito at hotmail dot com
10.12.2003 1:41
regarding egypt note on double quotes, the reason for that behaviour is that Oracle treats things with double quotes as identifiers on a given statement... using single quotes won't provoque mistakes...
egypt at nmt dot edu
15.10.2003 4:31
Whereas MySQL doesn't care what kind of quotes are around a LIKE clause, ociexecute gives the error:
    ociexecute(): OCIStmtExecute: ORA-00904: "NM": invalid identifier
for the following.
<?php
$sql 
= "SELECT * FROM addresses "
     
. "WHERE state LIKE \"NM\""// error!
$stmt = ociparse($conn, $sql);
ociexecute($stmt);
?>

it's fine if you just use single quotes:
    . "WHERE state LIKE 'NM'";
but i think it's interesting that ociparse doesn't say anything
mwd at modulo3 dot de
22.12.2000 16:21
if you're using "complex" statements e.g such having calls to build in oracle functions in the select list (as in example below), I did not find any other way as using the "AS <Name>" clause to being able to output the functions outcome using ociresult

example:

<?php
ociparse
($conn,"select EMPNO, LPAD(' ', 2*(LEVEL-1)) || ENAME AS COMPLETE_FANTASY_NAME, JOB, HIREDATE from scott.emp start with job='MANAGER' connect by PRIOR EMPNO = MGR");

echo
ociresult $stmt,"COMPLETE_FANTASY_NAME")." ";
?>

BTW: I also found out by TAE that "COMPLETE_FANATASY_NAME" might not be "complete fantasy" as it has to be all capital letters.



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)