Documentation TYPO3 par Ameos |
00001 <?php 00002 /* 00003 V4.80 8 Mar 2006 (c) 2000-2006 John Lim (jlim@natsoft.com.my). All rights reserved. 00004 Released under both BSD license and Lesser GPL library license. 00005 Whenever there is any discrepancy between the two licenses, 00006 the BSD license will take precedence. 00007 Set tabs to 4 for best viewing. 00008 00009 Latest version is available at http://adodb.sourceforge.net 00010 00011 DB2 data driver. Requires ODBC. 00012 00013 From phpdb list: 00014 00015 Hi Andrew, 00016 00017 thanks a lot for your help. Today we discovered what 00018 our real problem was: 00019 00020 After "playing" a little bit with the php-scripts that try 00021 to connect to the IBM DB2, we set the optional parameter 00022 Cursortype when calling odbc_pconnect(....). 00023 00024 And the exciting thing: When we set the cursor type 00025 to SQL_CUR_USE_ODBC Cursor Type, then 00026 the whole query speed up from 1 till 10 seconds 00027 to 0.2 till 0.3 seconds for 100 records. Amazing!!! 00028 00029 Therfore, PHP is just almost fast as calling the DB2 00030 from Servlets using JDBC (don't take too much care 00031 about the speed at whole: the database was on a 00032 completely other location, so the whole connection 00033 was made over a slow network connection). 00034 00035 I hope this helps when other encounter the same 00036 problem when trying to connect to DB2 from 00037 PHP. 00038 00039 Kind regards, 00040 Christian Szardenings 00041 00042 2 Oct 2001 00043 Mark Newnham has discovered that the SQL_CUR_USE_ODBC is not supported by 00044 IBM's DB2 ODBC driver, so this must be a 3rd party ODBC driver. 00045 00046 From the IBM CLI Reference: 00047 00048 SQL_ATTR_ODBC_CURSORS (DB2 CLI v5) 00049 This connection attribute is defined by ODBC, but is not supported by DB2 00050 CLI. Any attempt to set or get this attribute will result in an SQLSTATE of 00051 HYC00 (Driver not capable). 00052 00053 A 32-bit option specifying how the Driver Manager uses the ODBC cursor 00054 library. 00055 00056 So I guess this means the message [above] was related to using a 3rd party 00057 odbc driver. 00058 00059 Setting SQL_CUR_USE_ODBC 00060 ======================== 00061 To set SQL_CUR_USE_ODBC for drivers that require it, do this: 00062 00063 $db = NewADOConnection('db2'); 00064 $db->curMode = SQL_CUR_USE_ODBC; 00065 $db->Connect($dsn, $userid, $pwd); 00066 00067 00068 00069 USING CLI INTERFACE 00070 =================== 00071 00072 I have had reports that the $host and $database params have to be reversed in 00073 Connect() when using the CLI interface. From Halmai Csongor csongor.halmai#nexum.hu: 00074 00075 > The symptom is that if I change the database engine from postgres or any other to DB2 then the following 00076 > connection command becomes wrong despite being described this version to be correct in the docs. 00077 > 00078 > $connection_object->Connect( $DATABASE_HOST, $DATABASE_AUTH_USER_NAME, $DATABASE_AUTH_PASSWORD, $DATABASE_NAME ) 00079 > 00080 > In case of DB2 I had to swap the first and last arguments in order to connect properly. 00081 00082 00083 */ 00084 00085 // security - hide paths 00086 if (!defined('ADODB_DIR')) die(); 00087 00088 if (!defined('_ADODB_ODBC_LAYER')) { 00089 include(ADODB_DIR."/drivers/adodb-odbc.inc.php"); 00090 } 00091 if (!defined('ADODB_DB2')){ 00092 define('ADODB_DB2',1); 00093 00094 class ADODB_DB2 extends ADODB_odbc { 00095 var $databaseType = "db2"; 00096 var $concat_operator = '||'; 00097 var $sysDate = 'CURRENT_DATE'; 00098 var $sysTimeStamp = 'CURRENT TIMESTAMP'; 00099 // The complete string representation of a timestamp has the form 00100 // yyyy-mm-dd-hh.mm.ss.nnnnnn. 00101 var $fmtTimeStamp = "'Y-m-d-H.i.s'"; 00102 var $ansiOuter = true; 00103 var $identitySQL = 'values IDENTITY_VAL_LOCAL()'; 00104 var $_bindInputArray = true; 00105 var $hasInsertID = true; 00106 00107 function ADODB_DB2() 00108 { 00109 if (strncmp(PHP_OS,'WIN',3) === 0) $this->curmode = SQL_CUR_USE_ODBC; 00110 $this->ADODB_odbc(); 00111 } 00112 00113 function IfNull( $field, $ifNull ) 00114 { 00115 return " COALESCE($field, $ifNull) "; // if DB2 UDB 00116 } 00117 00118 function ServerInfo() 00119 { 00120 //odbc_setoption($this->_connectionID,1,101 /*SQL_ATTR_ACCESS_MODE*/, 1 /*SQL_MODE_READ_ONLY*/); 00121 $vers = $this->GetOne('select versionnumber from sysibm.sysversions'); 00122 //odbc_setoption($this->_connectionID,1,101, 0 /*SQL_MODE_READ_WRITE*/); 00123 return array('description'=>'DB2 ODBC driver', 'version'=>$vers); 00124 } 00125 00126 function _insertid() 00127 { 00128 return $this->GetOne($this->identitySQL); 00129 } 00130 00131 function RowLock($tables,$where,$flds='1 as ignore') 00132 { 00133 if ($this->_autocommit) $this->BeginTrans(); 00134 return $this->GetOne("select $flds from $tables where $where for update"); 00135 } 00136 00137 function &MetaTables($ttype=false,$showSchema=false, $qtable="%", $qschema="%") 00138 { 00139 global $ADODB_FETCH_MODE; 00140 00141 $savem = $ADODB_FETCH_MODE; 00142 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00143 $qid = odbc_tables($this->_connectionID, "", $qschema, $qtable, ""); 00144 00145 $rs = new ADORecordSet_odbc($qid); 00146 00147 $ADODB_FETCH_MODE = $savem; 00148 if (!$rs) { 00149 $false = false; 00150 return $false; 00151 } 00152 $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change; 00153 00154 $arr =& $rs->GetArray(); 00155 //print_r($arr); 00156 00157 $rs->Close(); 00158 $arr2 = array(); 00159 00160 if ($ttype) { 00161 $isview = strncmp($ttype,'V',1) === 0; 00162 } 00163 for ($i=0; $i < sizeof($arr); $i++) { 00164 00165 if (!$arr[$i][2]) continue; 00166 if (strncmp($arr[$i][1],'SYS',3) === 0) continue; 00167 00168 $type = $arr[$i][3]; 00169 00170 if ($showSchema) $arr[$i][2] = $arr[$i][1].'.'.$arr[$i][2]; 00171 00172 if ($ttype) { 00173 if ($isview) { 00174 if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2]; 00175 } else if (strncmp($type,'T',1) === 0) $arr2[] = $arr[$i][2]; 00176 } else if (strncmp($type,'S',1) !== 0) $arr2[] = $arr[$i][2]; 00177 } 00178 return $arr2; 00179 } 00180 00181 function &MetaIndexes ($table, $primary = FALSE, $owner=false) 00182 { 00183 // save old fetch mode 00184 global $ADODB_FETCH_MODE; 00185 $save = $ADODB_FETCH_MODE; 00186 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00187 if ($this->fetchMode !== FALSE) { 00188 $savem = $this->SetFetchMode(FALSE); 00189 } 00190 $false = false; 00191 // get index details 00192 $table = strtoupper($table); 00193 $SQL="SELECT NAME, UNIQUERULE, COLNAMES FROM SYSIBM.SYSINDEXES WHERE TBNAME='$table'"; 00194 if ($primary) 00195 $SQL.= " AND UNIQUERULE='P'"; 00196 $rs = $this->Execute($SQL); 00197 if (!is_object($rs)) { 00198 if (isset($savem)) 00199 $this->SetFetchMode($savem); 00200 $ADODB_FETCH_MODE = $save; 00201 return $false; 00202 } 00203 $indexes = array (); 00204 // parse index data into array 00205 while ($row = $rs->FetchRow()) { 00206 $indexes[$row[0]] = array( 00207 'unique' => ($row[1] == 'U' || $row[1] == 'P'), 00208 'columns' => array() 00209 ); 00210 $cols = ltrim($row[2],'+'); 00211 $indexes[$row[0]]['columns'] = explode('+', $cols); 00212 } 00213 if (isset($savem)) { 00214 $this->SetFetchMode($savem); 00215 $ADODB_FETCH_MODE = $save; 00216 } 00217 return $indexes; 00218 } 00219 00220 // Format date column in sql string given an input format that understands Y M D 00221 function SQLDate($fmt, $col=false) 00222 { 00223 // use right() and replace() ? 00224 if (!$col) $col = $this->sysDate; 00225 $s = ''; 00226 00227 $len = strlen($fmt); 00228 for ($i=0; $i < $len; $i++) { 00229 if ($s) $s .= '||'; 00230 $ch = $fmt[$i]; 00231 switch($ch) { 00232 case 'Y': 00233 case 'y': 00234 $s .= "char(year($col))"; 00235 break; 00236 case 'M': 00237 $s .= "substr(monthname($col),1,3)"; 00238 break; 00239 case 'm': 00240 $s .= "right(digits(month($col)),2)"; 00241 break; 00242 case 'D': 00243 case 'd': 00244 $s .= "right(digits(day($col)),2)"; 00245 break; 00246 case 'H': 00247 case 'h': 00248 if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)"; 00249 else $s .= "''"; 00250 break; 00251 case 'i': 00252 case 'I': 00253 if ($col != $this->sysDate) 00254 $s .= "right(digits(minute($col)),2)"; 00255 else $s .= "''"; 00256 break; 00257 case 'S': 00258 case 's': 00259 if ($col != $this->sysDate) 00260 $s .= "right(digits(second($col)),2)"; 00261 else $s .= "''"; 00262 break; 00263 default: 00264 if ($ch == '\\') { 00265 $i++; 00266 $ch = substr($fmt,$i,1); 00267 } 00268 $s .= $this->qstr($ch); 00269 } 00270 } 00271 return $s; 00272 } 00273 00274 00275 function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false) 00276 { 00277 $nrows = (integer) $nrows; 00278 if ($offset <= 0) { 00279 // could also use " OPTIMIZE FOR $nrows ROWS " 00280 if ($nrows >= 0) $sql .= " FETCH FIRST $nrows ROWS ONLY "; 00281 $rs =& $this->Execute($sql,$inputArr); 00282 } else { 00283 if ($offset > 0 && $nrows < 0); 00284 else { 00285 $nrows += $offset; 00286 $sql .= " FETCH FIRST $nrows ROWS ONLY "; 00287 } 00288 $rs =& ADOConnection::SelectLimit($sql,-1,$offset,$inputArr); 00289 } 00290 00291 return $rs; 00292 } 00293 00294 }; 00295 00296 00297 class ADORecordSet_db2 extends ADORecordSet_odbc { 00298 00299 var $databaseType = "db2"; 00300 00301 function ADORecordSet_db2($id,$mode=false) 00302 { 00303 $this->ADORecordSet_odbc($id,$mode); 00304 } 00305 00306 function MetaType($t,$len=-1,$fieldobj=false) 00307 { 00308 if (is_object($t)) { 00309 $fieldobj = $t; 00310 $t = $fieldobj->type; 00311 $len = $fieldobj->max_length; 00312 } 00313 00314 switch (strtoupper($t)) { 00315 case 'VARCHAR': 00316 case 'CHAR': 00317 case 'CHARACTER': 00318 case 'C': 00319 if ($len <= $this->blobSize) return 'C'; 00320 00321 case 'LONGCHAR': 00322 case 'TEXT': 00323 case 'CLOB': 00324 case 'DBCLOB': // double-byte 00325 case 'X': 00326 return 'X'; 00327 00328 case 'BLOB': 00329 case 'GRAPHIC': 00330 case 'VARGRAPHIC': 00331 return 'B'; 00332 00333 case 'DATE': 00334 case 'D': 00335 return 'D'; 00336 00337 case 'TIME': 00338 case 'TIMESTAMP': 00339 case 'T': 00340 return 'T'; 00341 00342 //case 'BOOLEAN': 00343 //case 'BIT': 00344 // return 'L'; 00345 00346 //case 'COUNTER': 00347 // return 'R'; 00348 00349 case 'INT': 00350 case 'INTEGER': 00351 case 'BIGINT': 00352 case 'SMALLINT': 00353 case 'I': 00354 return 'I'; 00355 00356 default: return 'N'; 00357 } 00358 } 00359 } 00360 00361 } //define 00362 ?>