V4.71 24 Jan 2006 (c) 2000-2006 John Lim (jlim#natsoft.com)
This software is dual licensed using BSD-Style and LGPL. This means you can use it in compiled proprietary and commercial products.
Useful ADOdb links: Download Other Docs
Introduction
Unique Features
How People are using ADOdb
Feature Requests and Bug Reports
Installation
Minimum Install
Initializing Code and Connectioning to Databases
Data Source Name (DSN) Support Connection Examples
High Speed ADOdb - tuning tips
Hacking and Modifying ADOdb Safely
PHP5 Features
foreach iterators exceptions
Supported Databases
Tutorials
Example 1: Select
Example 2: Advanced Select
Example 3: Insert
Example 4: Debugging rs2html
example
Example 5: MySQL and Menus
Example 6: Connecting to Multiple Databases at once
Example 7: Generating Update and Insert SQL
Example 8: Implementing Scrolling with Next and Previous
Example 9: Exporting in CSV or Tab-Delimited Format
Example 10: Custom filters
Example 11: Smart Transactions
Using Custom Error Handlers and PEAR_Error
Data Source Names
Caching
Pivot Tables
Variables: $ADODB_COUNTRECS
$ADODB_ANSI_PADDING_OFF
$ADODB_CACHE_DIR
$ADODB_FORCE_TYPE
$ADODB_FETCH_MODE
$ADODB_LANG
Constants: ADODB_ASSOC_CASE
ADOConnection
Connections: Connect PConnect
NConnect IsConnected
Executing SQL: Execute CacheExecute
SelectLimit CacheSelectLimit
Param Prepare PrepareSP
InParameter OutParameter AutoExecute
GetOne
CacheGetOne GetRow CacheGetRow
GetAll CacheGetAll GetCol
CacheGetCol GetAssoc CacheGetAssoc Replace
ExecuteCursor
(oci8 only)
Generates SQL strings: GetUpdateSQL GetInsertSQL
Concat IfNull length random substr
qstr Param OffsetDate SQLDate
DBDate DBTimeStamp
Blobs: UpdateBlob UpdateClob
UpdateBlobFile BlobEncode
BlobDecode
Paging/Scrolling: PageExecute CachePageExecute
Cleanup: CacheFlush Close
Transactions: StartTrans CompleteTrans
FailTrans HasFailedTrans
BeginTrans CommitTrans
RollbackTrans
Fetching Data: SetFetchMode
Strings: concat length qstr quote substr
Dates: DBDate DBTimeStamp UnixDate
UnixTimeStamp OffsetDate
SQLDate
Row Management: Affected_Rows Insert_ID RowLock
GenID CreateSequence DropSequence
Error Handling: ErrorMsg ErrorNo
MetaError MetaErrorMsg
Data Dictionary (metadata): MetaDatabases MetaTables
MetaColumns MetaColumnNames
MetaPrimaryKeys MetaForeignKeys
ServerInfo
Statistics and Query-Rewriting: LogSQL fnExecute
and fnCacheExecute
Deprecated: Bind BlankRecordSet
Parameter
ADORecordSet
Returns one field: Fields
Returns one row:FetchRow FetchInto
FetchObject FetchNextObject
FetchObj FetchNextObj
GetRowAssoc
Returns all rows:GetArray GetRows
GetAssoc
Scrolling:Move MoveNext MoveFirst
MoveLast AbsolutePosition CurrentRow
AtFirstPage AtLastPage
AbsolutePage
Menu generation:GetMenu GetMenu2
Dates:UserDate UserTimeStamp
UnixDate UnixTimeStamp
Recordset Info:RecordCount PO_RecordSet
NextRecordSet
Field Info:FieldCount FetchField
MetaType
Cleanup: Close
rs2html example
Differences between ADOdb and ADO
Database Driver Guide
Change Log
PHP's database access functions are not standardised. This creates a need for a database class library to hide the differences between the different database API's (encapsulate the differences) so we can easily switch databases. PHP 4.0.5 or later is now required (because we use array-based str_replace).
We currently support MySQL, Oracle, Microsoft SQL Server, Sybase, Sybase SQL Anywhere, Informix, PostgreSQL, FrontBase, SQLite, Interbase (Firebird and Borland variants), Foxpro, Access, ADO, DB2, SAP DB and ODBC. We have had successful reports of connecting to Progress and CacheLite via ODBC. We hope more people will contribute drivers to support other databases.
PHP4 supports session variables. You can store your session information using ADOdb for true portability and scalability. See adodb-session.php for more information.
Also read tips_portable_sql.htm for tips on writing portable SQL.
Feature requests and bug reports can be emailed to jlim#natsoft.com.my or posted to the ADOdb Help forums at http://phplens.com/lens/lensforum/topics.php?id=4.
Make sure you are running PHP 4.0.5 or later. Unpack all the files into a directory accessible by your webserver.
To test, try modifying some of the tutorial examples. Make sure you customize the connection settings correctly. You can debug using $db->debug = true as shown below:
<?php
include('adodb/adodb.inc.php');
$db = ADONewConnection($dbdriver); # eg 'mysql' or 'postgres'
$db->debug = true;
$db->Connect($server, $user, $password, $database);
$rs = $db->Execute('select * from some_small_table');
print "<pre>";
print_r($rs->GetRows());
print "</pre>";
?>
For developers who want to release a minimal install of ADOdb, you will need:
When running ADOdb, at least two files are loaded. First is adodb/adodb.inc.php, which contains all functions used by all database classes. The code specific to a particular database is in the adodb/driver/adodb-????.inc.php file.
For example, to connect to a mysql database:
include('/path/to/set/here/adodb.inc.php');
$conn = &ADONewConnection('mysql');
Whenever you need to connect to a database, you create a Connection object using the ADONewConnection($driver) function. NewADOConnection($driver) is an alternative name for the same function.
At this point, you are not connected to the database (no longer true if you pass in a dsn). You will first need to decide whether to use persistent or non-persistent connections. The advantage of persistent connections is that they are faster, as the database connection is never closed (even when you call Close()). Non-persistent connections take up much fewer resources though, reducing the risk of your database and your web-server becoming overloaded.
For persistent connections, use $conn->PConnect(), or $conn->Connect() for non-persistent connections. Some database drivers also support NConnect(), which forces the creation of a new connection.
Connection Gotcha: If you create two connections, but both use the same userid and password, PHP will share the same connection. This can cause problems if the connections are meant to different databases. The solution is to always use different userid's for different databases, or use NConnect().
Since ADOdb 4.51, you can connect to a database by passing a dsn to NewADOConnection() (or ADONewConnection, which is the same function). The dsn format is:
$driver://$username:$password@hostname/$database?options[=value]
NewADOConnection() calls Connect() or PConnect() internally for you. If the connection fails, false is returned.
# non-persistent connection
$dsn = 'mysql://root:pwd@localhost/mydb';
$db = NewADOConnection($dsn);
if (!$db) die("Connection failed");
# no need to call connect/pconnect!
$arr = $db->GetArray("select * from table");
# persistent connection
$dsn2 = 'mysql://root:pwd@localhost/mydb?persist';
If you have special characters such as /:? in your dsn, then you need to rawurlencode them first:
$pwd = rawurlencode($pwd);
$dsn = "mysql://root:$pwd@localhost/mydb";
Legal options are:
| For all drivers | 'persist', 'persistent', 'debug', 'fetchmode' |
| Interbase/Firebird | 'dialect','charset','buffers','role' |
| M'soft ADO | 'charpage' |
| MySQL | 'clientflags' |
| MySQLi | 'port', 'socket', 'clientflags' |
| Oci8 | 'nls_date_format','charset' |
For all drivers, when the options persist or persistent are set, a persistent connection is forced. The debug option enables debugging. The fetchmode calls SetFetchMode(). If no value is defined for an option, then the value is set to 1.
ADOdb DSN's are compatible with version 1.0 of PEAR DB's DSN format.
MySQL connections are very straightforward, and the parameters are identical to mysql_connect:
$conn = &ADONewConnection('mysql');
$conn->PConnect('localhost','userid','password','database');
# or dsn
$dsn = 'mysql://user:pwd@localhost/mydb';
$conn = ADONewConnection($dsn); # no need for Connect()
# or persistent dsn
$dsn = 'mysql://user:pwd@localhost/mydb?persist';
$conn = ADONewConnection($dsn); # no need for PConnect()
# a more complex example:
$pwd = urlencode($pwd);
$flags = MYSQL_CLIENT_COMPRESS;
$dsn = "mysql://user:$pwd@localhost/mydb?persist&clientflags=$flags";
$conn = ADONewConnection($dsn); # no need for PConnect()
For most drivers, you can use the standard function: Connect($server, $user, $password, $database), or a DSN since ADOdb 4.51. Exceptions to this are listed below.
PDO accepts a PDO connection string:
$conn = NewADConnection('pdo');
$conn->Connect('mysql:host=localhost',$user,$pwd,$mydb);
$conn->Connect('mysql:host=localhost;dbname=mydb',$user,$pwd);
$conn->Connect("mysql:host=localhost;dbname=mydb;username=$user;password=$pwd");
The DSN mechanism is also supported:
$conn = NewADConnection("pdo_mysql://user:pwd@localhost/mydb?persist"); # persist is optional
PostgreSQL 7 and 8 accepts connections using:
a. the standard connection string:
$conn = &ADONewConnection('postgres');
$conn->PConnect('host=localhost port=5432 dbname=mary');
b. the classical 4 parameters:
$conn->PConnect('localhost','userid','password','database');
c. dsn:
$dsn = 'postgres://user:pwd@localhost/mydb?persist'; # persist is optional $conn = ADONewConnection($dsn); # no need for Connect/PConnect
Here is an example of querying a LDAP server. Thanks to Josh Eldridge for the driver and this example:
require('/path/to/adodb.inc.php');
/* Make sure to set this BEFORE calling Connect() */
$LDAP_CONNECT_OPTIONS = Array(
Array ("OPTION_NAME"=>LDAP_OPT_DEREF, "OPTION_VALUE"=>2),
Array ("OPTION_NAME"=>LDAP_OPT_SIZELIMIT,"OPTION_VALUE"=>100),
Array ("OPTION_NAME"=>LDAP_OPT_TIMELIMIT,"OPTION_VALUE"=>30),
Array ("OPTION_NAME"=>LDAP_OPT_PROTOCOL_VERSION,"OPTION_VALUE"=>3),
Array ("OPTION_NAME"=>LDAP_OPT_ERROR_NUMBER,"OPTION_VALUE"=>13),
Array ("OPTION_NAME"=>LDAP_OPT_REFERRALS,"OPTION_VALUE"=>FALSE),
Array ("OPTION_NAME"=>LDAP_OPT_RESTART,"OPTION_VALUE"=>FALSE)
);
$host = 'ldap.baylor.edu';
$ldapbase = 'ou=People,o=Baylor University,c=US';
$ldap = NewADOConnection( 'ldap' );
$ldap->Connect( $host, $user_name='', $password='', $ldapbase );
echo "<pre>";
print_r( $ldap->ServerInfo() );
$ldap->SetFetchMode(ADODB_FETCH_ASSOC);
$userName = 'eldridge';
$filter="(|(CN=$userName*)(sn=$userName*)(givenname=$userName*)(uid=$userName*))";
$rs = $ldap->Execute( $filter );
if ($rs)
while ($arr = $rs->FetchRow()) {
print_r($arr);
}
$rs = $ldap->Execute( $filter );
if ($rs)
while (!$rs->EOF) {
print_r($rs->fields);
$rs->MoveNext();
}
print_r( $ldap->GetArray( $filter ) );
print_r( $ldap->GetRow( $filter ) );
$ldap->Close();
echo "</pre>";
Using DSN:
$dsn = "ldap://ldap.baylor.edu/ou=People,o=Baylor University,c=US"; $db = NewADOConnection($dsn);
$conn = &ADONewConnection('ibase');
$conn->PConnect('localhost:c:\ibase\employee.gdb','sysdba','masterkey');
Or dsn:
$dsn = 'firebird://user:pwd@localhost/mydb?persist&dialect=3'; # persist is optional
$conn = ADONewConnection($dsn); # no need for Connect/PConnect
$conn = &ADONewConnection('sqlite');
$conn->PConnect('c:\path\to\sqlite.db'); # sqlite will create if does not exist
Or dsn:
$path = urlencode('c:\path\to\sqlite.db');
$dsn = "sqlite://$path/?persist"; # persist is optional
$conn = ADONewConnection($dsn); # no need for Connect/PConnect
With oci8, you can connect in multiple ways. Note that oci8 works fine with newer versions of the Oracle, eg. 9i and 10g.
a. PHP and Oracle reside on the same machine, use default SID.
$conn->Connect(false, 'scott', 'tiger');
b. TNS Name defined in tnsnames.ora (or ONAMES or HOSTNAMES), eg. 'myTNS'
$conn->PConnect(false, 'scott', 'tiger', 'myTNS');
or
$conn->PConnect('myTNS', 'scott', 'tiger');
c. Host Address and SID
$conn->connectSID = true;
$conn->Connect('192.168.0.1', 'scott', 'tiger', 'SID');
d. Host Address and Service Name
$conn->Connect('192.168.0.1', 'scott', 'tiger', 'servicename');
e. Oracle connection string:
$cstr = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$host)(PORT=$port))
(CONNECT_DATA=(SID=$sid)))";
$conn->Connect($cstr, 'scott', 'tiger');
f. ADOdb dsn:
$dsn = 'oci8://user:pwd@tnsname/?persist'; # persist is optional
$conn = ADONewConnection($dsn); # no need for Connect/PConnect
$dsn = 'oci8://user:pwd@host/sid';
$conn = ADONewConnection($dsn);
$dsn = 'oci8://user:pwd@/'; # oracle on local machine
$conn = ADONewConnection($dsn);
You can also set the charSet for Oracle 9.2 and later, supported since PHP 4.3.2, ADOdb 4.54:
$conn->charSet = 'we8iso8859p1';
$conn->Connect(...);
# or
$dsn = 'oci8://user:pwd@tnsname/?charset=WE8MSWIN1252';
$db = ADONewConnection($dsn);
ODBC DSN's can be created in the ODBC control panel, or you can use a DSN-less connection.To use DSN-less connections with ODBC you need PHP 4.3 or later.
For Microsoft Access:
$db =& ADONewConnection('access');
$dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\northwind.mdb;Uid=Admin;Pwd=;";
$db->Connect($dsn);
For Microsoft SQL Server:
$db =& ADONewConnection('odbc_mssql');
$dsn = "Driver={SQL Server};Server=localhost;Database=northwind;";
$db->Connect($dsn,'userid','password');
or if you prefer to use the mssql extension (which is limited to mssql 6.5 functionality):
$db =& ADONewConnection('mssql');
$db->Execute('localhost', 'userid', 'password', 'northwind');
For DB2:
$db =& ADONewConnection('db2');
$dsn = "driver={IBM db2 odbc DRIVER};Database=sample;hostname=localhost;port=50000;protocol=TCPIP;".
"uid=root; pwd=secret";
$db->Connect($dsn);
DSN-less Connections with ADO<?php
include('adodb.inc.php');
$db = &ADONewConnection("ado_mssql");
print "<h1>Connecting DSN-less $db->databaseType...</h1>";
$myDSN="PROVIDER=MSDASQL;DRIVER={SQL Server};"
. "SERVER=flipper;DATABASE=ai;UID=sa;PWD=;" ; $db->Connect($myDSN); $rs = $db->Execute("select * from table"); $arr = $rs->GetArray(); print_r($arr); ?>
ADOdb is a big class library, yet it consistently beats all other PHP class libraries in performance. This is because it is designed in a layered fashion, like an onion, with the fastest functions in the innermost layer. Stick to the following functions for best performance:
Innermost Layer |
Connect, PConnect, NConnect |
The fastest way to access the field data is by accessing the array $recordset->fields directly. Also set the global variables $ADODB_FETCH_MODE = ADODB_FETCH_NUM, and (for oci8, ibase/firebird and odbc) $ADODB_COUNTRECS = false before you connect to your database.
Consider using bind parameters if your database supports it, as it improves query plan reuse. Use ADOdb's performance tuning system to identify bottlenecks quickly. At the time of writing (Dec 2003), this means oci8 and odbc drivers.
Lastly make sure you have a PHP accelerator cache installed such as APC, Turck MMCache, Zend Accelerator or ionCube.
Some examples:
| Fastest data retrieval using PHP | Fastest data retrieval using ADOdb extension |
$rs =& $rs->Execute($sql); |
$rs =& $rs->Execute($sql); |
Advanced Tips
If you have the ADOdb C extension installed, you can replace your calls to $rs->MoveNext() with adodb_movenext($rs). This doubles the speed of this operation. For retrieving entire recordsets at once, use GetArray(), which uses the high speed extension function adodb_getall($rs) internally.
Execute() is the default way to run queries. You can use the low-level functions _Execute() and _query() to reduce query overhead. Both these functions share the same parameters as Execute().
If you do not have any bind parameters or your database supports binding (without emulation), then you can call _Execute() directly. Calling this function bypasses bind emulation. Debugging is still supported in _Execute().
If you do not require debugging facilities nor emulated binding, and do not require a recordset to be returned, then you can call _query. This is great for inserts, updates and deletes. Calling this function bypasses emulated binding, debugging, and recordset handling. Either the resultid, true or false are returned by _query().
For Informix, you can disable scrollable cursors with $db->cursorType = 0.
You might want to modify ADOdb for your own purposes. Luckily you can still maintain backward compatibility by sub-classing ADOdb and using the $ADODB_NEWCONNECTION variable. $ADODB_NEWCONNECTION allows you to override the behaviour of ADONewConnection(). ADOConnection() checks for this variable and will call the function-name stored in this variable if it is defined.
In the following example, new functionality for the connection object is placed in the hack_mysql and hack_postgres7 classes. The recordset class naming convention can be controlled using $rsPrefix. Here we set it to 'hack_rs_', which will make ADOdb use hack_rs_mysql and hack_rs_postgres7 as the recordset classes.
class hack_mysql extends adodb_mysql {
var $rsPrefix = 'hack_rs_';
/* Your mods here */
}
class hack_rs_mysql extends ADORecordSet_mysql {
/* Your mods here */
}
class hack_postgres7 extends adodb_postgres7 {
var $rsPrefix = 'hack_rs_';
/* Your mods here */
}
class hack_rs_postgres7 extends ADORecordSet_postgres7 {
/* Your mods here */
}
$ADODB_NEWCONNECTION = 'hack_factory';
function& hack_factory($driver)
{
if ($driver !== 'mysql' && $driver !== 'postgres7') return false;
$driver = 'hack_'.$driver;
$obj = new $driver();
return $obj;
}
include_once('adodb.inc.php');
Don't forget to call the constructor of the parent class in your constructor. If you want to use the default ADOdb drivers return false in the above hack_factory() function.
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$rs = $db->Execute($sql);
foreach($rs as $k => $row) {
echo "r1=".$row[0]." r2=".$row[1]."<br>";
}
include("../adodb-exceptions.inc.php");
include("../adodb.inc.php");
try {
$db = NewADOConnection("oci8");
$db->Connect('','scott','bad-password');
} catch (exception $e) {
var_dump($e);
adodb_backtrace($e->gettrace());
}
Note that reaching EOF is not considered an error nor an exception.
| Name | Tested | Database | RecordCount() usable | Prerequisites | Operating Systems |
| access | B | Microsoft Access/Jet. You need to create an ODBC DSN. | Y/N | ODBC | Windows only |
| ado | B | Generic ADO, not tuned for specific databases. Allows DSN-less connections. For best performance, use an OLEDB provider. This is the base class for all ado drivers. You can set $db->codePage before connecting. |
? depends on database | ADO or OLEDB provider | Windows only |
| ado_access | B | Microsoft Access/Jet using ADO. Allows DSN-less connections. For best performance, use an OLEDB provider. | Y/N | ADO or OLEDB provider | Windows only |
| ado_mssql | B | Microsoft SQL Server using ADO. Allows DSN-less connections. For best performance, use an OLEDB provider. | Y/N | ADO or OLEDB provider | Windows only |
| db2 | A | DB2. Should work reliably as based on ODBC driver. | Y/N | DB2 CLI/ODBC interface | Unix and Windows. Unix install hints. I have had reports that the $host and $database params have to be reversed in Connect() when using the CLI interface. |
| vfp | A | Microsoft Visual FoxPro. You need to create an ODBC DSN. | Y/N | ODBC | Windows only |
| fbsql | C | FrontBase. | Y | ? | Unix and Windows |
| ibase | B | Interbase 6 or earlier. Some users report you might need
to use this $db->PConnect('localhost:c:/ibase/employee.gdb', "sysdba", "masterkey") to connect. Lacks Affected_Rows currently. You can set $db->role, $db->dialect, $db->buffers and $db->charSet before connecting. |
Y/N | Interbase client | Unix and Windows |
| firebird | C | Firebird version of interbase. | Y/N | Interbase client | Unix and Windows |
| borland_ibase | C | Borland version of Interbase 6.5 or later. Very sad that the forks differ. | Y/N | Interbase client | Unix and Windows |
| informix | C | Generic informix driver. Use this if you are using Informix 7.3 or later. | Y/N | Informix client | Unix and Windows |
| informix72 | C | Informix databases before Informix 7.3 that do no support SELECT FIRST. | Y/N | Informix client | Unix and Windows |
| ldap | C | LDAP driver. See this example for usage information. | LDAP extension | ? | |
| mssql | A | Microsoft SQL Server 7 and later. Works with Microsoft SQL Server 2000 also. Note that date formating is problematic with this driver. For example, the PHP mssql extension does not return the seconds for datetime! |
Y/N | Mssql client | Unix and Windows. |
| mssqlpo | A | Portable mssql driver. Identical to above mssql driver, except that '||', the concatenation operator, is converted to '+'. Useful for porting scripts from most other sql variants that use ||. |
Y/N | Mssql client | Unix and Windows. |
| mysql | A | MySQL without transaction support. You can also set $db->clientFlags before connecting. | Y | MySQL client | Unix and Windows |
| mysqlt or maxsql | A | MySQL with transaction support. We recommend using
|| as the concat operator for best portability. This can be done by running
MySQL using: |
Y/N | MySQL client | Unix and Windows |
| oci8 | A | Oracle 8/9. Has more functionality than oracle driver
(eg. Affected_Rows). You might have to putenv('ORACLE_HOME=...') before
Connect/PConnect. There are 2 ways of connecting
- with server IP and service name: Since 2.31, we support Oracle REF cursor variables directly (see ExecuteCursor). |
Y/N | Oracle client | Unix and Windows |
| oci805 | C | Supports reduced Oracle functionality for Oracle 8.0.5. SelectLimit is not as efficient as in the oci8 or oci8po drivers. | Y/N | Oracle client | Unix and Windows |
| oci8po | A | Oracle 8/9 portable driver. This is nearly identical with
the oci8 driver except (a) bind variables in Prepare() use the ? convention,
instead of :bindvar, (b) field names use the more common PHP convention
of lowercase names. Use this driver if porting from other databases is important. Otherwise the oci8 driver offers better performance. |
Y/N | Oracle client | Unix and Windows |
| odbc | A | Generic ODBC, not tuned for specific databases. To connect,
use PConnect('DSN','user','pwd'). This is the base class for all odbc derived drivers. |
? depends on database | ODBC | Unix and Windows. Unix hints. |
| odbc_mssql | C | Uses ODBC to connect to MSSQL | Y/N | ODBC | Unix and Windows. |
| odbc_oracle | C | Uses ODBC to connect to Oracle | Y/N | ODBC | Unix and Windows. |
| odbtp | C | Generic odbtp driver. Odbtp is a software for accessing Windows ODBC data sources from other operating systems. | Y/N | odbtp | Unix and Windows |
| odbtp_unicode | C | Odtbp with unicode support | Y/N | odbtp | Unix and Windows |
| oracle | C | Implements old Oracle 7 client API. Use oci8 driver if possible for better performance. | Y/N | Oracle client | Unix and Windows |
| netezza | C | Netezza driver. Netezza is based on postgres code-base. | Y | ? | ? |
| pdo | C | Generic PDO driver for PHP5. | Y | PDO extension and database specific drivers | Unix and Windows. |
| postgres | A | Generic PostgreSQL driver. Currently identical to postgres7 driver. | Y | PostgreSQL client | Unix and Windows. |
| postgres64 | A | For PostgreSQL 6.4 and earlier which does not support LIMIT internally. | Y | PostgreSQL client | Unix and Windows. |
| postgres7 | A | PostgreSQL which supports LIMIT and other version 7 functionality. | Y | PostgreSQL client | Unix and Windows. |
| postgres8 | A | PostgreSQL which supports version 8 functionality. | Y | PostgreSQL client | Unix and Windows. |
| sapdb | C | SAP DB. Should work reliably as based on ODBC driver. | Y/N | SAP ODBC client | ? |
| sqlanywhere | C | Sybase SQL Anywhere. Should work reliably as based on ODBC driver. | Y/N | SQL Anywhere ODBC client | ? |
| sqlite | B | SQLite. | Y | - | Unix and Windows. |
| sqlitepo | B | Portable SQLite driver. This is because assoc mode does not work like other drivers in sqlite.
Namely, when selecting (joining) multiple tables, the table
names are included in the assoc keys in the "sqlite" driver. In "sqlitepo" driver, the table names are stripped from the returned column names. When this results in a conflict, the first field get preference. |
Y | - | Unix and Windows. |
| sybase | C | Sybase. | Y/N | Sybase client | Unix and Windows. |
| sybase_ase | C | Sybase ASE. | Y/N | Sybase client | Unix and Windows. |
The "Tested" column indicates how extensively the code has been tested
and used.
A = well tested and used by many people
B = tested and usable, but some features might not be implemented
C = user contributed or experimental driver. Might not fully support all of
the latest features of ADOdb.
The column "RecordCount() usable" indicates whether RecordCount() return the number of rows, or returns -1 when a SELECT statement is executed. If this column displays Y/N then the RecordCount() is emulated when the global variable $ADODB_COUNTRECS=true (this is the default). Note that for large recordsets, it might be better to disable RecordCount() emulation because substantial amounts of memory are required to cache the recordset for counting. Also there is a speed penalty of 40-50% if emulation is required. This is emulated in most databases except for PostgreSQL and MySQL. This variable is checked every time a query is executed, so you can selectively choose which recordsets to count.
Task: Connect to the Access Northwind DSN, display the first 2 columns of each row.
In this example, we create a ADOConnection object, which represents the connection to the database. The connection is initiated with PConnect, which is a persistent connection. Whenever we want to query the database, we call the ADOConnection.Execute() function. This returns an ADORecordSet object which is actually a cursor that holds the current row in the array fields[]. We use MoveNext() to move from row to row.
NB: A useful function that is not used in this example is SelectLimit, which allows us to limit the number of rows shown.
<?
include('adodb.inc.php'); # load code common to ADOdb
$conn = &ADONewConnection('access'); # create a connection
$conn->PConnect('northwind'); # connect to MS-Access, northwind DSN
$recordSet = &$conn->Execute('select * from products');
if (!$recordSet)
print $conn->ErrorMsg();
else
while (!$recordSet->EOF) {
print $recordSet->fields[0].' '.$recordSet->fields[1].'<BR>';
$recordSet->MoveNext();
} $recordSet->Close(); # optional
$conn->Close(); # optional
?>
The $recordSet returned stores the current row in the $recordSet->fields array, indexed by column number (starting from zero). We use the MoveNext() function to move to the next row. The EOF property is set to true when end-of-file is reached. If an error occurs in Execute(), we return false instead of a recordset.
The $recordSet->fields[] array is generated by the PHP database
extension. Some database extensions only index by number and do not index the
array by field name. To force indexing by name - that is associative arrays
- use the SetFetchMode function. Each recordset saves and uses whatever fetch
mode was set when the recordset was created in Execute() or SelectLimit().
$db->SetFetchMode(ADODB_FETCH_NUM);
$rs1 = $db->Execute('select * from table');
$db->SetFetchMode(ADODB_FETCH_ASSOC);
$rs2 = $db->Execute('select * from table');
print_r($rs1->fields); # shows array([0]=>'v0',[1] =>'v1') print_r($rs2->fields); # shows array(['col1']=>'v0',['col2'] =>'v1')
To get the number of rows in the select statement, you can use $recordSet->RecordCount(). Note that it can return -1 if the number of rows returned cannot be determined.
Select a table, display the first two columns. If the second column is a date or timestamp, reformat the date to US format.
<?
include('adodb.inc.php'); # load code common to ADOdb
$conn = &ADONewConnection('access'); # create a connection
$conn->PConnect('northwind'); # connect to MS-Access, northwind dsn
$recordSet = &$conn->Execute('select CustomerID,OrderDate from Orders');
if (!$recordSet)
print $conn->ErrorMsg();
else
while (!$recordSet->EOF) {
$fld = $recordSet->FetchField(1); $type = $recordSet->MetaType($fld->type);
if ( $type == 'D' || $type == 'T')
print $recordSet->fields[0].' '.
$recordSet->UserDate($recordSet->fields[1],'m/d/Y').'<BR>';
else print $recordSet->fields[0].' '.$recordSet->fields[1].'<BR>';
$recordSet->MoveNext();
} $recordSet->Close(); # optional
$conn->Close(); # optional
?>
In this example, we check the field type of the second column using FetchField(). This returns an object with at least 3 fields.
We then use MetaType() to translate the native type to a generic type. Currently the following generic types are defined:
If the metatype is of type date or timestamp, then we print it using the user defined date format with UserDate(), which converts the PHP SQL date string format to a user defined one. Another use for MetaType() is data validation before doing an SQL insert or update.
Insert a row to the Orders table containing dates and strings that need to be quoted before they can be accepted by the database, eg: the single-quote in the word John's.
<?
include('adodb.inc.php'); # load code common to ADOdb
$conn = &ADONewConnection('access'); # create a connection
$conn->PConnect('northwind'); # connect to MS-Access, northwind dsn
$shipto = $conn->qstr("John's Old Shoppe");
$sql = "insert into orders (customerID,EmployeeID,OrderDate,ShipName) ";
$sql .= "values ('ANATR',2,".$conn->DBDate(time()).",$shipto)";
if ($conn->Execute($sql) === false) {
print 'error inserting: '.$conn->ErrorMsg().'<BR>';
}
?>
In this example, we see the advanced date and quote handling facilities of ADOdb. The unix timestamp (which is a long integer) is appropriately formated for Access with DBDate(), and the right escape character is used for quoting the John's Old Shoppe, which is John''s Old Shoppe and not PHP's default John's Old Shoppe with qstr().
Observe the error-handling of the Execute statement. False is returned by Execute() if an error occured. The error message for the last error that occurred is displayed in ErrorMsg(). Note: php_track_errors might have to be enabled for error messages to be saved.
<?
include('adodb.inc.php'); # load code common to ADOdb
$conn = &ADONewConnection('access'); # create a connection
$conn->PConnect('northwind'); # connect to MS-Access, northwind dsn
$shipto = $conn->qstr("John's Old Shoppe");
$sql = "insert into orders (customerID,EmployeeID,OrderDate,ShipName) ";
$sql .= "values ('ANATR',2,".$conn->FormatDate(time()).",$shipto)";
$conn->debug = true; if ($conn->Execute($sql) === false) print 'error inserting'; ?>
In the above example, we have turned on debugging by setting debug = true. This will display the SQL statement before execution, and also show any error messages. There is no need to call ErrorMsg() in this case. For displaying the recordset, see the rs2html() example.
Also see the section on Custom Error Handlers.
Connect to MySQL database agora, and generate a <select> menu from an SQL statement where the <option> captions are in the 1st column, and the value to send back to the server is in the 2nd column.
<?
include('adodb.inc.php'); # load code common to ADOdb
$conn = &ADONewConnection('mysql'); # create a connection
$conn->PConnect('localhost','userid','','agora');# connect to MySQL, agora db
$sql = 'select CustomerName, CustomerID from customers';
$rs = $conn->Execute($sql);
print $rs->GetMenu('GetCust','Mary Rosli');
?>
Here we define a menu named GetCust, with the menu option 'Mary Rosli' selected. See GetMenu(). We also have functions that return the recordset as an array: GetArray(), and as an associative array with the key being the first column: GetAssoc().
<?
include('adodb.inc.php'); # load code common to ADOdb
$conn1 = &ADONewConnection('mysql'); # create a mysql connection
$conn2 = &ADONewConnection('oracle'); # create a oracle connection
$conn1->PConnect($server, $userid, $password, $database);
$conn2->PConnect(false, $ora_userid, $ora_pwd, $oraname);
$conn1->Execute('insert ...');
$conn2->Execute('update ...');
?>
Since ADOdb 4.56, we support AutoExecute(), which simplifies things by providing an advanced wrapper for GetInsertSQL() and GetUpdateSQL(). For example, an INSERT can be carried out with:
$record["firstname"] = "Bob";
$record["lastname"] = "Smith";
$record["created"] = time();
$insertSQL = $conn->AutoExecute($rs, $record, 'INSERT');
and an UPDATE with:
$record["firstname"] = "Caroline";
$record["lastname"] = "Smith"; # Update Caroline's lastname from Miranda to Smith
$insertSQL = $conn->AutoExecute($rs, $record, 'UPDATE', 'id = 1');
The rest of this section is out-of-date:
ADOdb 1.31 and later supports two new recordset functions: GetUpdateSQL( ) and GetInsertSQL( ). This allow you to perform a "SELECT * FROM table query WHERE...", make a copy of the $rs->fields, modify the fields, and then generate the SQL to update or insert into the table automatically.
We show how the functions can be used when accessing a table with the following fields: (ID, FirstName, LastName, Created).
Before these functions can be called, you need to initialize the recordset by performing a select on the table. Idea and code by Jonathan Younger jyounger#unilab.com. Since ADOdb 2.42, you can pass a table name instead of a recordset into GetInsertSQL (in $rs), and it will generate an insert statement for that table.
<?$ADODB_FORCE_TYPE
#==============================================
# SAMPLE GetUpdateSQL() and GetInsertSQL() code
#==============================================
include('adodb.inc.php');
include('tohtml.inc.php');
#==========================
# This code tests an insert
$sql = "SELECT * FROM ADOXYZ WHERE id = -1";
# Select an empty record from the database
$conn = &ADONewConnection("mysql"); # create a connection
$conn->debug=1;
$conn->PConnect("localhost", "admin", "", "test"); # connect to MySQL, testdb
$rs = $conn->Execute($sql); # Execute the query and get the empty recordset
$record = array(); # Initialize an array to hold the record data to insert
# Set the values for the fields in the record
# Note that field names are case-insensitive
$record["firstname"] = "Bob";
$record["lastNamE"] = "Smith";
$record["creaTed"] = time();
# Pass the empty recordset and the array containing the data to insert
# into the GetInsertSQL function. The function will process the data and return
# a fully formatted insert sql statement.
$insertSQL = $conn->GetInsertSQL($rs, $record);
$conn->Execute($insertSQL); # Insert the record into the database
#==========================
# This code tests an update
$sql = "SELECT * FROM ADOXYZ WHERE id = 1";
# Select a record to update
$rs = $conn->Execute($sql); # Execute the query and get the existing record to update
$record = array(); # Initialize an array to hold the record data to update
# Set the values for the fields in the record
# Note that field names are case-insensitive
$record["firstname"] = "Caroline";
$record["LasTnAme"] = "Smith"; # Update Caroline's lastname from Miranda to Smith
# Pass the single record recordset and the array containing the data to update
# into the GetUpdateSQL function. The function will process the data and return
# a fully formatted update sql statement with the correct WHERE clause.
# If the data has not changed, no recordset is returned
$updateSQL = $conn->GetUpdateSQL($rs, $record);
$conn->Execute($updateSQL); # Update the record in the database
$conn->Close();
?>
The behaviour of AutoExecute(), GetUpdateSQL() and GetInsertSQL() when converting empty or null PHP variables to SQL is controlled by the global $ADODB_FORCE_TYPE variable. Set it to one of the values below. Default is ADODB_FORCE_VALUE (3):
0 = ignore empty fields. All empty fields in array are ignored.
1 = force null. All empty, php null and string 'null' fields are changed to sql NULL values.
2 = force empty. All empty, php null and string 'null' fields are changed to sql empty '' or 0 values.
3 = force value. Value is left as it is. Php null and string 'null' are set to sql NULL values and
empty fields '' are set to empty '' sql values.
define('ADODB_FORCE_IGNORE',0);
define('ADODB_FORCE_NULL',1);
define('ADODB_FORCE_EMPTY',2);
define('ADODB_FORCE_VALUE',3);
Thanks to Niko (nuko#mbnet.fi) for the $ADODB_FORCE_TYPE code.
Note: the constant ADODB_FORCE_NULLS is obsolete since 4.52 and is ignored. Set $ADODB_FORCE_TYPE = ADODB_FORCE_NULL for equivalent behaviour.
Since 4.62, the table name to be used can be overridden by setting $rs->tableName before AutoExecute(), GetInsertSQL() or GetUpdateSQL() is called.
The following code creates a very simple recordset pager, where you can scroll from page to page of a recordset.
include_once('../adodb.inc.php');
include_once('../adodb-pager.inc.php');
session_start();
$db = NewADOConnection('mysql');
$db->Connect('localhost','root','','xphplens');
$sql = "select * from adoxyz ";
$pager = new ADODB_Pager($db,$sql);
$pager->Render($rows_per_page=5);
This will create a basic record pager that looks like this:
|< <<
>> >|
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Page 8/10 |
The number of rows to display at one time is controled by the Render($rows) method. If you do not pass any value to Render(), ADODB_Pager will default to 10 records per page.
You can control the column titles by modifying your SQL (supported by most databases):
$sql = 'select id as "ID", firstname as "First Name",
lastname as "Last Name", created as "Date Created"
from adoxyz';
The above code can be found in the adodb/tests/testpaging.php example included with this release, and the class ADODB_Pager in adodb/adodb-pager.inc.php. The ADODB_Pager code can be adapted by a programmer so that the text links can be replaced by images, and the dull white background be replaced with more interesting colors.
You can also allow display of html by setting $pager->htmlSpecialChars = false.
Some of the code used here was contributed by Iván Oliva and Cornel G.
We provide some helper functions to export in comma-separated-value (CSV) and tab-delimited formats:
include_once('/path/to/adodb/toexport.inc.php');
include_once('/path/to/adodb/adodb.inc.php');
$db = &NewADOConnection('mysql');
$db->Connect($server, $userid, $password, $database);
$rs = $db->Execute('select fname as "First Name", surname as "Surname" from table');
print "<pre>";
print rs2csv($rs); # return a string, CSV formatprint '<hr>';
$rs->MoveFirst(); # note, some databases do not support MoveFirst
print rs2tab($rs,false); # return a string, tab-delimited
# false == suppress field names in first line
print '<hr>';
$rs->MoveFirst();
rs2tabout($rs); # send to stdout directly (there is also an rs2csvout function)
print "</pre>";
$rs->MoveFirst();
$fp = fopen($path, "w");
if ($fp) {
rs2csvfile($rs, $fp); # write to file (there is also an rs2tabfile function)
fclose($fp);
}
Carriage-returns or newlines are converted to spaces. Field names are returned in the first line of text. Strings containing the delimiter character are quoted with double-quotes. Double-quotes are double-quoted again. This conforms to Excel import and export guide-lines.
All the above functions take as an optional last parameter, $addtitles which
defaults to true. When set to false field names in the first line
are suppressed.
Sometimes we want to pre-process all rows in a recordset before we use it. For example, we want to ucwords all text in recordset.
include_once('adodb/rsfilter.inc.php');
include_once('adodb/adodb.inc.php');
// ucwords() every element in the recordset
function do_ucwords(&$arr,$rs)
{
foreach($arr as $k => $v) {
$arr[$k] = ucwords($v);
}
}
$db = NewADOConnection('mysql');
$db->PConnect('server','user','pwd','db');
$rs = $db->Execute('select ... from table');
$rs = RSFilter($rs,'do_ucwords');
The RSFilter function takes 2 parameters, the recordset, and the name of the filter function. It returns the processed recordset scrolled to the first record. The filter function takes two parameters, the current row as an array, and the recordset object. For future compatibility, you should not use the original recordset object.
$conn->BeginTrans();This is very complicated for large projects because you have to track the error status. Smart Transactions is much simpler. You start a smart transaction by calling StartTrans():
$ok = $conn->Execute($sql);
if ($ok) $ok = $conn->Execute($sql2);
if (!$ok) $conn->RollbackTrans();
else $conn->CommitTrans();
$conn->StartTrans();CompleteTrans() detects when an SQL error occurs, and will Rollback/Commit as appropriate. To specificly force a rollback even if no error occured, use FailTrans(). Note that the rollback is done in CompleteTrans(), and not in FailTrans().
$conn->Execute($sql);
$conn->Execute($Sql2);
$conn->CompleteTrans();
$conn->StartTrans();
$conn->Execute($sql);
if (!CheckRecords()) $conn->FailTrans();
$conn->Execute($Sql2);
$conn->CompleteTrans();
You can also check if a transaction has failed, using HasFailedTrans(), which returns true if FailTrans() was called, or there was an error in the SQL execution. Make sure you call HasFailedTrans() before you call CompleteTrans(), as it is only works between StartTrans/CompleteTrans.
Lastly, StartTrans/CompleteTrans is nestable, and only the outermost block is executed. In contrast, BeginTrans/CommitTrans/RollbackTrans is NOT nestable.
$conn->StartTrans();
$conn->Execute($sql);
$conn->StartTrans(); # ignored if (!CheckRecords()) $conn->FailTrans(); $conn->CompleteTrans(); # ignored $conn->Execute($Sql2); $conn->CompleteTrans();
Note: Savepoints are currently not supported.
ADOdb supports PHP5 exceptions. Just include adodb-exceptions.inc.php and you can now catch exceptions on errors as they occur.
include("../adodb-exceptions.inc.php");
include("../adodb.inc.php");
try {
$db = NewADOConnection("oci8://scott:bad-password@mytns/");
} catch (exception $e) {
var_dump($e);
adodb_backtrace($e->gettrace());
}
ADOdb also provides two custom handlers which you can modify for your needs. The first one is in the adodb-errorhandler.inc.php file. This makes use of the standard PHP functions error_reporting to control what error messages types to display, and trigger_error which invokes the default PHP error handler.
Including the above file will cause trigger_error($errorstring,E_USER_ERROR)
to be called when
(a) Connect() or PConnect() fails, or
(b) a function that executes SQL statements such as Execute() or SelectLimit()
has an error.
(c) GenID() appears to go into an infinite loop.
The $errorstring is generated by ADOdb and will contain useful debugging information similar to the error.log data generated below. This file adodb-errorhandler.inc.php should be included before you create any ADOConnection objects.
If you define error_reporting(0), no errors will be passed to the error handler. If you set error_reporting(E_ALL), all errors will be passed to the error handler. You still need to use ini_set("display_errors", "0" or "1") to control the display of errors.
<?php
error_reporting(E_ALL); # pass any error messages triggered to error handler
include('adodb-errorhandler.inc.php'); include('adodb.inc.php'); include('tohtml.inc.php'); $c = NewADOConnection('mysql'); $c->PConnect('localhost','root','','northwind'); $rs=$c->Execute('select * from productsz'); #invalid table productsz'); if ($rs) rs2html($rs); ?>
If you want to log the error message, you can do so by defining the following optional constants ADODB_ERROR_LOG_TYPE and ADODB_ERROR_LOG_DEST. ADODB_ERROR_LOG_TYPE is the error log message type (see error_log in the PHP manual). In this case we set it to 3, which means log to the file defined by the constant ADODB_ERROR_LOG_DEST.
<?phpThe following message will be logged in the error.log file:
error_reporting(E_ALL); # report all errors
ini_set("display_errors", "0"); # but do not echo the errors
define('ADODB_ERROR_LOG_TYPE',3);
define('ADODB_ERROR_LOG_DEST','C:/errors.log');
include('adodb-errorhandler.inc.php'); include('adodb.inc.php'); include('tohtml.inc.php'); $c = NewADOConnection('mysql'); $c->PConnect('localhost','root','','northwind'); $rs=$c->Execute('select * from productsz'); ## invalid table productsz if ($rs) rs2html($rs); ?>
(2001-10-28 14:20:38) mysql error: [1146: Table 'northwind.productsz' doesn't exist] in
EXECUTE("select * from productsz")
<?php
include('adodb-errorpear.inc.php'); include('adodb.inc.php'); include('tohtml.inc.php'); $c = NewADOConnection('mysql'); $c->PConnect('localhost','root','','northwind'); $rs=$c->Execute('select * from productsz'); #invalid table productsz'); if ($rs) rs2html($rs); else { $e = ADODB_Pear_Error();
echo '<p>',$e->message,'</p>'; } ?>
You can use a PEAR_Error derived class by defining the constant ADODB_PEAR_ERROR_CLASS before the adodb-errorpear.inc.php file is included. For easy debugging, you can set the default error handler in the beginning of the PHP script to PEAR_ERROR_DIE, which will cause an error message to be printed, then halt script execution:
include('PEAR.php');
PEAR::setErrorHandling('PEAR_ERROR_DIE');
Note that we do not explicitly return a PEAR_Error object to you when an error occurs. We return false instead. You have to call ADODB_Pear_Error() to get the last error or use the PEAR_ERROR_DIE technique.
If you need error messages that work across multiple databases, then use MetaError(), which returns a virtualized error number, based on PEAR DB's error number system, and MetaErrMsg().
Error messages are outputted using the static method ADOConnnection::outp($msg,$newline=true). By default, it sends the messages to the client. You can override this to perform error-logging.
We now support connecting using PEAR style DSN's. A DSN is a connection string of the form:
$dsn = "$driver://$username:$password@$hostname/$databasename";
An example:
$username = 'root';
$password = '';
$hostname = 'localhost';
$databasename = 'xphplens';
$driver = 'mysql';
$dsn = "$driver://$username:$password@$hostname/$databasename"
$db = NewADOConnection();
# DB::Connect($dsn) also works if you include 'adodb/adodb-pear.inc.php' at the top
$rs = $db->query('select firstname,lastname from adoxyz');
$cnt = 0;
while ($arr = $rs->fetchRow()) {
print_r($arr); print "<br>";
}
More info and connection examples on the DSN format.
DB_Common query - returns PEAR_Error on error limitQuery - return PEAR_Error on error prepare - does not return PEAR_Error on error execute - does not return PEAR_Error on error setFetchMode - supports ASSOC and ORDERED errorNative quote nextID disconnect getOne getAssoc getRow getCol DB_Result numRows - returns -1 if not supported numCols fetchInto - does not support passing of fetchmode fetchRows - does not support passing of fetchmode free
ADOdb now supports caching of recordsets using the CacheExecute( ), CachePageExecute( ) and CacheSelectLimit( ) functions. There are similar to the non-cache functions, except that they take a new first parameter, $secs2cache.
An example:
include('adodb.inc.php'); # load code common to ADOdb
$ADODB_CACHE_DIR = '/usr/ADODB_cache';
$conn = &ADONewConnection('mysql'); # create a connection
$conn->PConnect('localhost','userid','','agora');# connect to MySQL, agora db
$sql = 'select CustomerName, CustomerID from customers';
$rs = $conn->CacheExecute(15,$sql);
The first parameter is the number of seconds to cache the query. Subsequent calls to that query will used the cached version stored in $ADODB_CACHE_DIR. To force a query to execute and flush the cache, call CacheExecute() with the first parameter set to zero. Alternatively, use the CacheFlush($sql) call.
For the sake of security, we recommend you set register_globals=off in php.ini if you are using $ADODB_CACHE_DIR.
In ADOdb 1.80 onwards, the secs2cache parameter is optional in CacheSelectLimit() and CacheExecute(). If you leave it out, it will use the $connection->cacheSecs parameter, which defaults to 60 minutes.
$conn->Connect(...);
$conn->cacheSecs = 3600*24; # cache 24 hours
$rs = $conn->CacheExecute('select * from table');
Please note that magic_quotes_runtime should be turned off. More
info, and do not change $ADODB_FETCH_MODE (or SetFetchMode)
as the cached recordset will use the $ADODB_FETCH_MODE set when the query was executed.
Pivot Tables
Since ADOdb 2.30, we support the generation of SQL to create pivot tables, also known as cross-tabulations. For further explanation read this DevShed Cross-Tabulation tutorial. We assume that your database supports the SQL case-when expression.
In this example, we will use the Northwind database from Microsoft. In the database, we have a products table, and we want to analyze this table by suppliers versus product categories. We will place the suppliers on each row, and pivot on categories. So from the table on the left, we generate the pivot-table on the right:
|
--> |
|
The following code will generate the SQL for a cross-tabulation:
# Query the main "product" table
# Set the rows to CompanyName
# and the columns to the values of Categories
# and define the joins to link to lookup tables
# "categories" and "suppliers"
#
include "adodb/pivottable.php";
$sql = PivotTableSQL(
$gDB, # adodb connection
'products p ,categories c ,suppliers s', # tables
'CompanyName', # rows (multiple fields allowed)
'CategoryName', # column to pivot on
'p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID' # joins/where
);
This will generate the following SQL:
SELECT CompanyName,
SUM(CASE WHEN CategoryName='Beverages' THEN 1 ELSE 0 END) AS "Beverages",
SUM(CASE WHEN CategoryName='Condiments' THEN 1 ELSE 0 END) AS "Condiments",
SUM(CASE WHEN CategoryName='Confections' THEN 1 ELSE 0 END) AS "Confections",
SUM(CASE WHEN CategoryName='Dairy Products' THEN 1 ELSE 0 END) AS "Dairy
Products",
SUM(CASE WHEN CategoryName='Grains/Cereals' THEN 1 ELSE 0 END) AS "Grains/Cereals",
SUM(CASE WHEN CategoryName='Meat/Poultry' THEN 1 ELSE 0 END) AS "Meat/Poultry",
SUM(CASE WHEN CategoryName='Produce' THEN 1 ELSE 0 END) AS "Produce",
SUM(CASE WHEN CategoryName='Seafood' THEN 1 ELSE 0 END) AS "Seafood",
SUM(1) as Total
FROM products p ,categories c ,suppliers s WHERE p.CategoryID = c.CategoryID
and s.SupplierID= p.SupplierID
GROUP BY CompanyName
You can also pivot on numerical columns and generate totals by using ranges. This code was revised in ADODB 2.41 and is not backward compatible. The second example shows this:
$sql = PivotTableSQL(
$gDB, # adodb connection
'products p ,categories c ,suppliers s', # tables
'CompanyName', # rows (multiple fields allowed) array( # column ranges ' 0 ' => 'UnitsInStock <= 0', "1 to 5" => '0 < UnitsInStock and UnitsInStock <= 5', "6 to 10" => '5 < UnitsInStock and UnitsInStock <= 10', "11 to 15" => '10 < UnitsInStock and UnitsInStock <= 15', "16+" => '15 < UnitsInStock' ), ' p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID', # joins/where 'UnitsInStock', # sum this field 'Sum ' # sum label prefix );
Which generates:
SELECT CompanyName,
SUM(CASE WHEN UnitsInStock <= 0 THEN UnitsInStock ELSE 0 END) AS "Sum
0 ",
SUM(CASE WHEN 0 < UnitsInStock and UnitsInStock <= 5 THEN UnitsInStock
ELSE 0 END) AS "Sum 1 to 5",
SUM(CASE WHEN 5 < UnitsInStock and UnitsInStock <= 10 THEN UnitsInStock
ELSE 0 END) AS "Sum 6 to 10",
SUM(CASE WHEN 10 < UnitsInStock and UnitsInStock <= 15 THEN UnitsInStock
ELSE 0 END) AS "Sum 11 to 15",
SUM(CASE WHEN 15 < UnitsInStock THEN UnitsInStock ELSE 0 END) AS "Sum
16+",
SUM(UnitsInStock) AS "Sum UnitsInStock",
SUM(1) as Total,
FROM products p ,categories c ,suppliers s WHERE p.CategoryID = c.CategoryID
and s.SupplierID= p.SupplierID
GROUP BY CompanyName
Function parameters with [ ] around them are optional.
If the database driver API does not support counting the number of records returned in a SELECT statement, the function RecordCount() is emulated when the global variable $ADODB_COUNTRECS is set to true, which is the default. We emulate this by buffering the records, which can take up large amounts of memory for big recordsets. Set this variable to false for the best performance. This variable is checked every time a query is executed, so you can selectively choose which recordsets to count.
If you are using recordset caching, this is the directory to save your recordsets in. Define this before you call any caching functions such as CacheExecute( ). We recommend setting register_globals=off in php.ini if you use this feature for security reasons.
If you are using Unix and apache, you might need to set your cache directory permissions to something similar to the following:
chown -R apache /path/to/adodb/cache
chgrp -R apache /path/to/adodb/cache
Determines whether to right trim CHAR fields (and also VARCHAR for ibase/firebird). Set to true to trim. Default is false. Currently works for oci8po, ibase and firebird drivers. Added in ADOdb 4.01.
Determines the language used in MetaErrorMsg(). The default is 'en', for English. To find out what languages are supported, see the files in adodb/lang/adodb-$lang.inc.php, where $lang is the supported langauge.
This is a global variable that determines how arrays are retrieved by recordsets. The recordset saves this value on creation (eg. in Execute( ) or SelectLimit( )), and any subsequent changes to $ADODB_FETCH_MODE have no affect on existing recordsets, only on recordsets created in the future.
The following constants are defined:
define('ADODB_FETCH_DEFAULT',0);
define('ADODB_FETCH_NUM',1);
define('ADODB_FETCH_ASSOC',2);
define('ADODB_FETCH_BOTH',3);
An example:
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$rs1 = $db->Execute('select * from table');
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rs2 = $db->Execute('select * from table');
print_r($rs1->fields); # shows array([0]=>'v0',[1] =>'v1') print_r($rs2->fields); # shows array(['col1']=>'v0',['col2'] =>'v1')
As you can see in the above example, both recordsets store and use different fetch modes based on the $ADODB_FETCH_MODE setting when the recordset was created by Execute().
If no fetch mode is predefined, the fetch mode defaults to ADODB_FETCH_DEFAULT. The behaviour of this default mode varies from driver to driver, so do not rely on ADODB_FETCH_DEFAULT. For portability, we recommend sticking to ADODB_FETCH_NUM or ADODB_FETCH_ASSOC. Many drivers do not support ADODB_FETCH_BOTH.
SetFetchMode Function
If you have multiple connection objects, and want to have different fetch modes for each connection, then use SetFetchMode. Once this function is called for a connection object, that connection object will ignore the global variable $ADODB_FETCH_MODE and will use the internal fetchMode property exclusively.
$db->SetFetchMode(ADODB_FETCH_NUM);
$rs1 = $db->Execute('select * from table');
$db->SetFetchMode(ADODB_FETCH_ASSOC);
$rs2 = $db->Execute('select * from table');
print_r($rs1->fields); # shows array([0]=>'v0',[1] =>'v1') print_r($rs2->fields); # shows array(['col1']=>'v0',['col2'] =>'v1')
To retrieve the previous fetch mode, you can use check the $db->fetchMode property, or use the return value of SetFetchMode( ).
You can control the associative fetch case for certain drivers which behave differently. For the sybase, oci8po, mssql, odbc and ibase drivers and all drivers derived from them, ADODB_ASSOC_CASE will by default generate recordsets where the field name keys are lower-cased. Use the constant ADODB_ASSOC_CASE to change the case of the keys. There are 3 possible values:
0 = assoc lowercase field names. $rs->fields['orderid']
1 = assoc uppercase field names. $rs->fields['ORDERID']
2 = use native-case field names. $rs->fields['OrderID'] -- this is the
default since ADOdb 2.90
To use it, declare it before you incldue adodb.inc.php.
define('ADODB_ASSOC_CASE', 2); # use native-case for ADODB_FETCH_ASSOC
include('adodb.inc.php');
See the GetUpdateSQL tutorial.
Object that performs the connection to the database, executes SQL statements and has a set of utility functions for standardising the format of SQL statements for issues such as concatenation and date formats.
databaseType: Name of the database system we are connecting to. Eg. odbc or mssql or mysql.
dataProvider: The underlying mechanism used to connect to the database. Normally set to native, unless using odbc or ado.
host: Name of server or data source name (DSN) to connect to.
database: Name of the database or to connect to. If ado is used, it will hold the ado data provider.
user: Login id to connect to database. Password is not saved for security reasons.
raiseErrorFn: Allows you to define an error handling function. See adodb-errorhandler.inc.php for an example.
debug: Set to true to make debug statements to appear.
concat_operator: Set to '+' or '||' normally. The operator used to concatenate strings in SQL. Used by the Concat function.
fmtDate: The format used by the DBDate function to send dates to the database. is '#Y-m-d#' for Microsoft Access, and ''Y-m-d'' for MySQL.
fmtTimeStamp: The format used by the DBTimeStamp function to send timestamps to the database.
true: The value used to represent true.Eg. '.T.'. for Foxpro, '1' for Microsoft SQL.
false: The value used to represent false. Eg. '.F.'. for Foxpro, '0' for Microsoft SQL.
replaceQuote: The string used to escape quotes. Eg. double single-quotes for Microsoft SQL, and backslash-quote for MySQL. Used by qstr.
autoCommit: indicates whether automatic commit is enabled. Default is true.
charSet: set the default charset to use. Currently only interbase/firebird supports this.
dialect: set the default sql dialect to use. Currently only interbase/firebird supports this.
role: set the role. Currently only interbase/firebird supports this.
metaTablesSQL: SQL statement to return a list of available tables. Eg. SHOW TABLES in MySQL.
genID: The latest id generated by GenID() if supported by the database.
cacheSecs: The number of seconds to cache recordsets if CacheExecute() or CacheSelectLimit() omit the $secs2cache parameter. Defaults to 60 minutes.
sysDate: String that holds the name of the database function to call to get the current date. Useful for inserts and updates.
sysTimeStamp: String that holds the name of the database function to call to get the current timestamp/datetime value.
leftOuter: String that holds operator for left outer join, if known. Otherwise set to false.
rightOuter: String that holds operator for left outer join, if known. Otherwise set to false.
ansiOuter: Boolean that if true indicates that ANSI style outer joins are permitted. Eg. select * from table1 left join table2 on p1=p2.
connectSID: Boolean that indicates whether to treat the $database parameter in connects as the SID for the oci8 driver. Defaults to false. Useful for Oracle 8.0.5 and earlier.
autoRollback: Persistent connections are auto-rollbacked in PConnect( ) if this is set to true. Default is false.
ADOConnection( )
Constructor function. Do not call this directly. Use ADONewConnection( ) instead.
Connect($host,[$user],[$password],[$database])
Non-persistent connect to data source or server $host, using userid $user and password $password. If the server supports multiple databases, connect to database $database.
Returns true/false depending on connection success. Since 4.23, null is returned if the extension is not loaded.
ADO Note: If you are using a Microsoft ADO and not OLEDB, you can set the $database parameter to the OLEDB data provider you are using.
PostgreSQL: An alternative way of connecting to the database is to pass the standard PostgreSQL connection string in the first parameter $host, and the other parameters will be ignored.
For Oracle and Oci8, there are two ways to connect. First is to use the TNS name defined in your local tnsnames.ora (or ONAMES or HOSTNAMES). Place the name in the $database field, and set the $host field to false. Alternatively, set $host to the server, and $database to the database SID, this bypassed tnsnames.ora.
Examples:
# $oraname in tnsnames.ora/ONAMES/HOSTNAMES
$conn->Connect(false, 'scott', 'tiger', $oraname);
$conn->Connect('server:1521', 'scott', 'tiger', 'ServiceName'); # bypass tnsnames.ora
There are many examples of connecting to a database. See Connection Examples for many examples.
PConnect($host,[$user],[$password],[$database])
Persistent connect to data source or server $host, using userid $user and password $password. If the server supports multiple databases, connect to database $database.
We now perform a rollback on persistent connection for selected databases since 2.21, as advised in the PHP manual. See change log or source code for which databases are affected.
Returns true/false depending on connection. Since 4.23, null is returned if the extension is not loaded. See Connect( ) above for more info.
Since ADOdb 2.21, we also support autoRollback. If you set:
$conn = &NewADOConnection('mysql');
$conn->autoRollback = true; # default is false
$conn->PConnect(...); # rollback here
Then when doing a persistent connection with PConnect( ), ADOdb will perform a rollback first. This is because it is documented that PHP is not guaranteed to rollback existing failed transactions when persistent connections are used. This is implemented in Oracle, MySQL, PgSQL, MSSQL, ODBC currently.
Since ADOdb 3.11, you can force non-persistent connections even if PConnect is called by defining the constant ADODB_NEVER_PERSIST before you call PConnect.
Since 4.23, null is returned if the extension is not loaded.
NConnect($host,[$user],[$password],[$database])
Always force a new connection. In contrast, PHP sometimes reuses connections when you use Connect() or PConnect(). Currently works only on mysql (PHP 4.3.0 or later), postgresql and oci8-derived drivers. For other drivers, NConnect() works like Connect().
Returns true if connected to database. Added in 4.53.
Execute SQL statement $sql and return derived class of ADORecordSet if successful. Note that a record set is always returned on success, even if we are executing an insert or update statement. You can also pass in $sql a statement prepared in Prepare().
Returns derived class of ADORecordSet. Eg. if connecting via mysql, then ADORecordSet_mysql would be returned. False is returned if there was an error in executing the sql.
The $inputarr parameter can be used for binding variables to parameters. Below is an Oracle example:
$conn->Execute("SELECT * FROM TABLE WHERE COND=:val", array('val'=> $val));
Another example, using ODBC,which uses the ? convention:
$conn->Execute("SELECT * FROM TABLE WHERE COND=?", array($val));
Binding variablesVariable binding speeds the compilation and caching of SQL statements, leading to higher performance. Currently Oracle, Interbase and ODBC supports variable binding. Interbase/ODBC style ? binding is emulated in databases that do not support binding. Note that you do not have to quote strings if you use binding.
Variable binding in the odbc, interbase and oci8po drivers.
$rs = $db->Execute('select * from table where val=?', array('10'));
Variable binding in the oci8 driver:
$rs = $db->Execute('select name from table where val=:key',
array('key' => 10));
Bulk binding
Since ADOdb 3.80, we support bulk binding in Execute(), in which you pass in a 2-dimensional array to be bound to an INSERT/UPDATE or DELETE statement.
$arr = array(
array('Ahmad',32),
array('Zulkifli', 24),
array('Rosnah', 21)
);
$ok = $db->Execute('insert into table (name,age) values (?,?)',$arr);
This provides very high performance as the SQL statement is prepared first. The prepared statement is executed repeatedly for each array row until all rows are completed, or until the first error. Very useful for importing data.
CacheExecute([$secs2cache,]$sql,$inputarr=false)
Similar to Execute, except that the recordset is cached for $secs2cache seconds in the $ADODB_CACHE_DIR directory, and $inputarr only accepts 1-dimensional arrays. If CacheExecute() is called again with the same $sql, $inputarr, and also the same database, same userid, and the cached recordset has not expired, the cached recordset is returned.
include('adodb.inc.php');
include('tohtml.inc.php');
$ADODB_CACHE_DIR = '/usr/local/ADOdbcache';
$conn = &ADONewConnection('mysql');
$conn->PConnect('localhost','userid','password','database');
$rs = $conn->CacheExecute(15, 'select * from table'); # cache 15 secs
rs2html($rs); /* recordset to html table */
Alternatively, since ADOdb 1.80, the $secs2cache parameter is optional:
$conn->Connect(...);If $secs2cache is omitted, we use the value in $connection->cacheSecs (default is 3600 seconds, or 1 hour). Use CacheExecute() only with SELECT statements.
$conn->cacheSecs = 3600*24; // cache 24 hours
$rs = $conn->CacheExecute('select * from table');
Performance note: I have done some benchmarks and found that they vary so greatly that it's better to talk about when caching is of benefit. When your database server is much slower than your Web server or the database is very overloaded then ADOdb's caching is good because it reduces the load on your database server. If your database server is lightly loaded or much faster than your Web server, then caching could actually reduce performance.
ExecuteCursor($sql,$cursorName='rs',$parameters=false)
Execute an Oracle stored procedure, and returns an Oracle REF cursor variable as a regular ADOdb recordset. Does not work with any other database except oci8. Thanks to Robert Tuttle for the design.
$db = ADONewConnection("oci8");
$db->Connect("foo.com:1521", "uid", "pwd", "FOO");
$rs = $db->ExecuteCursor("begin :cursorvar := getdata(:param1); end;",
'cursorvar',
array('param1'=>10));
# $rs is now just like any other ADOdb recordset object
rs2html($rs);
ExecuteCursor() is a helper function that does the following internally:
$stmt = $db->Prepare("begin :cursorvar := getdata(:param1); end;", true);
$db->Parameter($stmt, $cur, 'cursorvar', false, -1, OCI_B_CURSOR);
$rs = $db->Execute($stmt,$bindarr);
ExecuteCursor only accepts 1 out parameter. So if you have 2 out parameters, use:
$vv = 'A%';for the following PL/SQL:
$stmt = $db->PrepareSP("BEGIN list_tabs(:crsr,:tt); END;");
$db->OutParameter($stmt, $cur, 'crsr', -1, OCI_B_CURSOR);
$db->OutParameter($stmt, $vv, 'tt', 32); # return varchar(32)
$arr = $db->GetArray($stmt);
print_r($arr);
echo " val = $vv"; ## outputs 'TEST'
TYPE TabType IS REF CURSOR RETURN TAB%ROWTYPE;
PROCEDURE list_tabs(tabcursor IN OUT TabType,tablenames IN OUT VARCHAR) IS
BEGIN
OPEN tabcursor FOR SELECT * FROM TAB WHERE tname LIKE tablenames;
tablenames := 'TEST';
END list_tabs;
SelectLimit($sql,$numrows=-1,$offset=-1,$inputarr=false)
Returns a recordset if successful. Returns false otherwise. Performs a select statement, simulating PostgreSQL's SELECT statement, LIMIT $numrows OFFSET $offset clause.
In PostgreSQL, SELECT * FROM TABLE LIMIT 3 will return the first 3 records
only. The equivalent is $connection->SelectLimit('SELECT * FROM TABLE',3).
This functionality is simulated for databases that do not possess this feature.
And SELECT * FROM TABLE LIMIT 3 OFFSET 2 will return records 3, 4 and 5 (eg.
after record 2, return 3 rows). The equivalent in ADOdb is $connection->SelectLimit('SELECT
* FROM TABLE',3,2).
Note that this is the opposite of MySQL's LIMIT clause. You can also
set $connection->SelectLimit('SELECT * FROM TABLE',-1,10) to
get rows 11 to the last row.
The last parameter $inputarr is for databases that support variable binding such as Oracle oci8. This substantially reduces SQL compilation overhead. Below is an Oracle example:
$conn->SelectLimit("SELECT * FROM TABLE WHERE COND=:val", 100,-1,array('val'=> $val));
The oci8po driver (oracle portable driver) uses the more standard bind variable of ?:
$conn->SelectLimit("SELECT * FROM TABLE WHERE COND=?", 100,-1,array('val'=> $val));
Ron Wilson reports that SelectLimit does not work with UNIONs.
CacheSelectLimit([$secs2cache,] $sql, $numrows=-1,$offset=-1,$inputarr=false)
Similar to SelectLimit, except that the recordset returned is cached for $secs2cache seconds in the $ADODB_CACHE_DIR directory.
Since 1.80, $secs2cache has been optional, and you can define the caching time in $connection->cacheSecs.
$conn->Connect(...);
$conn->cacheSecs = 3600*24; // cache 24 hours
$rs = $conn->CacheSelectLimit('select * from table',10);
CacheFlush($sql=false,$inputarr=false)
Flush (delete) any cached recordsets for the SQL statement $sql in $ADODB_CACHE_DIR.
If no parameter is passed in, then all adodb_*.cache files are deleted.
If you want to flush all cached recordsets manually, execute the following
PHP code (works only under Unix):
system("rm -f `find ".$ADODB_CACHE_DIR." -name
adodb_*.cache`");
For general cleanup of all expired files, you should use crontab
on Unix, or at.exe on Windows, and a shell script similar to the following:
#------------------------------------------------------
# This particular example deletes files in the TMPPATH
# directory with the string ".cache" in their name that
# are more than 7 days old.
#------------------------------------------------------
AGED=7
find ${TMPPATH} -mtime +$AGED | grep "\.cache" | xargs rm -f
Returns a virtualized error number, based on PEAR DB's error number system. You might need to include adodb-error.inc.php before you call this function. The parameter $errno is the native error number you want to convert. If you do not pass any parameter, MetaError will call ErrorNo() for you and convert it. If the error number cannot be virtualized, MetaError will return -1 (DB_ERROR).
Pass the error number returned by MetaError() for the equivalent textual error message.
Returns the last status or error message. The error message is reset after every call to Execute().
This can return a string even if no error occurs. In general you do not need to call this function unless an ADOdb function returns false on an error.
Note: If debug is enabled, the SQL error message is always displayed when the Execute function is called.
Returns the last error number. The error number is reset after every call to Execute(). If 0 is returned, no error occurred.
Note that old versions of PHP (pre 4.0.6) do not support error number for ODBC. In general you do not need to call this function unless an ADOdb function returns false on an error.
Sets the current fetch mode for the connection and stores it in $db->fetchMode. Legal modes are ADODB_FETCH_ASSOC and ADODB_FETCH_NUM. For more info, see $ADODB_FETCH_MODE.
Returns the previous fetch mode, which could be false if SetFetchMode( ) has not been called before.
CreateSequence($seqName = 'adodbseq',$startID=1)
Create a sequence. The next time GenID( ) is called, the value returned will be $startID. Added in 2.60.
DropSequence($seqName = 'adodbseq')
Delete a sequence. Added in 2.60.
GenID($seqName = 'adodbseq',$startID=1)
Generate a sequence number . Works for interbase, mysql, postgresql, oci8, oci8po, mssql, ODBC based (access,vfp,db2,etc) drivers currently. Uses $seqName as the name of the sequence. GenID() will automatically create the sequence for you if it does not exist (provided the userid has permission to do so). Otherwise you will have to create the sequence yourself.
If your database driver emulates sequences, the name of the table is the sequence name. The table has one column, "id" which should be of type integer, or if you need something larger - numeric(16).
For ODBC and databases that do not support sequences natively (eg mssql, mysql), we create a table for each sequence. If the sequence has not been defined earlier, it is created with the starting value set in $startID.
Note that the mssql driver's GenID() before 1.90 used to generate 16 byte GUID's.
UpdateBlob($table,$column,$val,$where)
Allows you to store a blob (in $val) into $table into $column in a row at $where.Usage:
# for oracle
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, empty_blob())');
$conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');
# non oracle databases
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');
Returns true if succesful, false otherwise. Supported by MySQL, PostgreSQL, Oci8, Oci8po and Interbase drivers. Other drivers might work, depending on the state of development.
Note that when an Interbase blob is retrieved using SELECT, it still needs to be decoded using $connection->DecodeBlob($blob); to derive the original value in versions of PHP before 4.1.0.
For PostgreSQL, you can store your blob using blob oid's or as a bytea field.
You can use bytea fields but not blob oid's currently with UpdateBlob( ).
Conversely UpdateBlobFile( ) supports oid's, but not bytea data. If you do not have any blob fields, you can improve you can improve general SQL query performance by disabling blob handling with $connection->disableBlobs = true.
If you do not pass in an oid, then UpdateBlob() assumes that you are storing
in bytea fields.
UpdateClob($table,$column,$val,$where)
Allows you to store a clob (in $val) into $table into $column in a row at $where. Similar to UpdateBlob (see above), but for Character Large OBjects.Usage:
# for oracle
$conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, empty_clob())');
$conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');
# non oracle databases
$conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, null)');
$conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');
UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
Similar to UpdateBlob, except that we pass in a file path to where the blob resides.
For PostgreSQL, if you are using blob oid's, use this interface. This interface does not support bytea fields.
Returns true if successful, false otherwise.
Some databases require blob's to be encoded manually before upload. Note if you use UpdateBlob( ) or UpdateBlobFile( ) the conversion is done automatically for you and you do not have to call this function. For PostgreSQL, currently, BlobEncode() can only be used for bytea fields.
Returns the encoded blob value.
Note that there is a connection property called blobEncodeType which has 3 legal values:
false - no need to perform encoding or decoding.
'I' - blob encoding required, and returned encoded blob is a numeric value
(no need to quote).
'C' - blob encoding required, and returned encoded blob is a character value
(requires quoting).
This is purely for documentation purposes, so that programs that accept multiple database drivers know what is the right thing to do when processing blobs.
BlobDecode($blob, $maxblobsize = false)
Some databases require blob's to be decoded manually after doing a select statement. If the database does not require decoding, then this function will return the blob unchanged. Currently BlobDecode is only required for one database, PostgreSQL, and only if you are using blob oid's (if you are using bytea fields, we auto-decode for you). The default maxblobsize is set in $connection->maxblobsize, which is set to 256K in adodb 4.54.
In ADOdb 4.54 and later, the blob is the return value. In earlier versions, the blob data is sent to stdout.
$rs = $db->Execute("select bloboid from postgres_table where id=$key");
$blob = $db->BlobDecode( reset($rs->fields) );
Replace($table, $arrFields, $keyCols,$autoQuote=false)
Try to update a record, and if the record is not found, an insert statement is generated and executed. Returns 0 on failure, 1 if update statement worked, 2 if no record was found and the insert was executed successfully. This differs from MySQL's replace which deletes the record and inserts a new record. This also means you cannot update the primary key. The only exception to this is Interbase and its derivitives, which uses delete and insert because of some Interbase API limitations.
The parameters are $table which is the table name, the $arrFields which is an associative array where the keys are the field names, and $keyCols is the name of the primary key, or an array of field names if it is a compound key. If $autoQuote is set to true, then Replace() will quote all values that are non-numeric; auto-quoting will not quote nulls. Note that auto-quoting will not work if you use SQL functions or operators.
Examples:
# single field primary key
$ret = $db->Replace('atable',
array('id'=>1000,'firstname'=>'Harun','lastname'=>'Al-Rashid'),
'id',$autoquote = true);
# generates UPDATE atable SET firstname='Harun',lastname='Al-Rashid' WHERE id=1000
# or INSERT INTO atable (id,firstname,lastname) VALUES (1000,'Harun','Al-Rashid')
# compound key
$ret = $db->Replace('atable2',
array('firstname'=>'Harun','lastname'=>'Al-Rashid', 'age' => 33, 'birthday' => 'null'),
array('lastname','firstname'),
$autoquote = true);
# no auto-quoting
$ret = $db->Replace('atable2',
array('firstname'=>"'Harun'",'lastname'=>"'Al-Rashid'", 'age' => 'null'),
array('lastname','firstname'));
AutoExecute($table, $arrFields, $mode, $where=false, $forceUpdate=true,$magicq=false)
Since ADOdb 4.56, you can automatically generate and execute INSERTs and UPDATEs on a given table with this function, which is a wrapper for GetInsertSQL() and GetUpdateSQL().
AutoExecute() inserts or updates $table given an array of $arrFields, where the keys are the field names and the array values are the field values to store. Note that there is some overhead because the table is first queried to extract key information before the SQL is generated. We generate an INSERT or UPDATE based on $mode (see below).
Legal values for $mode are
You have to define the constants DB_AUTOQUERY_UPDATE and DB_AUTOQUERY_INSERT yourself or include adodb-pear.inc.php.
The $where clause is required if $mode == 'UPDATE'. If $forceUpdate=false then we will query the database first and check if the field value returned by the query matches the current field value; only if they differ do we update that field.
Returns true on success, false on error.
An example of its use is:
$record["firstName"] = "Carol";
$record["lasTname"] = "Smith";
$conn->AutoExecute($table,$record,'INSERT');
# executes "INSERT INTO $table (firstName,lasTname) values ('Carol',Smith')";
$record["firstName"] = "Carol";
$record["lasTname"] = "Jones";
$conn->AutoExecute($table,$record,'UPDATE', "lastname like 'Sm%'");
# executes "UPDATE $table SET firstName='Carol',lasTname='Jones' WHERE lastname like 'Sm%'";
Note: One of the strengths of ADOdb's AutoExecute() is that only valid field names for $table are updated. If $arrFields contains keys that are invalid field names for $table, they are ignored. There is some overhead in doing this as we have to query the database to get the field names, but given that you are not directly coding the SQL yourself, you probably aren't interested in speed at all, but convenience.
Since 4.62, the table name to be used can be overridden by setting $rs->tableName before AutoExecute(), GetInsertSQL() or GetUpdateSQL() is called.
GetUpdateSQL(&$rs, $arrFields, $forceUpdate=false,$magicq=false, $force=null)
Generate SQL to update a table given a recordset $rs, and the modified fields of the array $arrFields (which must be an associative array holding the column names and the new values) are compared with the current recordset. If $forceUpdate is true, then we also generate the SQL even if $arrFields is identical to $rs->fields. Requires the recordset to be associative. $magicq is used to indicate whether magic quotes are enabled (see qstr()). The field names in the array are case-insensitive.
Since 4.52, we allow you to pass the $force type parameter, and this overrides the $ADODB_FORCE_TYPE
global variable.
Since 4.62, the table name to be used can be overridden by setting $rs->tableName before AutoExecute(), GetInsertSQL() or GetUpdateSQL() is called.
GetInsertSQL(&$rs, $arrFields,$magicq=false,$force_type=false)
Generate SQL to insert into a table given a recordset $rs. Requires the query to be associative. $magicq is used to indicate whether magic quotes are enabled (for qstr()). The field names in the array are case-insensitive.
Since 2.42, you can pass a table name instead of a recordset into GetInsertSQL (in $rs), and it will generate an insert statement for that table.
Since 4.52, we allow you to pass the $force_type parameter, and this overrides the $ADODB_FORCE_TYPE
global variable.
Since 4.62, the table name to be used can be overridden by setting $rs->tableName before AutoExecute(), GetInsertSQL() or GetUpdateSQL() is called.
PageExecute($sql, $nrows, $page, $inputarr=false)
Used for pagination of recordset. $page is 1-based. See Example 8.
CachePageExecute($secs2cache, $sql, $nrows, $page, $inputarr=false)
Used for pagination of recordset. $page is 1-based. See Example 8. Caching version of PageExecute.
Close the database connection. PHP4 proudly states that we no longer have to clean up at the end of the connection because the reference counting mechanism of PHP4 will automatically clean up for us.
Start a monitored transaction. As SQL statements are executed, ADOdb will monitor for SQL errors, and if any are detected, when CompleteTrans() is called, we auto-rollback.
To understand why StartTrans() is superior to BeginTrans(), let us examine a few ways of using BeginTrans(). The following is the wrong way to use transactions:
$DB->BeginTrans();
$DB->Execute("update table1 set val=$val1 where id=$id");
$DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CommitTrans();
because you perform no error checking. It is possible to update table1 and for the update on table2 to fail. Here is a better way:
$DB->BeginTrans();
$ok = $DB->Execute("update table1 set val=$val1 where id=$id");
if ($ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id");
if ($ok) $DB->CommitTrans();
else $DB->RollbackTrans();
Another way is (since ADOdb 2.0):
$DB->BeginTrans();
$ok = $DB->Execute("update table1 set val=$val1 where id=$id");
if ($ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CommitTrans($ok);
Now it is a headache monitoring $ok all over the place. StartTrans() is an improvement because it monitors all SQL errors for you. This is particularly useful if you are calling black-box functions in which SQL queries might be executed. Also all BeginTrans, CommitTrans and RollbackTrans calls inside a StartTrans block will be disabled, so even if the black box function does a commit, it will be ignored.
$DB->StartTrans();
CallBlackBox();
$DB->Execute("update table1 set val=$val1 where id=$id");
$DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CompleteTrans();
Note that a StartTrans blocks are nestable, the inner blocks are ignore