Source for file adodb-odbc.inc.php
Documentation is available at adodb-odbc.inc.php
V4.97 22 Jan 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). 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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Requires ODBC. Works on Windows and Unix.
define("_ADODB_ODBC_LAYER", 2 );
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive
// breaking backward-compat
//var $longreadlen = 8000; // default number of chars to return for a Blob/Long field
var $curmode = SQL_CUR_USE_DRIVER; // See sqlext.h, SQL_CUR_DEFAULT == SQL_CUR_USE_DRIVER == 2L
var $uCaseTables = true; // for meta* functions, uppercase table names
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
ADOConnection::outp("For odbc Connect(), $argDatabasename is not used. Place dsn in 1st parameter.");
if (isset ($php_errormsg)) $php_errormsg = '';
$this->_errorMsg = isset ($php_errormsg) ? $php_errormsg : '';
if (isset ($this->connectStmt)) $this->Execute($this->connectStmt);
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
if (isset ($php_errormsg)) $php_errormsg = '';
$this->_errorMsg = isset ($php_errormsg) ? $php_errormsg : '';
if ($this->debug && $argDatabasename) {
ADOConnection::outp("For odbc PConnect(), $argDatabasename is not used. Place dsn in 1st parameter.");
// print "dsn=$argDSN u=$argUsername p=$argPassword<br>"; flush();
$this->_errorMsg = isset ($php_errormsg) ? $php_errormsg : '';
if (isset ($this->connectStmt)) $this->Execute($this->connectStmt);
$first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT);
if (!isset ($rez['version'])) $rez['version'] = '';
return $this->Execute("insert into $seqname values($start)");
This algorithm is not very efficient, but works even if table locking
Will return false if unable to generate an ID after $MAXLOOPS attempts.
function GenID($seq= 'adodbseq',$start= 1)
// if you have to modify the parameter below, your database is overloaded,
// or you need to implement generation of id's yourself!
$num = $this->GetOne("select id from $seq");
$ok = $this->Execute("insert into $seq values($start)");
$this->Execute("update $seq set id=id+1 where id=$num");
if ($this->affected_rows() > 0) {
$fn($this->databaseType,'GENID',- 32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num);
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = $savem;
$ADODB_FETCH_MODE = $savem;
for ($i= 0; $i < sizeof($arr); $i++ ) {
if ($arr[$i][3]) $arr2[] = $arr[$i][3];
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = $savem;
$isview = strncmp($ttype,'V',1) === 0;
for ($i= 0; $i < sizeof($arr); $i++ ) {
if (!$arr[$i][2]) continue;
if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2];
} else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2];
} else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2];
See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcdatetime_data_type_changes.asp
#define SQL_UNKNOWN_TYPE 0
/ One-parameter shortcuts for date/time data types /
#define SQL_TYPE_TIMESTAMP 93
#define SQL_UNICODE (-95)
#define SQL_UNICODE_VARCHAR (-96)
#define SQL_UNICODE_LONGVARCHAR (-97)
case - 11: // uniqidentifier
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
/*if (false) { // after testing, confirmed that the following does not work becoz of a bug
$qid2 = odbc_tables($this->_connectionID);
$rs = new ADORecordSet_odbc($qid2);
$ADODB_FETCH_MODE = $savem;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
if ($table == strtoupper($rs->fields[2])) {
$qid = odbc_columns($this->_connectionID,$q,$o,strtoupper($table),'%');
if (empty($qid)) return $false;
$ADODB_FETCH_MODE = $savem;
// adodb_pr($rs->fields);
$fld->name = $rs->fields[3];
$fld->type = $this->ODBCTypes($rs->fields[4]);
// ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp
// access uses precision to store length for char/varchar
if ($fld->type == 'C' or $fld->type == 'X') {
$fld->max_length = $rs->fields[6];
else if ($rs->fields[4] <= - 95) // UNICODE
$fld->max_length = $rs->fields[7]/ 2;
$fld->max_length = $rs->fields[7];
$fld->max_length = $rs->fields[7];
$fld->not_null = !empty($rs->fields[10]);
$fld->scale = $rs->fields[8];
$rs->Close(); //-- crashes 4.03pl1 -- why?
if (empty($retarr)) $retarr = false;
// we don't know whether odbc driver is parsing prepared stmts, so just return sql
return array($sql,$stmt,false);
/* returns queryID or false */
function _query($sql,$inputarr= false)
if (isset ($php_errormsg)) $php_errormsg = '';
$this->_errorMsg = isset ($php_errormsg) ? $php_errormsg : '';
//@odbc_free_result($stmtid);
//@odbc_free_result($stmtid);
$this->_errorMsg = isset ($php_errormsg) ? $php_errormsg : '';
$this->_errorMsg = isset ($php_errormsg) ? $php_errormsg : '';
Insert a null into the blob field of the table first.
Then use UpdateBlob to store the blob.
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
function UpdateBlob($table,$column,$val,$where,$blobtype= 'BLOB')
return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false;
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
// the following is required for mysql odbc driver in 4.3.1 -- why?
//$this->ADORecordSet($id);
// returns the field object
$off= $fieldOffset+ 1; // offsets begin at 1
if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
/* Use associative array to get fields array */
// some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0
//$this->useFetchArray = $this->connection->useFetchArray;
// speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
while (!$this->EOF && $nrows != $cnt) {
$results[$cnt++ ] = $this->fields;
|