Source for file adodb-oci8.inc.php
Documentation is available at adodb-oci8.inc.php
version V4.97 22 Jan 2008 (c) 2000-2008 John Lim. All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Latest version is available at http://adodb.sourceforge.net
Code contributed by George Fourlanos <fou@infomap.gr>
13 Nov 2000 jlim - removed all ora_* references.
Allows you to use a date format other than the Oracle Lite default. When a literal
character string appears where a date value is expected, the Oracle Lite database
tests the string to see if it matches the formats of Oracle, SQL-92, or the value
specified for this parameter in the POLITE.INI file. Setting this parameter also
defines the default format used in the TO_CHAR or TO_DATE functions when no
other format string is supplied.
For Oracle the default is dd-mon-yy or dd-mon-yyyy, and for SQL-92 the default is
Using 'RR' in the format forces two-digit years less than or equal to 49 to be
interpreted as years in the 21st century (2000–2049), and years over 50 as years in
the 20th century (1950–1999). Setting the RR format as the default for all two-digit
year entries allows you to become year-2000 compliant. For example:
NLS_DATE_FORMAT='RR-MM-DD'
You can also modify the date format using the ALTER SESSION command.
# define the LOB descriptor type for the given type
# returns false if no LOB descriptor
case OCI_B_BFILE: $result = OCI_D_FILE; break;
case OCI_B_CFILEE: $result = OCI_D_FILE; break;
case OCI_B_CLOB: $result = OCI_D_LOB; break;
case OCI_B_BLOB: $result = OCI_D_LOB; break;
case OCI_B_ROWID: $result = OCI_D_ROWID; break;
default: $result = false; break;
var $metaDatabasesSQL = "SELECT USERNAME FROM ALL_USERS WHERE USERNAME NOT IN ('SYS','SYSTEM','DBSNMP','OUTLN') ORDER BY 1";
var $metaTablesSQL = "select table_name,table_type from cat where table_type in ('TABLE','VIEW') and table_name not like 'BIN\$%'"; // bin$ tables are recycle bin tables
var $metaColumnsSQL = "select cname,coltype,width, SCALE, PRECISION, NULLS, DEFAULTVAL from col where tname='%s' order by colno"; //changed by smondino@users.sourceforge. net
var $random = "abs(mod(DBMS_RANDOM.RANDOM,10000001)/10000000)";
var $leftOuter = ''; // oracle wierdness, $col = $value (+) for LEFT OUTER, $col (+)= $value for RIGHT OUTER
var $firstrows = true; // enable first rows optimization on SelectLimit()
var $NLS_DATE_FORMAT = 'YYYY-MM-DD'; // To include time, use 'RRRR-MM-DD HH24:MI:SS'
var $datetime = false; // MetaType('DATE') returns 'D' (datetime==false) or 'T' (datetime == true)
// var $ansiOuter = true; // if oracle9
/* Function &MetaColumns($table) added by smondino@users.sourceforge.net*/
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = $save;
while (!$rs->EOF) { //print_r($rs->fields);
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->max_length = $rs->fields[2];
$fld->scale = $rs->fields[3];
if ($rs->fields[1] == 'NUMBER') {
if ($rs->fields[3] == 0) $fld->type = 'INT';
$fld->max_length = $rs->fields[4];
$fld->not_null = (strncmp($rs->fields[5], 'NOT',3) === 0);
$fld->default_value = $rs->fields[6];
$rs = & $this->Execute("select TO_CHAR($this->sysTimeStamp,'YYYY-MM-DD HH24:MI:SS') from dual");
Multiple modes of connection are supported:
$conn->Connect(false,'scott','tiger');
$conn->Connect(false,'scott','tiger',$tnsname);
$conn->Connect($tnsname,'scott','tiger');
$conn->Connect($serveraddress,'scott,'tiger',$service_name);
$conn->connectSID = true;
$conn->Connect($serveraddress,'scott,'tiger',$SID);
(ADDRESS = (PROTOCOL = TCP)(HOST = kermit)(PORT = 1523))
(SERVICE_NAME = natsoft.domain)
There are 3 connection modes, 0 = non-persistent, 1 = persistent, 2 = force new connection
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$mode= 0)
if($argHostname) { // added by Jorma Tuomainen <jorma.tuomainen@ppoy.fi>
if (empty($argDatabasename)) $argDatabasename = $argHostname;
if(strpos($argHostname,":")) {
$argHostinfo= explode(":",$argHostname);
$argHostname= $argHostinfo[0];
$argHostport= $argHostinfo[1];
$argHostport = empty($this->port)? "1521" : $this->port;
$argDatabasename= "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=". $argHostname
. ")(PORT=$argHostport))(CONNECT_DATA=(SID=$argDatabasename)))";
$argDatabasename= "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=". $argHostname
. ")(PORT=$argHostport))(CONNECT_DATA=(SERVICE_NAME=$argDatabasename)))";
//if ($argHostname) print "<p>Connect: 1st argument should be left blank for $this->databaseType</p>";
OCIPLogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
OCIPLogon($argUsername,$argPassword, $argDatabasename)
OCINLogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
OCINLogon($argUsername,$argPassword, $argDatabasename);
OCILogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
OCILogon($argUsername,$argPassword, $argDatabasename);
// Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production With the Partitioning option JServer Release 8.1.7.0.0 - Production
// $vers = OCIServerVersion($this->_connectionID);
// if (strpos($vers,'8i') !== false) $this->ansiOuter = true;
$arr['compat'] = $this->GetOne('select value from sys.database_compatible_level');
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,1);
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,2);
function IfNull( $field, $ifNull )
return " NVL($field, $ifNull) "; // if Oracle
// format and return date string in database date format
if (empty($d) && $d !== 0) return 'null';
// format and return date string in database timestamp format
if (empty($ts) && $ts !== 0) return 'null';
return 'TO_DATE('. adodb_date("'Y-m-d H:i:s'",$ts). ",'RRRR-MM-DD, HH24:MI:SS')";
function RowLock($tables,$where,$flds= '1 as ignore')
return $this->GetOne("select $flds from $tables where $where for update");
function &MetaTables($ttype= false,$showSchema= false,$mask= false)
function &MetaIndexes ($table, $primary = FALSE, $owner= false)
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$rs = $this->Execute(sprintf("SELECT * FROM ALL_CONSTRAINTS WHERE UPPER(TABLE_NAME)='%s' AND CONSTRAINT_TYPE='P'",$table));
if ($row = $rs->FetchRow())
$primary_key = $row[1]; //constraint_name
if ($primary== TRUE && $primary_key== '') {
$ADODB_FETCH_MODE = $save;
return $false; //There is no primary key
$rs = $this->Execute(sprintf("SELECT ALL_INDEXES.INDEX_NAME, ALL_INDEXES.UNIQUENESS, ALL_IND_COLUMNS.COLUMN_POSITION, ALL_IND_COLUMNS.COLUMN_NAME FROM ALL_INDEXES,ALL_IND_COLUMNS WHERE UPPER(ALL_INDEXES.TABLE_NAME)='%s' AND ALL_IND_COLUMNS.INDEX_NAME=ALL_INDEXES.INDEX_NAME",$table));
$ADODB_FETCH_MODE = $save;
// parse index data into array
while ($row = $rs->FetchRow()) {
if ($primary && $row[0] != $primary_key) continue;
if (!isset ($indexes[$row[0]])) {
$indexes[$row[0]] = array(
'unique' => ($row[1] == 'UNIQUE'),
$indexes[$row[0]]['columns'][$row[2] - 1] = $row[3];
// sort columns by order in the index
ksort ($indexes[$index]['columns']);
$ADODB_FETCH_MODE = $save;
$this->_commit = OCI_COMMIT_ON_SUCCESS;
$this->_commit = OCI_COMMIT_ON_SUCCESS;
if ($arr === false) return '';
if ($arr == false) $arr = @OCIError();
if ($arr == false) return '';
// Format date column in sql string given an input format that understands Y M D
$s = 'TO_CHAR('. $col. ",'";
for ($i= 0; $i < $len; $i++ ) {
// handle escape characters...
$sql = "SELECT * FROM ($sql ORDER BY dbms_random.value) WHERE rownum = 1";
return $this->GetRow($sql,$arr);
This algorithm makes use of
The FIRST_ROWS hint explicitly chooses the approach to optimize response time,
that is, minimum resource usage to return the first row. Results will be returned
as soon as they are identified.
b. Uses rownum tricks to obtain only the required rows from a given offset.
As this uses complicated sql statements, we only use this if the $offset >= 100.
This idea by Tomas V V Cox.
This implementation does not appear to work with oracle 8.0.5 or earlier. Comment
out this function then, and the slower SelectLimit() in the base class will be used.
function &SelectLimit($sql,$nrows=- 1,$offset=- 1, $inputarr= false,$secs2cache= 0)
// seems that oracle only supports 1 hint comment in 8i
$sql = preg_replace('/^[ \t\n]*select/i','SELECT /*+FIRST_ROWS*/',$sql);
if ($offset > 0) $nrows += $offset;
//$inputarr['adodb_rownum'] = $nrows;
$sql = "select * from (". $sql. ") where rownum <= ?";
$sql = "select * from (". $sql. ") where rownum <= :adodb_offset";
$inputarr['adodb_offset'] = $nrows;
// note that $nrows = 0 still has to work ==> no rows returned
// Algorithm by Tomas V V Cox, from PEAR DB oci8.php
// Let Oracle return the name of the columns
$q_fields = "SELECT * FROM (". $sql. ") WHERE NULL = NULL";
if (! $stmt_arr = $this->Prepare($q_fields)) {
foreach($inputarr as $k => $v) {
if (sizeof($v) == 2) // suggested by g.giunta@libero.
OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
if ($v === ' ') $len = 1;
if (isset ($bindarr)) { // is prepared sql, so no need to ocibindbyname again
} else { // dynamic sql, so rebind every time
OCIBindByName($stmt,":$k",$inputarr[$k],$len);
if (!OCIExecute($stmt, OCI_DEFAULT)) {
$ncols = OCINumCols($stmt);
for ( $i = 1; $i <= $ncols; $i++ ) {
$cols[] = '"'. OCIColumnName($stmt, $i). '"';
$offset += 1; // in Oracle rownum starts at 1
$sql = "SELECT $fields FROM".
"(SELECT rownum as adodb_rownum, $fields FROM".
" ($sql) WHERE rownum <= ?".
") WHERE adodb_rownum >= ?";
$sql = "SELECT $fields FROM".
"(SELECT rownum as adodb_rownum, $fields FROM".
" ($sql) WHERE rownum <= :adodb_nrows".
") WHERE adodb_rownum >= :adodb_offset";
$inputarr['adodb_nrows'] = $nrows;
$inputarr['adodb_offset'] = $offset;
if ($secs2cache> 0) $rs = & $this->CacheExecute($secs2cache, $sql,$inputarr);
else $rs = & $this->Execute($sql,$inputarr);
* Example: to store $var in a blob
* $conn->Execute('insert into TABLE (id,ablob) values(12,empty_blob())');
* $conn->UpdateBlob('TABLE', 'ablob', $varHoldingBlob, 'ID=12', 'BLOB');
* $blobtype supports 'BLOB' and 'CLOB', but you need to change to 'empty_clob()'.
* select DBMS_LOB.GETLENGTH(ablob) from TABLE
* If you are using CURSOR_SHARING = force, it appears this will case a segfault
* under oracle 8.1.7.0. Run:
* $db->Execute('ALTER SESSION SET CURSOR_SHARING=EXACT');
* before UpdateBlob() then...
function UpdateBlob($table,$column,$val,$where,$blobtype= 'BLOB')
//if (strlen($val) < 4000) return $this->Execute("UPDATE $table SET $column=:blob WHERE $where",array('blob'=>$val)) != false;
case 'BLOB': $type = OCI_B_BLOB; break;
case 'CLOB': $type = OCI_B_CLOB; break;
$sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO ?";
$sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO :blob";
$arr['blob'] = array($desc,- 1,$type);
if ($rez = !empty($rs)) $desc->save($val);
* Usage: store file pointed to by $var in a blob
case 'BLOB': $type = OCI_B_BLOB; break;
case 'CLOB': $type = OCI_B_CLOB; break;
$sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO ?";
$sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO :blob";
$arr['blob'] = array($desc,- 1,$type);
if ($rez = !empty($rs)) $desc->savefile($val);
* @param sql SQL statement to execute, or possibly an array holding prepared statement ($sql[0] will hold sql text)
* @param [inputarr] holds the input data to bind to. Null elements will be set to null.
* @return RecordSet or false
function &Execute($sql,$inputarr= false)
$ret = & $fn($this,$sql,$inputarr);
if (isset ($ret)) return $ret;
#if (!is_array($inputarr)) $inputarr = array($inputarr);
$element0 = reset($inputarr);
# is_object check because oci8 descriptors can be passed in
foreach($inputarr as $arr) {
$ret = & $this->_Execute($sql,$inputarr);
$stmt = $this->Prepare('insert into emp (empno, ename) values (:empno, :ename)');
function Prepare($sql,$cursor= false)
$stmt = OCIParse($this->_connectionID,$sql);
$sttype = @OCIStatementType($stmt);
if ($sttype == 'BEGIN' || $sttype == 'DECLARE') {
return array($sql,$stmt,0,$BINDNUM, ($cursor) ? OCINewCursor($this->_connectionID) : false);
return array($sql,$stmt,0,$BINDNUM);
Call an oracle stored procedure and returns a cursor variable as a recordset.
Concept by Robert Tuttle robert@ud.com
Note: we return a cursor variable in :RS2
$rs = $db->ExecuteCursor("BEGIN adodb.open_tab(:RS2); END;",'RS2');
$rs = $db->ExecuteCursor(
"BEGIN :RS2 = adodb.getdata(:VAR1); END;",
array('VAR1' => 'Mr Bean'));
$this->Parameter($stmt, $ignoreCur, $cursorName, false, - 1, OCI_B_CURSOR);
foreach($params as $k => $v) {
if ($rs->databaseType == 'array') OCIFreeCursor($stmt[4]);
else if ($hasref) $rs->_refcursor = $stmt[4];
Bind a variable -- very, very fast for executing repeated statements in oracle.
for ($i = 0; $i < $max; $i++) {
$p1 = ?; $p2 = ?; $p3 = ?;
$this->Execute("insert into table (col0, col1, col2) values (:0, :1, :2)",
$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:0, :1, :2)");
for ($i = 0; $i < $max; $i++) {
$p1 = ?; $p2 = ?; $p3 = ?;
** Test table has 3 cols, and 1 index. Test to insert 1000 records
Time 0.6081s (1644.60 inserts/sec) with direct OCIParse/OCIExecute
Time 0.6341s (1577.16 inserts/sec) with ADOdb Prepare/Bind/Execute
Time 1.5533s ( 643.77 inserts/sec) with pure SQL using Execute
Now if PHP only had batch/bulk updating like Java or PL/SQL...
Note that the order of parameters differs from OCIBindByName,
because we default the names to :0, :1, :2
function Bind(&$stmt,&$var,$size= 4000,$type= false,$name= false,$isOutput= false)
if (($type == OCI_B_CURSOR) && sizeof($stmt) >= 5) {
return OCIBindByName($stmt[1],":". $name,$stmt[4],$size,$type);
if ($type !== false) $rez = OCIBindByName($stmt[1],":". $stmt[2],$var,$size,$type);
else $rez = OCIBindByName($stmt[1],":". $stmt[2],$var,$size); // +1 byte for null terminator
//we have to create a new Descriptor here
$this->_refLOBs[$numlob]['TYPE'] = $isOutput;
$tmp = &$this->_refLOBs[$numlob]['LOB'];
$rez = OCIBindByName($stmt[1], ":". $name, $tmp, - 1, $type);
ADOConnection::outp("<b>Bind</b>: descriptor has been allocated, var (". $name. ") binded");
// if type is input then write data to lob now
if ($isOutput == false) {
$tmp->WriteTemporary($var);
$this->_refLOBs[$numlob]['VAR'] = &$var;
$this->_refLOBs[$numlob]['VAR'] = &$var;
if ($type !== false) $rez = OCIBindByName($stmt[1],":". $name,$var,$size,$type);
else $rez = OCIBindByName($stmt[1],":". $name,$var,$size); // +1 byte for null terminator
function Param($name,$type= false)
$stmt = $db->Prepare('select * from table where id =:myid and group=:group');
$db->Parameter($stmt,$id,'myid');
$db->Parameter($stmt,$group,'group');
@param $stmt Statement returned by Prepare() or PrepareSP().
@param $var PHP variable to bind to
@param $name Name of stored procedure variable name to bind to.
@param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8.
@param [$maxLen] Holds an maximum length of the variable.
@param [$type] The data type of $var. Legal values depend on driver.
See OCIBindByName documentation at php.net.
function Parameter(&$stmt,&$var,$name,$isOutput= false,$maxLen= 4000,$type= false)
$prefix = ($isOutput) ? 'Out' : 'In';
$ztype = (empty($type)) ? 'false' : $type;
ADOConnection::outp( "{ $prefix}Parameter(\$stmt, \$php_var=' $var', \$name=' $name', \$maxLen= $maxLen, \$type= $ztype); ");
return $this->Bind($stmt,$var,$maxLen,$type,$name,$isOutput);
returns query ID if successful, otherwise false
1. $db->execute('select * from table');
2. $db->prepare('insert into table (a,b,c) values (:0,:1,:2)');
$db->execute($prepared_statement, array(1,2,3));
3. $db->execute('insert into table (a,b,c) values (:a,:b,:c)',array('a'=>1,'b'=>2,'c'=>3));
4. $db->prepare('insert into table (a,b,c) values (:0,:1,:2)');
$db->bind($stmt,1); $db->bind($stmt,2); $db->bind($stmt,3);
function _query($sql,$inputarr)
if (is_array($sql)) { // is prepared sql
// we try to bind to permanent array, so that OCIBindByName is persistent
// and carried out once only - note that max array element size is 4000 chars
if (isset ($this->_bind[$bindpos])) {
$bindarr = &$this->_bind[$bindpos];
// one statement to bind them all
foreach($inputarr as $k => $v) {
OCIBindByName($stmt,":$k",$bindarr[$k],is_string($v) && strlen($v)> 4000 ? - 1 : 4000);
$this->_bind[$bindpos] = &$bindarr;
if (!$stmt) return false;
foreach($inputarr as $k => $v) {
if (sizeof($v) == 2) // suggested by g.giunta@libero.
OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
if ($this->debug== 99) echo "name=:$k",' var='. $inputarr[$k][0],' len='. $v[1],' type='. $v[2],'<br>';
if ($v === ' ') $len = 1;
if (isset ($bindarr)) { // is prepared sql, so no need to ocibindbyname again
} else { // dynamic sql, so rebind every time
OCIBindByName($stmt,":$k",$inputarr[$k],$len);
if (OCIExecute($stmt,$this->_commit)) {
foreach ($this -> _refLOBs as $key => $value) {
$tmp = $this -> _refLOBs[$key]['LOB'] -> load();
//$_GLOBALS[$this -> _refLOBs[$key]['VAR']] = $tmp;
switch (@OCIStatementType($stmt)) {
if (is_array($sql) && !empty($sql[4])) {
$ok = OCIExecute($cursor);
// ociclose -- no because it could be used in a LOB?
foreach ($this ->_refLOBs as $key => $value) {
if ($internalKey) return array('ROWID');
// tested with oracle 8.1.7
$owner_clause = "AND ((a.OWNER = b.OWNER) AND (a.OWNER = UPPER('$owner')))";
SELECT /*+ RULE */ distinct b.column_name
FROM {$ptab}CONSTRAINTS a
WHERE ( UPPER(b.table_name) = ('$table'))
AND (UPPER(a.table_name) = ('$table') and a.constraint_type = 'P')
AND (a.constraint_name = b.constraint_name)";
// http://gis.mit.edu/classes/11.521/sqlnotes/referential_integrity.html
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
"select constraint_name,r_owner,r_constraint_name
where constraint_type = 'R' and table_name = $table $owner";
foreach($constraints as $constr) {
$cons = $this->qstr($constr[0]);
$rowner = $this->qstr($constr[1]);
$rcons = $this->qstr($constr[2]);
$cols = $this->GetArray("select column_name from {$tabp}cons_columns where constraint_name=$cons $owner order by position");
$tabcol = $this->GetArray("select table_name,column_name from {$tabp}cons_columns where owner=$rowner and constraint_name=$rcons order by position");
for ($i= 0, $max= sizeof($cols); $i < $max; $i++ ) {
$arr[$tabcol[$i][0]] = $cols[$i][0]. '='. $tabcol[$i][1];
$ADODB_FETCH_MODE = $save;
* An example is $db->qstr("Don't bother",magic_quotes_runtime());
* @param s the string to quote
* @param [magic_quotes] if $s is GET/POST var, set to get_magic_quotes_gpc().
* This undoes the stupidity of magic quotes for GPC.
* @return quoted string to be sent back to database
function qstr($s,$magic_quotes= false)
// undo magic quotes for "
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
$this->fetchMode = OCI_NUM+ OCI_RETURN_NULLS+ OCI_RETURN_LOBS; break;
$this->adodbFetchMode = $mode;
// based on idea by Gaetano Giunta to detect unusual oracle errors
// see http://phplens.com/lens/lensforum/msgs.php?id=6771
$err = OCIError($this->_queryID);
if ($err && $this->connection->debug) ADOConnection::outp($err);
/* Returns: an object containing field information.
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
$fld->name = OCIcolumnname($this->_queryID, $fieldOffset);
$fld->type = OCIcolumntype($this->_queryID, $fieldOffset);
$fld->max_length = OCIcolumnsize($this->_queryID, $fieldOffset);
$p = OCIColumnPrecision($this->_queryID, $fieldOffset);
$sc = OCIColumnScale($this->_queryID, $fieldOffset);
if ($p != 0 && $sc == 0) $fld->type = 'INT';
/* For some reason, OCIcolumnname fails when called after _initrs() so we cache it */
// 10% speedup to move MoveNext to child class
//global $ADODB_EXTENSION;if ($ADODB_EXTENSION) return @adodb_movenext($this);
if ($this->EOF) return false;
if(@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode))
# does not work as first record is retrieved in _initrs(), so is not included in GetArray()
function &GetArray($nRows = -1)
global $ADODB_OCI8_GETARRAY;
if (true || !empty($ADODB_OCI8_GETARRAY)) {
# does not support $ADODB_ANSI_PADDING_OFF
//OCI_RETURN_NULLS and OCI_RETURN_LOBS is set by OCIfetchstatement
switch($this->adodbFetchMode) {
$ncols = @OCIfetchstatement($this->_queryID, $results, 0, $nRows, OCI_FETCHSTATEMENT_BY_ROW+OCI_NUM);
$results = array_merge(array($this->fields),$results);
if (ADODB_ASSOC_CASE != 2 || $this->databaseType != 'oci8') break;
$ncols = @OCIfetchstatement($this->_queryID, $assoc, 0, $nRows, OCI_FETCHSTATEMENT_BY_ROW);
$results =& array_merge(array($this->fields),$assoc);
$results =& ADORecordSet::GetArray($nRows);
/* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */
for ($i= 1; $i < $offset; $i++ )
if (!@OCIFetch($this->_queryID)) return $arr;
while (!$this->EOF && $nrows != $cnt) {
$results[$cnt++ ] = $this->fields;
/* Use associative array to get fields array */
/* close() only needs to be called if you are worried about using too much memory while your script
is running. All associated result memory for the specified result identifier will automatically be freed. */
if (!empty($this->_refcursor)) {
OCIFreeCursor($this->_refcursor);
$this->_refcursor = false;
$len = $fieldobj->max_length;
if (isset ($this) && $len <= $this->blobSize) return 'C';
case 'TIMESTAMP': return 'T';
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
case ADODB_FETCH_ASSOC: $this->fetchMode = OCI_ASSOC+ OCI_RETURN_NULLS+ OCI_RETURN_LOBS; break;
case ADODB_FETCH_BOTH: $this->fetchMode = OCI_NUM+ OCI_ASSOC+ OCI_RETURN_NULLS+ OCI_RETURN_LOBS; break;
default: $this->fetchMode = OCI_NUM+ OCI_RETURN_NULLS+ OCI_RETURN_LOBS; break;
$this->adodbFetchMode = $mode;
$this->_queryID = $queryID;
return adodb_movenext($this);
|