Source for file adodb-db2.inc.php
Documentation is available at adodb-db2.inc.php
V4.97 22 Jan 2008 (c) 2006 John Lim (jlim#natsoft.com.my). All rights reserved.
This is a version of the ADODB driver for DB2. It uses the 'ibm_db2' PECL extension
for PHP (http://pecl.php.net/package/ibm_db2), which in turn requires DB2 V8.2.2 or
Originally tested with PHP 5.1.1 and Apache 2.0.55 on Windows XP SP2.
More recently tested with PHP 5.1.2 and Apache 2.0.55 on Windows XP SP2.
This file was ported from "adodb-odbc.inc.php" by Larry Menard, "larry.menard#rogers.com".
I ripped out what I believed to be a lot of redundant or obsolete code, but there are
probably still some remnants of the ODBC support in this file; I'm relying on reviewers
of this code to point out any other things that can be removed.
define("_ADODB_DB2_LAYER", 2 );
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive
// breaking backward-compat
var $_genSeqSQL = "CREATE SEQUENCE %s START WITH 1 NO MAXVALUE NO CYCLE";
var $uCaseTables = true; // for meta* functions, uppercase table names
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
ADOConnection::outp("Warning: The old ODBC based DB2 driver has been renamed 'odbc_db2'. This ADOdb driver calls PHP's native db2 extension.");
// This needs to be set before the connect().
// Replaces the odbc_binmode() call that was in Execute()
$this->_connectionID = db2_connect($argDatabasename,$argUsername,$argPassword);
$this->_connectionID = db2_connect($argDSN,$argUsername,$argPassword);
if (isset ($php_errormsg)) $php_errormsg = '';
// For db2_connect(), there is an optional 4th arg. If present, it must be
// an array of valid options. So far, we don't use them.
if (isset ($this->connectStmt)) $this->Execute($this->connectStmt);
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
// This needs to be set before the connect().
// Replaces the odbc_binmode() call that was in Execute()
if (isset ($php_errormsg)) $php_errormsg = '';
$this->_errorMsg = isset ($php_errormsg) ? $php_errormsg : '';
$this->_connectionID = db2_pconnect($argDatabasename,$argUsername,$argPassword);
$this->_connectionID = db2_pconnect($argDSN,$argUsername,$argPassword);
if (isset ($php_errormsg)) $php_errormsg = '';
if (isset ($this->connectStmt)) $this->Execute($this->connectStmt);
// format and return date string in database timestamp format
if (empty($ts) && $ts !== 0) return 'null';
// Format date column in sql string given an input format that understands Y M D
// use right() and replace() ?
/* use TO_CHAR() if $fmt is TO_CHAR() allowed fmt */
if ($fmt== 'Y-m-d H:i:s')
return 'TO_CHAR('. $col. ", 'YYYY-MM-DD HH24:MI:SS')";
for ($i= 0; $i < $len; $i++ ) {
if ($len== 1) return "year($col)";
$s .= "char(year($col))";
if ($len== 1) return "monthname($col)";
$s .= "substr(monthname($col),1,3)";
if ($len== 1) return "month($col)";
$s .= "right(digits(month($col)),2)";
if ($len== 1) return "day($col)";
$s .= "right(digits(day($col)),2)";
if ($len== 1) return "hour($col)";
if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)";
if ($len== 1) return "minute($col)";
$s .= "right(digits(minute($col)),2)";
if ($len== 1) return "second($col)";
$s .= "right(digits(second($col)),2)";
$first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT);
if (!isset ($rez['version'])) $rez['version'] = '';
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("VALUES NEXTVAL FOR $seq");
// 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];
function MetaForeignKeys($table, $owner = FALSE, $upper = FALSE, $asociative = FALSE )
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$qid = @db2_foreign_keys($this->_connectionID,'',$schema,$table);
$ADODB_FETCH_MODE = $savem;
$ADODB_FETCH_MODE = $savem;
if (!is_array($foreign_keys[$rs->fields[5]. '.'. $rs->fields[6]]))
$foreign_keys[$rs->fields[5]. '.'. $rs->fields[6]] = array();
$foreign_keys[$rs->fields[5]. '.'. $rs->fields[6]][$rs->fields[7]] = $rs->fields[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;
$schemaval = ($schema) ? $arr[$i][1]. '.' : '';
if (strncmp($type,'V',1) === 0) $arr2[] = $schemaval. $arr[$i][2];
} else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $schemaval. $arr[$i][2];
} else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $schemaval. $arr[$i][2];
See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2datetime_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;
$qid = db2_columns($this->_connectionID, "", $schema, $table, $colname);
if (empty($qid)) return $false;
$ADODB_FETCH_MODE = $savem;
$fld->name = $rs->fields[3];
$fld->type = $this->DB2Types($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') {
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];
$fld->primary_key = false;
if (empty($retarr)) $retarr = false;
$qid = db2_primary_keys($this->_connectionID, "", $schema, $table);
if (empty($qid)) return $false;
$ADODB_FETCH_MODE = $savem;
if (!$rs) return $retarr;
if (empty($retarr)) $retarr = false;
// we don't know whether db2 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 : '';
if (! db2_execute($stmtid,$inputarr)) {
if (!db2_execute($stmtid)) {
if (@db2_num_fields($stmtid) == 0) {
$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;
// returns the field object
$o->name = @db2_field_name($this->_queryID,$offset);
$o->type = @db2_field_type($this->_queryID,$offset);
$o->max_length = db2_field_width($this->_queryID,$offset);
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
// speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
while (!$this->EOF && $nrows != $cnt) {
$results[$cnt++ ] = $this->fields;
return @db2_free_result($this->_queryID);
|