From 80fd12d9ef5bd1a0b616501a28c93000d9dae552 Mon Sep 17 00:00:00 2001 From: Christopher Jones Date: Sat, 14 Nov 2009 00:21:58 +0000 Subject: [PATCH] Big update git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@290727 c90b9560-bf6c-de11-be94-00142212c4b1 --- reference/oci8/functions/oci-bind-by-name.xml | 715 +++++++++++++++--- 1 file changed, 593 insertions(+), 122 deletions(-) diff --git a/reference/oci8/functions/oci-bind-by-name.xml b/reference/oci8/functions/oci-bind-by-name.xml index 509e022347..89ffe60ecc 100644 --- a/reference/oci8/functions/oci-bind-by-name.xml +++ b/reference/oci8/functions/oci-bind-by-name.xml @@ -3,7 +3,7 @@ oci_bind_by_name - Binds the PHP variable to the Oracle placeholder + Binds a PHP variable to an Oracle placeholder @@ -11,16 +11,81 @@ booloci_bind_by_name resourcestatement - stringph_name + stringbv_name mixedvariable intmaxlength-1 inttypeSQLT_CHR - Binds the PHP variable variable to the Oracle - placeholder ph_name. Whether it will be used for - input or output will be determined at run-time and the necessary - storage space will be allocated. + Binds a PHP variable variable to the Oracle + bind variable placeholder bv_name. Binding + is important for Oracle database performance and also as a way to + avoid SQL Injection security issues. + + + + Binding allows the database to reuse the statement context and + caches from previous executions of the statement, even if another + user or process originally executed it. Binding reduces SQL + Injection concerns because the data associated with a bind + variable is never treated as part of the SQL statement. It does + not need quoting or escaping. + + + + PHP variables that have been bound can be changed and the + statement re-executed without needing to re-parse the statement or + re-bind. + + + + In Oracle, bind variables are commonly divided + into IN binds for values that are passed into + the database, and OUT binds for values that are + returned to PHP. A bind variable may be + both IN and OUT. Whether a + bind variable will be used for input or output is determined at + run-time. + + + + You must specify maxlength when using + an OUT bind so that PHP allocates enough memory + to hold the returned value. + + + + For IN binds it is recommended to set + the maxlength length if the statement is + re-executed multiple times with different values for the PHP + variable. Otherwise Oracle may truncate data to the length of the + initial PHP variable value. If you don't know what the maximum + length will be, then re-call oci_bind_by_name + with the current data size prior to + each oci_execute call. Binding an + unnecessarily large length will have an impact on process memory + in the database. + + + + A bind call tells Oracle which memory address to read data from. + For IN binds that address needs to contain + valid data when oci_execute is called. This + means that the variable bound must remain in scope until + execution. If it doesn't, unexpected results or errors such as + "ORA-01460: unimplemented or unreasonable conversion requested" + may occur. For OUT binds one symptom is no + value being set in the PHP variable. + + + + For a statement that is repeatedly executed, binding values that + never change may reduce the ability of the Oracle optimizer to + choose the best statement execution plan. Long running statements + that are rarely re-executed may not benefit from binding. However + in both cases, binding might be safer than joining strings into a + SQL statement, as this can be a security risk if unfiltered user + text is concatenated. @@ -32,23 +97,26 @@ statement - An OCI statement. + A valid OCI8 statement identifer. - ph_name + bv_name - The placeholder. + The colon-prefixed bind variable placeholder used in the + statement. The colon is optional + in bv_name. Oracle does not use question + marks for placeholders. - variable + variable - The PHP variable. + The PHP variable to be associated with bv_name @@ -56,23 +124,34 @@ maxlength - Sets the maximum length for the bind. If you set it to -1, this - function will use the current length of variable - to set the maximum length. + Sets the maximum length for the data. If you set it to -1, this + function will use the current length + of variable to set the maximum + length. In this case the variable must + exist and contain data + when oci_bind_by_name is called. type + + The datatype that Oracle will treat the data as. The + default type used + is SQLT_CHR. Oracle will convert the data + between this type and the database column (or PL/SQL variable + type), when possible. + If you need to bind an abstract datatype (LOB/ROWID/BFILE) you need to allocate it first using the oci_new_descriptor function. The length is not used for abstract datatypes - and should be set to -1. The type parameter - tells Oracle which descriptor is used. Default to SQLT_CHR. - Possible values are: + and should be set to -1. + + + Possible values for type are: @@ -138,8 +217,8 @@ - SQLT_RSET or - for cursors, that were created - before with oci_new_cursor. + SQLT_RSET - for cursors created + with oci_new_cursor. @@ -161,146 +240,518 @@ &reftitle.examples; - <function>oci_bind_by_name</function> example + Inserting data with <function>oci_bind_by_name</function> "Larry", - 2222 => "Bill", - 3333 => "Jim" - ); +$stid = oci_parse($conn,"INSERT INTO mytab (id, text) VALUES(:id_bv, :text_bv)"); + +$id = 1; +$text = "Data to insert "; +oci_bind_by_name($stid, ":id_bv", $id); +oci_bind_by_name($stid, ":text_bv", $text); +oci_execute($stid); + +// Table now contains: 1, 'Data to insert ' + +?> +]]> + + + + + + + Binding once for multiple executions + + +]]> + + + + + + + Binding with a <function>foreach</function> loop + + 'IT Support', ':loc' => 1700); + +foreach ($ba as $key => $val) { + + // oci_bind_by_name($stid, $key, $val) does not work + // because it binds each placeholder to the same location: $val + // instead use the actual location of the data: $ba[$key] + oci_bind_by_name($stid, $key, $ba[$key]); +} + +oci_execute($stid); +$row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS); +foreach ($row as $item) { + print $item."
\n"; +} + +oci_free_statement($stid); +oci_close($conn); + +?> +]]> +
+
+
+ + + + Binding in a WHERE clause + +\n"; + +// Output is +// Kochhar + +oci_free_statement($stid); +oci_close($conn); + +?> +]]> + + + + + + + Binding with a LIKE clause + +\n"; +} +// Output is +// South Brunswick +// South San Francisco +// Southlake + +oci_free_statement($stid); +oci_close($conn); + +?> +]]> + + + + + + + Binding with REGEXP_LIKE + +\n"; +} +// Output is +// Beijing +// Singapore + +oci_free_statement($stid); +oci_close($conn); + +?> +]]> + + + + + + For a small, fixed number of IN clause conditions, use individual + bind variables. Values unknown at run time can be set to NULL. + This allows a single statement to be used by all application + users, maximizing Oracle DB cache efficiency. + + + + + Binding Multiple Values in an IN Clause + +\n"; +} + +// Output is +// Ernst +// Hunold + +oci_free_statement($stid); +oci_close($conn); + +?> +]]> + + + + + + + Binding a ROWID returned by a query + + +]]> + + + + + + + Binding a ROWID on INSERT + + "Larry", + 2222 => "Bill", + 3333 => "Jim"); -$sal = 10000; +// Salary of each person +$salary = 10000; -foreach ($data as $empno => $ename) { - oci_execute($stmt); - oci_execute($update); +// Insert and immediately update each row +foreach ($data as $id => $name) { + oci_execute($ins_stid); + oci_execute($upd_stid); } $rowid->free(); +oci_free_statement($upd_stid); +oci_free_statement($ins_stid); -oci_free_statement($update); -oci_free_statement($stmt); - -$stmt = oci_parse($conn, " - SELECT - * - FROM - emp - WHERE - empno - IN - (1111,2222,3333) - "); -oci_execute($stmt); - -while ($row = oci_fetch_assoc($stmt)) { +// Show the new rows +$stid = oci_parse($conn, "SELECT * FROM mytab"); +oci_execute($stid); +while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) { var_dump($row); } -oci_free_statement($stmt); - -/* delete our "junk" from the emp table.... */ -$stmt = oci_parse($conn, " - DELETE FROM - emp - WHERE - empno - IN - (1111,2222,3333) - "); -oci_execute($stmt); -oci_free_statement($stmt); - +oci_free_statement($stid); oci_close($conn); + ?> ]]> - - Remember, this function strips trailing whitespace. See the following - example: - + - <function>oci_bind_by_name</function> example + Binding for a PL/SQL stored function ]]> + - - <function>oci_bind_by_name</function> example + + Binding parameters for a PL/SQL stored procedure ]]> + + + + Binding a CLOB column + +save("A very long string"); + +oci_commit($conn); + +// Fetching CLOB data + +$query = 'SELECT myclob FROM mytab WHERE mykey = :mykey'; + +$stid = oci_parse ($conn, $query); +oci_bind_by_name($stid, ":mykey", $mykey, 5); +oci_execute($stid); + +print ''; +while ($row = oci_fetch_array($stid, OCI_ASSOC)) { + $result = $row['MYCLOB']->load(); + print ''; +} +print '
'.$result.'
'; + +?> +]]> +
+
+
+ @@ -316,21 +767,41 @@ oci_close($conn); Do not use magic_quotes_gpc or - addslashes and oci_bind_by_name - simultaneously as no quoting is needed and any magically applied quotes - will be written into your database as oci_bind_by_name - is not able to distinguish magically added quotings from those added - intentionally. + addslashes + and oci_bind_by_name simultaneously as no + quoting is needed. Any magically applied quotes will be written + into your database because oci_bind_by_name + inserts data verbatim and does not remove quotes or escape + characters. - In PHP versions before 5.0.0 you must use ocibindbyname instead. - This name still can be used, it was left as alias of - oci_bind_by_name for downwards compatability. - This, however, is deprecated and not recommended. + If you bind a string to a CHAR column in + a WHERE clause, remember that Oracle uses + blank-padded comparison semantics for CHAR + columns. Your PHP variable should be blank padded to the same + width as the column for the WHERE clause to + succeed. + + + In PHP versions before 5.0.0 you must + use ocibindbyname + instead. &oci.name.compat.note; + + + + + + &reftitle.seealso; + + + oci_bind_array_by_name + oci_parse + +