V4.92 29 Ago 2006 (c) 2000-2006 John Lim (jlim#natsoft.com)
Este programa tiene licencia dual BSD-Style y LGPL. Esto significa que lo puedes usar tanto en productos comerciales como en propietarios.
Ligas utules de ADOdb: Descarga Otros manuales (en ingles) Otros manuales (en español
Introduccion
Caracteristicas Unicas
Como se esta usando actualmente ADOdb
Solicitud de mejoras y reporte de fallas
Instalacion
Instalacion Minima
Codigo de Inicio y Ejemplos de conexion
Soporte a DSN (Data Source Name)
Ejemplos de conexion
ADOdb de alta velocidad - trucos de optimizacion
Modificando y extendiendo ADOdb con seguridad
Caracteristicas para PHP5
foreach iterators exceptions
Base de datos soportadas
Tutoriales
Ejemplo 1: Select
Ejemplo 2: Select avanzado
Ejemplo 3: Insert
Ejemplo 4: Depurando Ejemplo rs2html
Ejemplo 5: MySQL y Menus
Ejemplo 6: Conectarase a multiples bases de datos al mismo tiempo
Ejemplo 7: Generando enunciados SQL de Update e Insert
Ejemplo 8: Implementando cursores con Siguiente y Anterior
Ejemplo 9: Exportando a formatos delimitados por Tabulador o comas
Ejemplo 10: Filtros a la medida
Ejemplo 11: Transacciones inteligentes
Usando manejadores de errores a la medida o de PEAR
Nombres de DSN
Memoria intermedia (Caching)
Tablas Pivote
Variables: $ADODB_COUNTRECS $ADODB_ANSI_PADDING_OFF
$ADODB_CACHE_DIR $ADODB_FORCE_TYPE
$ADODB_FETCH_MODE
$ADODB_LANG
Constantes: ADODB_ASSOC_CASE
ADOConnection
Conecciones: Connect PConnect
NConnect IsConnected
Ejecutando SQL: Execute CacheExecute
SelectLimit CacheSelectLimit
Param Prepare PrepareSP
InParameter OutParameter
AutoExecute
GetOne
CacheGetOne GetRow CacheGetRow
GetAll CacheGetAll GetCol
CacheGetCol GetAssoc CacheGetAssoc Replace
ExecuteCursor
(oci8 unicamente)
Generando enunciados SQL: GetUpdateSQL GetInsertSQL
Concat IfNull length random substr
qstr Param
OffsetDate SQLDate
DBDate DBTimeStamp
BindDate BindTimeStamp
Blobs: UpdateBlob UpdateClob
UpdateBlobFile BlobEncode
BlobDecode
Paginacion/Desplazamiento: PageExecute CachePageExecute
Limpieza: CacheFlush Close
Transacciones: StartTrans CompleteTrans
FailTrans HasFailedTrans
BeginTrans CommitTrans
RollbackTransSetTransactionMode
Recuperando Datos: SetFetchMode
Cadenas: concat length qstr quote substr
Fechas: DBDate DBTimeStamp UnixDate
UnixTimeStamp OffsetDate
SQLDate
Renglones: Affected_Rows Insert_ID RowLock
GenID CreateSequence DropSequence
Manejo de Errores: ErrorMsg ErrorNo
MetaError MetaErrorMsg
IgnoreErrors
Diccionario de datos (metadata): MetaDatabases MetaTables
MetaColumns MetaColumnNames
MetaPrimaryKeys MetaForeignKeys
ServerInfo
Estadisticas y modifacion de SQL: LogSQL fnExecute
and fnCacheExecute
Descontinuado: Bind BlankRecordSet
Parameter
ADORecordSet
Regresa un campo: Fields
Regresa un renglon:FetchRow FetchInto
FetchObject FetchNextObject
FetchObj FetchNextObj
GetRowAssoc
Regresa todos los renglones:GetArray GetRows
GetAssoc
Desplazamiento:Move MoveNext MoveFirst
MoveLast AbsolutePosition CurrentRow
AtFirstPage AtLastPage
AbsolutePage
Generacion de Menu:GetMenu GetMenu2
Fechas:UserDate UserTimeStamp
UnixDate UnixTimeStamp
Informacion del Recordset:RecordCount PO_RecordSet
NextRecordSet
Informacion de un campo:FieldCount FetchField
MetaType
Limpieza: Close
Diferencias entre ADOdb y ADO
Guia para manejadores de base de datos
Bitacora de cambios
Las funciones de acceso a base de datos en PHP no estan estandarizadas. Esto requiere una libreria que esconda las diferencias entre cada API de base de datos (encapsular las diferencias) para que podamos cambiar facilmente de base de datos. Se requiere la version de PHP 4.0.5 o posterior (debido a que usamos la funcion str_replace con arreglos).
Actualmente manejamos MySQL, Oracle, Microsoft SQL Server, Sybase, Sybase SQL Anywhere, Informix, PostgreSQL, FrontBase, SQLite, Interbase (versiones de Firebird y Borland), Foxpro, Access, ADO, DB2, SAP DB and ODBC. Tenemos noticias que se puede conectar a Progress y CacheLite via ODBC. Esperamos que mas personas contribuyan con drivers para manejar mas base de datos.
PHP4 maneja variables de sesion. Puedes almacenar la informacion de tu sesion usando ADOdb para tener una verdadera portabilidad y escalabilidad. Para mas informacion ve el archivo adodb-session.php.
Tambie lee tips_portable_sql-es.htm (tambien dispobible en ingles en el archivo tips_portable_sql.htm) para consejos para escribir enunciados SQL portables.
Las solicitudes de mejoras o reporte de fallas pueden ser enviadas por correo electronico a jlim#natsoft.com.my o publicadas en el foro de ayuda de ADOdb en http://phplens.com/lens/lensforum/topics.php?id=4.
Asegurate de estar usando PHP 4.0.5 o posterior. Descomprime todos los archivos en un directorio accesible por tu servidor Web.
Para probar, intenta modificar algunos de los ejemplos del tutorial. Asegurate de corregir los parametros de coneccion a tus necesidades. Puedes depurar el codigo usando $db->debug = true como se muestra a continuacion:
<?php
include('adodb/adodb.inc.php');
$db = ADONewConnection($dbdriver); # eg 'mysql' o 'postgres'
$db->debug = true;
$db->Connect($servidor, $usuario, $contraseña, $database);
$rs = $db->Execute('select * from alguna_tabla_pequeña');
print "<pre>";
print_r($rs->GetRows());
print "</pre>";
?>
Para los desarrolladores que quieran distribuir una version minima de ADOdb, se requieren los siguientes archivos:
Al ejecutar ADOdb, al menos se cargan dos archivos. Primero adodb/adodb.inc.php, que contienen todas las funciones usadas por todas las clases de bases de datos. El codigo especifico a una base de datos en particular esta en el archivo adodb/driver/adodb-????.inc.php.
Por ejemplo, para conectarse a una base de datos mysql:
include('adodb/adodb.inc.php');
$conn = &ADONewConnection('mysql');
Cada vez que necesitas conectarte a una base de datos, debes de crear un objeto de conexion usando la funcion ADONewConnection($driver). NewADOConnection($driver) es un nombre alterno para la misma funcion.
En este momento, no estas conectado a la base de datos (ya no es cierto si como parametro usas un dsn). Primero tienes que decidir si vas a usar una coneccion persistente o no persistente. La ventaja de las conexiones persistentes es que son mas rapidas, debido a que la conexion no es cerrada nunca (aun si usas Close()). Las conexiones No persistentes consumen menos recursos reduciendo el riesgo de sobrecargar la base de datos o el servidor Web.
Para conexiones persistentes, usa $conn->PConnect(), o $conn->Connect() para conexiones no persistentes. Algunas bases de datos tambien manejan NConnect(), la cual forza la creacion de una nueva conexion.
Problemas con Conexiones: Si creas dos conexiones, pero ambas usan el mismo usuario y contraseña, PHP compartira las conexiones. Esto puede causar problemas si se supone que las conexiones son a diferentes bases de datos. La solucion es usar siempre diferentes usuarios para diferentes bases de datos o usar NConnect().
Desde la version 4.51 de ADOdb, te puedes conectar a la base de datos pasando como argumento a NewADOConnection() (o ADONewConnection, que es la misma funcion) un dsn. El formato del dsn es:
$driver://$username:$password@hostname/$database?options[=value]
NewADOConnection() llama a Connect() o PConnect() internamente por ti. Si la conexion falla, te regresa false.
# Conexion no persistente
$dsn = 'mysql://root:pwd@localhost/mydb';
$db = NewADOConnection($dsn);
if (!$db) die("Conexion incorrecta");
# no se requiere llamar connect/pconnect!
$arr = $db->GetArray("select * from table");
# conexion persistente
$dsn2 = 'mysql://root:pwd@localhost/mydb?persist';
Si tienes caracteres especiales como /:?_ en tu dsn, entonces tienes que invocar a rawurlencode primero:
$pwd = rawurlencode($pwd);
$dsn = "mysql://root:$pwd@localhost/mydb"; $dsn2=rawurlencode("sybase_ase")."://user:pass@host/path?query";
Las opciones permitidas son:
| Para todas los drivers | 'persist', 'persistent', 'debug', 'fetchmode', 'new' |
| Interbase/Firebird | 'dialect','charset','buffers','role' |
| M'soft ADO | 'charpage' |
| MySQL | 'clientflags' |
| MySQLi | 'port', 'socket', 'clientflags' |
| Oci8 | 'nls_date_format','charset' |
Para todos los drivers, cuando se activa la opcion persist o persistent, se forza una conexionpersistente; asi mismo, cuando se activa new, entonces la conexion se creara usando NConnect si el driver lo maneja. La opcion debug habilita la depuracion. La opcion fetchmode invoca SetFetchMode(). Si no se le indica el valor a alguna oopcion se asume el valor de 1.
La version DSN de ADOdb DSN es compatible con el formato de la version 1.0 de PEAR DB.
Las conexiones a MySQL son muy sencillas, y los parametros son identicos a mysql_connect:
$conn = &ADONewConnection('mysql');
$conn->PConnect('localhost','usuario','contraseña','database');
# o dsn
$dsn = 'mysql://user:pwd@localhost/mydb';
$conn = ADONewConnection($dsn); # no necesita Connect()
# o dsn persistente
$dsn = 'mysql://user:pwd@localhost/mydb?persist';
$conn = ADONewConnection($dsn); # no necesita PConnect()
# un ejemplo mas complejo:
$pwd = urlencode($pwd);
$flags = MYSQL_CLIENT_COMPRESS;
$dsn = "mysql://user:$pwd@localhost/mydb?persist&clientflags=$flags";
$conn = ADONewConnection($dsn); # no need for PConnect()
La mayoria de las demas bases de datos usan la misma convencion: Connect($servidor, $usuario, $contraseña, $database). Las excepciones se enlistas a continuacion.
PDO, que solo funciona en PHP5, acepta una cadena de driver especifica:
$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");
El mecanismo via DSN tambien funciona:
$conn =& NewADConnection("pdo_mysql://user:pwd@localhost/mydb?persist"); # persist es opcional
PostgreSQL 7 y 8 acepta conexiones usando:
a. La cadena estandard de conexcion:
$conn = &ADONewConnection('postgres');
$conn->PConnect('host=localhost port=5432 dbname=maria');
b. Los 4 parametros clasicos:
$conn->PConnect('localhost','usuario','contraseña','database');
c. dsn:
$dsn = 'postgres://user:pwd@localhost/mydb?persist'; # persist es opcional
$conn = ADONewConnection($dsn); # no se requiere Connect/PConnect
Este es un ejemplo de busqueda en un servidor LDAP. Gracias a Josh Eldridge por el driver y este ejemplo:
<?php
require('adodb/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');
O con dsn:
$dsn = 'firebird://user:pwd@localhost/mydb?persist&dialect=3'; # persist es opcional $conn = ADONewConnection($dsn); # no se requiere Connect/PConnect
$conn = &ADONewConnection('sqlite');
$conn->PConnect('c:\path\to\sqlite.db'); # sqlite la creara si no existe
O con dsn:
$path = urlencode('c:\path\to\sqlite.db');
$dsn = "sqlite://$path/?persist"; # persist es opcional
$conn = ADONewConnection($dsn); # no se requiere Connect/PConnect
Con oci8 te puedes conectar de varias maneras.
a. PHP y Oracle estan en la misma maquina, usar SID.
$conn->Connect(false, 'scott', 'tiger');
b. Nombre TNS definido en tnsnames.ora (o ONAMES o HOSTNAMES), ej. 'miTNS'
$conn->PConnect(false, 'scott', 'tiger', 'miTNS');
o
$conn->PConnect('miTNS', 'scott', 'tiger');
c. Direccion del servidor y SID
$conn->connectSID = true;
$conn->Connect('192.168.0.1', 'scott', 'tiger', 'SID');
d. Direccion del servidor y nombre del servicio
$conn->Connect('192.168.0.1', 'scott', 'tiger', 'servicename');
e. Cadena de conexion de Oracle:
$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);
Tamnbien puedes usar el charSet para Oracle 9.2 y posterior, soportado desde PHP 4.3.2, ADOdb 4.54:
$conn->charSet = 'we8iso8859p1';
$conn->Connect(...);
# o
$dsn = 'oci8://user:pwd@tnsname/?charset=WE8MSWIN1252';
$db = ADONewConnection($dsn);
Las conexiones DSN via ODBC pueden ser creadas en el panel de control de ODBC, o puedes usar una conexion DSN-less. Para usar una conexion DSN-less se necesita PHP version 4.3 o posterior.
Para Microsoft Access:
$db =& ADONewConnection('access');
$dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\northwind.mdb;Uid=Admin;Pwd=;";
$db->Connect($dsn);
Para Microsoft SQL Server:
$db =& ADONewConnection('odbc_mssql');
$dsn = "Driver={SQL Server};Server=localhost;Database=northwind;";
$db->Connect($dsn,'userid','password');
o si lo prefieres, se puede usar la extension mssql (que esta limitada a la funcionalildad de la version 6.5):
$db =& ADONewConnection('mssql');
$db->Execute('localhost', 'userid', 'password', 'northwind');
Para DB2:
$dbms = 'db2'; # or 'odbc_db2' if db2 extension not available
$db =& ADONewConnection($dbms);
$dsn = "driver={IBM db2 odbc DRIVER};Database=sample;hostname=localhost;port=50000;protocol=TCPIP;".
"uid=root; pwd=secret";
$db->Connect($dsn);
Conexiones DSN-less con 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);
?>
La libreria ADOdb es una clase grande, aun asi regularmente derrota a las 'otras' clases PHP en rendimiento. Esto es por su diseño en forma de capas, como una cebolla, con las funciones mas rapidas en la capa mas profunda. Usa principalmente estas funciones para el mejor rendimiento:
Capa mas profunda |
Connect, PConnect, NConnect |
La manera mas rapida de acceder a los campos es usando el arreglo array $recordset->fields. Tambien hay que asignar la variable global $ADODB_FETCH_MODE = ADODB_FETCH_NUM, y (para oci8, ibase/firebird y odbc) $ADODB_COUNTRECS = false antes de conectarse a la base de datos. Esto al momento (Dec 2003).
Considera usar parametros posisicionales (bind) si tu base de datos los soporta, ya que mejora la reutilizacion de los planes de ejecucion. Usa el sistema de 'performance tuning de ADodb para identificar rapidamente los cuellos de botella.
Finalmente asegurate de que tienes un acelerador de PHP instalado como APC, Turck MMCache, Zend Accelerator o ionCube.
Algunos ejemplos:
| Recuperacion de datos mas rapida usando PHP | Recuperacion de datos mas rapida usando la extension ADOdb |
$rs =& $rs->Execute($sql); |
$rs =& $rs->Execute($sql); |
Sugerencias Avanzadas
Si tienes instalada la extension C ADOdb, puedes modificar tus llamados a $rs->MoveNext() por adodb_movenext($rs). Esto duplica la velocidad de esta operacion. Para obtener todo un conjunto de rsultados en una operacion, usa GetArray(), el cual usa internamente la funcion de alta velocidad de la extension adodb_getall($rs).
Execute() es la manera usal para ejecutar enunciados SQL. Puedes usar la funcion de bajo nivel _Execute() y _query() para reducir el costo. Ambas funciones comparten los mismos parametros que Execute().
Si no tienes ningun parametro posicional o si tu base de datos soporta los parametros posicionales (sin emulacion), entonces puedes llamar _Execute() directamente. AL invocar esta funcion eliminas la emulacion de parametros. La depuracion tambien es manejada por _Execute().
Si no requuieres depuracion ni emulacion de parametros, no requieres obtener un recordset, entonces puedes llamar _query. Es muy buena para inserts, updates y deletes. Al invocar esta funcion omites la emulacion de parametros, la depuracion y el majejo de recordsets. _query() regresa el resultid, true o false.
Recomendacion para INFORMIX: Desabilita los cursores navegables 'scroll' con $db->cursorType = 0.
Tu puedes modificar ADOdb para tus propios usos. Por suerte puedes mantener la compatibilidad extendiendo las clases de ADodb y por medio de la variable $ADODB_NEWCONNECTION. $ADODB_NEWCONNECTION nos permite modificar el comportamiento de ADONewConnection(). ADOConnection() verifica esta variable e invocara la funcion cuyo nombre tenga la variable.
En el siguiente ejemplo, se le agrega mas funcionabilidad al objeto de conexion por medio de las clases hack_mysql y hack_postgres7. La convencion en el nombre de las clases recordset se controla por medio de la propiedad $rsPrefix. En este caso se le asigna el valor de 'hack_rs_', lo que proboca que ADOdb use hack_rs_mysql y hack_rs_postgres7 como los nombres de las clases recordset. En caso de que se requiera usar los drivers normales de ADODB hay que regresar el valor 'false' en la funcion.
class hack_mysql extends adodb_mysql {
var $rsPrefix = 'hack_rs_';
/* aqui van las modificaciones */
}
class hack_rs_mysql extends ADORecordSet_mysql {
/* aqui van las modificaciones */
}
class hack_postgres7 extends adodb_postgres7 {
var $rsPrefix = 'hack_rs_';
/* aqui van las modificaciones */
}
class hack_rs_postgres7 extends ADORecordSet_postgres7 {
/* aqui van las modificaciones */
}
$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');
No olvides invocar el constructor de la clase padre.
$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);
}
Nota: Alcanzar el fin de archivo (EOF) NO es considerado ni un error ni una excepcion.
| Nombre | Verificada | Base de datos | sirve RecordCount() | Pre-requisitos | Sistemas operativos |
| access | B | Microsoft Access/Jet. Hay que crear el DSN en el ODBC. | S/N | ODBC | Windows unicamente |
| ado | B | ADO generico, no esta optimizado para ninguna base de datos especifica. Permite conexiones DSN-less. Para un mejor rendimiento, utilizar un proveedor de OLEDB. Esta la clase basa para todos los drivers ado. Hay que configurar $db->codePage antes de conextarse. |
? depende de la base de datos | ADO o proveedor OLEDB | Windows unicamente |
| ado_access | B | Microsoft Access/Jet usando ADO. Permite conexiones DSN-less. Para mejor rendimiento usar un proveedor OLEDB. | S/N | ADO o proveedor OLEDB | Windows unicamente |
| ado_mssql | B | Microsoft SQL Server usando ADO. Permite conexiones DSN-less. Para mejor rendimiento usar un proveedor OLEDB. | S/N | ADO o proveedor OLEDB | Windows unicamente |
| db2 | A | DB2. Debe de funcionar satisfactoriamente porque se base en el driver ODBC based on ODBC. | S/N | Interfase CLI/ODBC de DB2 | Unix y Windows. Trucos de instalacion en Unix. Hay reportes de que los parametros $host y $database del Connect() tienen que ir invertidos si se usa la interfase CLI. |
| odbc_db2 | C | Se conecta a DB2 usando la extesion ODBC generica. | S/N | Interfase CLI/ODBC de DB2 | Unix y Windows. sugerencias para instalacion en Unix. Tengo reportes que los parametros $host y $database tienen que ser invertidos en el Connect() cuando se usa la interfase CLI. |
| vfp | A | Microsoft Visual FoxPro. Hay que crear un DSN. | S/N | ODBC | Windows unicamente |
| fbsql | C | FrontBase. | S | ? | Unix y Windows |
| ibase | B | Interbase 6 o anterior. Algunos usuarios dicen que puedes necesitar esta sintaxis para conectarte $db->PConnect('localhost:c:/ibase/employee.gdb', "sysdba", "masterkey") . Actualmente le falta Affected_Rows. Antes de conectarte puedes modificarle $db->dialect, $db->buffers y $db->charSet. |
S/N | cliente Interbase | Unix y Windows |
| firebird | C | version Firebird de interbase. | S/N | cliente Interbase | Unix y Windows |
| borland_ibase | C | version Borland de Interbase 6.5 o posterior. Desafortunadamente las version son diferentess. | S/N | cliente Interbase | Unix y Windows |
| informix72 | C | Versiones Informix anteriores a 7.3 que no soportan SELECT FIRST. | S/N | Cliente Informix | Unix y Windows |
| informix | C | Driver generico para informix. | S/N | Cliente Informix | Unix y Windows |
| ldap | C | Driver LDAP driver. Ver el ejemplo para informacion de uso. | Extension LDAP | ? | |
| mssql | A | Microsoft SQL Server 7 y posterior. Tanbien funciona con Microsoft SQL Server 2000. Toma en cuenta que el formato de las fechas es problematico con este driver. Por ejemplo, la extension mssql de PHP no regresa los segundos de los campos datetime! |
S/N | cliente Mssql | Unix y Windows. |
| mssqlpo | A | Driver portable de mssql. Es identico al driver de mssqk anteriorm excepto que el operador de concatenacion '||' se convirtio a '+'. Esto es util para migrar codigo desde otras versiones de SQL. |
S/N | Cliente Mssql | Unix y Windows. |
| mysql | A | MySQL sin manejo de transacciones. Puedes usar $db->clientFlags antes de conectarte. | S/N | Cliente MySQL | Unix y Windows |
| mysqlt or maxsql | A | MySQL con soporte de transacciones. Recomendamos usar
|| como el operador de concatenacion para una mejor portabilidad.
Esto se logra ejectuando MySQL con: |
S/N | Cliente MySQL | Unix y Windows |
| oci8 | A | Oracle 8/9. Tiene mas funcionabilidad que el driver oracle
(ej. Affected_Rows). Puedes tener que hacer un putenv('ORACLE_HOME=...') antes del
Connect/PConnect. hay dos maneras de conectarse
- Con la direccion IP del servidor y el nombre del servicio: A partir de la version 2.31, se manejan las variables de cursores REF directamente (ver ExecuteCursor). |
S/N | Cliente Oracle | Unix y Windows |
| oci805 | C | Maneja un funcionaldiad reducida para la version 8.0.5 de Oracle. SelectLimit no es tan eficiente como en los drivers oci8 o oci8po. | S/N | Cliente Oracle | Unix y Windows |
| oci8po | A | Driver portable de Oracle 8/9. Esta es casi identica al driver oci8
execpto que (a) Las variables 'bind' en los Prepare() usan ? en lugar de :bindvar,
(b) los nombres de campos estan en minusculas (la manera mas usual en PHP).
Usa este driver si la portabilidad de tu codigo a otras bases de datos es importante. En caso contrario usa el driver oci8 ya que da mejor rendimiento. |
S/N | Cliente Oracle | Unix y Windows |
| odbc | A | Driver generico para ODBC, no esta optimizado para ninguna base de
datos especifica. Para conectarse usa PConnect('DSN','user','pwd'). Esta es la clase base para todos los drivers basados en ODBC . |
? depende de la base de datos | ODBC | Unix y Windows. Trucos para Unix. |
| odbc_mssql | C | Usa ODBC para conectarse a MSSQL | S/N | ODBC | Unix y Windows. |
| odbc_oracle | C | Usa ODBC para conectarse a Oracle | S/N | ODBC | Unix y Windows. |
| odbtp | C | Driver odbtp generico. Odbtp es un programa para poder usar los DSN en el ODBC de Windows desde OTROS sistemas operativos (ej. Linux). | S/N | odbtp | Unix y Windows |
| odbtp_unicode | C | Odtbp con soporte unicode | S/N | odbtp | Unix y Windows |
| oracle | C | Implementa el viejo API de Oracle 7. Si te es posible usa el driver oci8 para un mejor rendimiento. | S/N | Cliente Oracle | Unix y Windows |
| netezza | C | Driver para Netezza. Netezza esta basado en el codigo base de postgres. | Y | ? | ? |
| postgres | A | Driver generico PostgreSQL. Actualmente es identico al driver postgres7. | S | Cliente PostgreSQL | Unix y Windows. |
| postgres64 | A | Para PostgreSQL 6.4 y anteriores que no manejan LIMIT internamente. | S | Cliente PostgreSQL | Unix y Windows. |
| postgres7 | A | PostgreSQL que soporta LIMIT y caracteristicas de la version 7. | S | Cliente PostgreSQL | Unix y Windows. |
| postgres8 | A | PostgreSQL que maneja la funcionalidad de la version 8. | S | Cliente PostgreSQL | Unix y Windows. |
| sapdb | C | SAP DB. Debe de funcionar bien ya que esta basado en el driver ODBC. | S/N | Cliente ODBC de SAPdb | ? |
| sqlanywhere | C | Sybase SQL Anywhere. Debe de funcionar bien ya que esta basado en el driver ODBC. | S/N | Cliente ODBC de SQL Anywhere ODBC | ? |
| sqlite | B | SQLite. Unicamente verificada en PHP5. | S | - | Unix y Windows. |
| sqlitepo | B | Driver portable para SQLLite. Es debido a que el modo asociativo no funciona como en
los otros drivers. Al seleccionar multiples tablas (joining), se incluye el nombre de la tabla en la llave del
arreglo asociativo. En el driver "sqlitepo", el nombre de la tabla es eliminado del nombre de la columna. Cuando hay conflictos, el primer campo tiene preferencia. |
S | - | Unix y Windows. |
| sybase | C | Sybase. | S/N | Cliente Sybase | Unix y Windows. |
| sybase_ase | C | Sybase ASE. | S/N | Cliente Sybase | Unix y Windows. |
La columna "Verificada" indica que tan profusamente el codigo a sido verificado y usado.
A = bien verificado y usado con mucha gente
B = verificado y usable, pero algunas caracteristicas pueden no estar implementadas
C = driver proporcionado por los usuarios o experimental.
Puede no manejar todas las ultimas caracteristcicas de ADOdb.
La columna "sirve RecordCount()" indica si RecordCount() regresa la cantidad de renglones o regresa -1 cuando se ejectuta un enunciado SELECT. Si la columna muestra S/N entonces RecordCount() es simulado cuando la variable global $ADODB_COUNTRECS=true (esto es el valor por omision). Nota que para recordsets muy grandes, puede ser mejor desabilitar la emulacion de RecordCount()debido a la gran cantidad de memoria para leer el recordset para contarlo. Tambien hay una penalizacion del 40-50% si se tiene que emular la funcion. Es emulada en la mayoria de las bases de datos excepto para PostgreSQL y MySQL. Esta variable es verificada cada vez que se ejecuta un SELECT, por lo que puedes escoger selectivamente cuales recordset contar.
Tarea: Conectarse al DSN MS Access de la base de datos Nortwind, mostrar las primeras 2 columnas de cada renglon.
En este ejemplo, se crea un objeto ADOConnection que representa la conexion a la base de datos. La conexion se inicia con PConnect, que es una conexion persistente. Para interrogar a las base de datos llamamos a la funcion ADOConnection.Execute() . Esto regresa un objeto ADORecordSet que es de hecho un cursor que contiene el renglon actual en el arreglo fields[]. Tambien usamos el metodo MoveNext() para avanzar de renglon en renglon.
Nota: Una funcion muy util que NO usamos en este ejemplo es SelectLimit, que nos permite limitar la cantidad de renglones a mostrar.
<?
include('adodb.inc.php'); # Carga el codigo comun de ADOdb
$conn = &ADONewConnection('access'); # crea la conexion
$conn->PConnect('northwind'); # se conecta a la base detos northwind via el DSN MS-Access
$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(); # opcional
$conn->Close(); # opcional
?>
La variable $recordSet obtenida contiene el renglon actual en el arreglo $recordSet->fields , indexado por numero de columna (empezando en cero). Usamos el metodo MoveNext() para avanxar al renglon siguiente. La propiedad EOF tiene valor verdadero (true) cuando se llega al final del archivo. Si hay algun error en el Execute() se regresa falso (false) en lugar del recordset.
El arreglo $recordSet->fields[] es generado por la extension PHP de la base
de datos correspondiente. Algunas extensiones unicamente indexan por numero y no por nombre
del campo. Para provocar que se indexe por nombre (o sea con arreglos asociativos)
hay que usar la funcion SetFetchMode. Cada recordset almacena y usa el metodo que estuvo
vigente cuando se creo el recordset con un Execute() o 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); # muestra array([0]=>'v0',[1] =>'v1')
print_r($rs2->fields); # muestra array(['col1']=>'v0',['col2'] =>'v1')
Para obtener el numero de renglones en el enunciado SELECT, se puede usar la funcion $recordSet->RecordCount(). Observa que la funcion puede regresar -1 si no se puede determinar la cantidad de renglones.
Seleccionar los registros de una tabla, desplegar las primeras dos columnas. Si la segunda columna es un campo DATE o TIMESTAMP entonces reformatear la fecha al formato americano.
<?php
include('adodb/adodb.inc.php'); # Carga el codigo comun de ADOdb
$conn = &ADONewConnection('access'); # crea la conexion
$conn->PConnect('northwind'); # se conecta al DSN de northwind
$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(); # opcional
$conn->Close(); # opcional
?>
En este ejemplo se verifica el tipo de campo de la segunda columna usando la funcion FetchField(). Esto obtiene un objeto con al menos tres propiedades.
Posteriormente usamos MetaType() para traducir el tipo nativo a un tipo generico. Actualmente estan definidos los siguientes tipos genericos:
Si el metatype es de tipo date o timestamp, entonces se imprime usando la funcion definida por el usuario UserDate(), la cual convierte la cadena de texto en formato PHP SQL al formato definido por el usuario. otro uso para la funcion MetaType() es para validar los datos antes de ejecutar un enunciado SQL de INSERT o UPDATE.
Insertar un renglon en la tabla Orders conteniendo fechas y cadenas de caracteres que necesitan ser encomillados antes de que sean aceptados por la base de datos, por ejemplo el apostrofo en la palabra John's.
<?php
include('adodb/adodb.inc.php'); # carga el codigo comun de ADOdb
$conn = &ADONewConnection('access'); # crea la connection
$conn->PConnect('northwind'); # Se conecta al DSN northwind
$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 al insertar: '.$conn->ErrorMsg().'<BR>';
}
?>
En este ejemplo observamos el manejo avanzado de encomillado y de fechas que tiene ADOdb. El valor unix del tiempo (que es un entero largo) se formatea correctamente para Access con DBDate(), y se usa el caracter adecuado para encomillar John's Old Shoppe, lo correcto es John''s Old Shoppe y no lo que hace PHP normalmente John's Old Shoppe con qstr().
Observa el manejo de errores en el enunciado Execute. Se obtiene Falso si hubo un error al ejectutar Execute(). El mensaje de error del ultimo error encontrado se muestra con ErrorMsg(). Ojo: Se necesita que php_track_errors este habiliatado para que se salven los mensajes de error.
<?php
include('adodb/adodb.inc.php'); # carga el codigo comun de ADOdb
$conn = &ADONewConnection('access'); # crea la conexion
$conn->PConnect('northwind'); # se conecta al DSN de northwind
$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';
?>
En el ejemplo anterior se activo la depuracion asignando debug = true. Esto desplegara los enunciados SQL antes de ejectuarse, y ademas mostrara cualquier mensaje de error. En este caso no hay necesidad de llamar la funcion ErrorMsg(). Para mostrar el contenido del recordset, ve el ejemplo de rs2html().
Tambien ve la seccion de Manejadores de error a la medida.
Conectarse a la base de datos MySQL agora, y generar un menu <select> a partir de un enunciado SQL donde cada leyenda del <option> se saca de la primera columna y el valor a enviar al servidor se obtiene de la segunda columna.
<?php
include('adodb/adodb.inc.php'); # Carga el codigo comun de ADOdb
$conn = &ADONewConnection('mysql'); # crea la conexion
$conn->PConnect('localhost','userid','','agora');# se conecta a la base de datos agora
$sql = 'select CustomerName, CustomerID from customers';
$rs = $conn->Execute($sql);
print $rs->GetMenu('GetCust','Mary Rosli');
?>
Aqui definimos un menu llamado GetCust, con la opcion del menu 'Mary Rosli' pre seleccionada. Ve el metodo GetMenu(). Tambien hay funciones que regresan el recordset como un arreglo: GetArray(), y como un arreglo asociativo con la primera columna como llave: GetAssoc().
<?php
include('adodb/adodb.inc.php'); # Carga el codigo comun de ADOdb
$conn1 = &ADONewConnection('mysql'); # Crea la conexion a mysql
$conn2 = &ADONewConnection('oracle'); # Crea la conexion a oracle
$conn1->PConnect($server, $userid, $password, $database);
$conn2->PConnect(false, $ora_userid, $ora_pwd, $oraname);
$conn1->Execute('insert ...');
$conn2->Execute('update ...');
?>
Desde la version 4.56 de ADOdb,manejamos AutoExecute(), el cual simplifica las cosas proporcionando una funcion de nivel superior que encapsula los llamados a GetInsertSQL() y GetUpdateSQL(). Por ejemplo, un INSERT puede hacerse asi:
$record["firstname"] = "Bob";
$record["lastname"] = "Smith";
$record["created"] = time();
$insertSQL = $conn->AutoExecute($rs, $record, 'INSERT');
y un UPDATE asi:
$record["firstname"] = "Caroline";
$record["lastname"] = "Smith"; # Actualiza iel apellido de Caroline de Miranda a Smith
$insertSQL = $conn->AutoExecute($rs, $record, 'UPDATE', 'id = 1');
El resto de esta section esta desactualizada:
A partir de la version 1.31 de ADOdb 1.31 hay dos metodos nuevos para recordset: GetUpdateSQL( ) y GetInsertSQL( ). Esto nos permite ejecutar un "SELECT * FROM table query WHERE...", copiar los valores de $rs->fields, modificar los campos y generar el SQL correcto para hacer un update o insert en la tabla.
Mostraremos como pueden ser empleadas las funciones en una tabla con los siguiente campos: (ID, FirstName, LastName, Created).
Antes de que estos metodos puedan ser invocados, necesitas inicializar el recordset ejecutando un select en la tabla. En base a una idea de Jonathan Younger jyounger#unilab.com. a partir de la version de 2.42 de ADOdb, puedes mandar como parametro el nombre de la tabla en lugar del recordset y se generara un enunciado insert para la tabla.
<?php
#=====================================================
# codigo de Ejemplo de GetUpdateSQL()y GetInsertSQL()
#=====================================================
include('adodb/adodb.inc.php');
include('adodb/tohtml.inc.php');
#==========================
# Codigo para probar un insert
$sql = "SELECT * FROM ADOXYZ WHERE id = -1";
# Selecciona un registro en blanco de la base de datos
$conn = &ADONewConnection("mysql"); # crea la conexion
$conn->debug=1;
$conn->PConnect("localhost", "admin", "", "test"); # se conecta a la base de datos testdb
$rs = $conn->Execute($sql); # Ejecuta la busqueda y obtiene el recordset vacio
$record = array(); # Inicializa el arreglo que contiene los datos a insertar
# Asignar el valor de los campos en el registro
# Observa que el nombre de los campos pueden ser mayusculas o minusculas
$record["firstname"] = "Bob";
$record["lastNamE"] = "Smith";
$record["creaTed"] = time();
# Mandar como parametro el recordset vacio y el arreglo conteniendo los datos a insertar
# a la funcion GetInsertSQL. Esta procesara los datos y regresara un enunciado SQL
# para procesar el INSERT.
$insertSQL = $conn->GetInsertSQL($rs, $record);
$conn->Execute($insertSQL); # Inserta el registro en la base de datos
#==========================
# Codigo de prueba para UPDATE
$sql = "SELECT * FROM ADOXYZ WHERE id = 1";
# Selecciona el registro a actualizar
$rs = $conn->Execute($sql); # Executa la busqueda y obtiene el registro a actualizar.
$record = array(); # Inicializa el arreglo que contiene los datos a modificar
# Asignar el valor de los campos en el registro
# Observa que el nombre de los campos pueden ser mayusculas o minusculas
$record["firstname"] = "Caroline";
$record["LasTnAme"] = "Smith"; # Corrige el apellido de Carolina de Miranda a Smith
# Mandar como parametro el recordset y el arreglo conteniendo los datos a actualizar
# a la funcion GetUpdateSQL. Esta procesara los datos y regresara el enunciado sql del
# update necesario con clausula WHERE correcta.
# Si no se modificaron los datos no regresa nada.
$updateSQL = $conn->GetUpdateSQL($rs, $record);
$conn->Execute($updateSQL); # Actualiza el registro en la base de datos
$conn->Close();
?>
$ADODB_FORCE_TYPEEl comportamiento de AutoExecute(), GetUpdateSQL() y GetInsertSQL() al convertir variables PHP vacias o nulas a varibales SQL is controlado por la nueva variable global $ADODB_FORCE_TYPE. Asignale alguno de los valores enlistados abajo. El valor por omision es ADODB_FORCE_VALUE (3):
0 = ignorar campos vacios. Todos los campos vacios en el arreglo son ignorados.
1 = forzar null. Todos los campos vacios, con valor null (de php) o con la cadena 'null' se cambian al
valor SQL de NULL.
2 = forzar vacio. Todos los campos vacios, con valor null (de php) o con la cadena 'null' se cambian a la
cadena vacia de SQL '' o a 0.
3 = forzar valor value. El valor se deja como esta. Lo null (de php) y las cadenas 'null' se cambien a NULL
de SQL y los camnpos vacios con '' se convierten a vacio de SQL ''.
define('ADODB_FORCE_IGNORE',0);
define('ADODB_FORCE_NULL',1);
define('ADODB_FORCE_EMPTY',2);
define('ADODB_FORCE_VALUE',3);
Gracias a Niko (nuko#mbnet.fi) por el codigo de $ADODB_FORCE_TYPE.
Nota: la constante ADODB_FORCE_NULLS es obsoleta desde la version 4.52 y es ignorada. Asigna $ADODB_FORCE_TYPE = ADODB_FORCE_NULL para un comportamiento similar.
Desde la version 4.62, el nombre de la tabla a ser usada puede ser modificado al poner $rs->tableName antes de invocar AutoExecute(), GetInsertSQL() o GetUpdateSQL().
El siguiente codigo crea un navegador por paginas muy sencillo, donde puedes navegar de pagina en pagina de un recordset.
<?php
include_once('adodb/adodb.inc.php');
include_once('adodb/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);
?>
Esto crea un paginador de registros que es asi:
|< <<
>> >|
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Page 8/10 |
El numero de renglones a mostrar en cada pagina se controla con el metodo Render($rows). Si no le mandas ningun parametro a Render(), ADODB_Pager toma como valor por omision 10 renglones por pagina.
Puedes controlar el titulo de cada columna modificando el SQL (funciona en la mayoria de las bases de datos):
$sql = 'select id as "Clave", firstname as "Nombre", lastname as "Apellido", created as "Fecha Creacion"
from adoxyz';
El codigo anterior lo puedes encontrar en los ejemplos incluidos con la distribucion en el archivo adodb/tests/testpaging.php, y la clase ADODB_Pager esta en adodb/adodb-pager.inc.php. El codigo de ADODB_Pager puede ser modificado por el programador para que las ligas sean imagenes en lugar de textos, y el aburrido fondo blanco tenga colores mas interesantes.
Tambien puedes habilitar que se muestre HTML modificando $pager->htmlSpecialChars = false.
Parte del codigo usado aqui fue proporcionado por Iván Oliva and Cornel G.
Se proporcionan funciones de ayuda para exportar en formatos delimitado por coma (CSV) y delimitado por tabuladores:
<?php
include_once('adodb/toexport.inc.php');
include_once('adodb/adodb.inc.php');
$db = &NewADOConnection('mysql');
$db->Connect($server, $userid, $password, $database);
$rs = $db->Execute('select fname as "Nombre", surname as "Apellido" from table');
print "<pre>";
print rs2csv($rs); # obtenemos un texto en formao CSV
print '<hr>';
$rs->MoveFirst(); # Nota, en algunas bases de datos no funciona el MoveFirst
print rs2tab($rs,false); # obtenemos el texto delimitado por tabuladores
# false == omite el nombre de los campos en el primer renglon
print '<hr>';
$rs->MoveFirst();
rs2tabout($rs); # manda a la salida estandar (stdout) (tambien existe la funcion rs2csvout)
print "</pre>";
$rs->MoveFirst();
$fp = fopen($path, "w");
if ($fp) {
rs2csvfile($rs, $fp); # Escribe a un archivo (tambien existe la funcion rs2tabfile)
fclose($fp);
}
?>
Los regresos de carro y saltos de linea (CR/LF) se convierten a espacios. Los nombres de los campos se muestran en el primer renglon del texto. Las cadenas de caracteres que contengan el caracter de delimitador se encierran entre comillas dobles. Las comillas dobles se encierran tambien entre comillas. Esto cumple las guias de importacion y exportacion de MS Excel.
Todas las funciones anteriores tienen un ultimo parametro opcional, $addtitles que tiene
como valor por omision true. Cuando se le manda false se omite el nombre de los
campos en la primera linea.
Algunas veces se desea pre procesar todos los renglones de un recordset antes de usarlos. Por ejemplo, deseamos convertir a mayusculas todo el texto de un recordset.
<?php
include_once('adodb/rsfilter.inc.php');
include_once('adodb/adodb.inc.php');
// Procesar con ucwords() cada elemento en un 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');
La funcion RSFilter requiere dos parametros, el recordset y el nombre de la funcion del filtro. Regresa el recordset apuntando nuevamente al primer registro. La funcion filter requiere otros dos parametros, el renglon como un arreglo, y el objeto recordset. Para compatibilidad con futuras versiones se recomienda no usar el objeto recordset original.
$conn->BeginTrans(); $ok = $conn->Execute($sql); if ($ok) $ok = $conn->Execute($sql2); if (!$ok) $conn->RollbackTrans(); else $conn->CommitTrans();Esto es muy compliado para proyectos largos debido a que debes de ir siguiendole la huella a los errores. Con transacciones inteligentes es mas sencillo. Se empieza una transaccion invocando StartTrans():
$conn->StartTrans(); $conn->Execute($sql); $conn->Execute($Sql2); $conn->CompleteTrans();El metodo CompleteTrans() detecta cuando ocurrio un error SQL, y procesara Rollback o Commit segun sea necesario. Para forzar especificamente un evento rollback si no ha ocurrido un error, usa el metodo FailTrans(). Toma en cuenta que el rollback se efectua HASTA el CompleteTrans(), y no con el FailTrans(). /-- El metodo CompleteTrans() detecta cuando ocurrio un error SQL, y procesara Rollback o Commit segun sea necesario. Para explicitamente provocar el rollback aun cuando no ha ocurrido un error , usa el metodo FailTrans(). Toma en cuenta que el rollback se efectua HASTA el CompleteTrans(), y no con el FaulTrans(). //-->
$conn->StartTrans(); $conn->Execute($sql); if (!CheckRecords()) $conn->FailTrans(); $conn->Execute($Sql2); $conn->CompleteTrans();
Tambien se puede verificar si una transaccion a fallado usando HasFailedTrans(), el cual nos devuelve verdadero si se ha invocado FailTrans() o si hubo un error en la ejecucion de los SQL. Asegurese de usar HasFailedTrans() antes de llamar a CompleteTrans(), ya que esta unicamente funciona dentro de StartTrans y CompleteTrans.
Finalmente, StartTrans/CompleteTrans son anidables, y unicamente el bloque exterior se ejecuta. En contraste BeginTrans/CommitTrans/RollbackTrans NO son anidables.
$conn->StartTrans(); $conn->Execute($sql); $conn->StartTrans(); # ignorado if (!CheckRecords()) $conn->FailTrans(); $conn->CompleteTrans(); # ignorado $conn->Execute($Sql2); $conn->CompleteTrans();
Nota: Actualmente no se manajean 'Savepoints'.
ADOdb maeja las exception de PHP5. Solamente incluye adodb-exceptions.inc.php y ya puedes atrapar las excepciones conforme ocurran los errores.
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 proporciona dos estilos de manejo de errores que se pueden ajustar a nuestras necesidades. El primero esta en el archivo adodb-errorhandler.inc.php. Este utiliza las funciones estandard de PHP error_reporting para controlar los tipos de mensajes de error a mostrar, y trigger_error que invoca al manejador de errores usual de PHP.
Si se incluye el archivo anterior se provoca que se invoque a la funcion trigger_error($errorstring,E_USER_ERROR) cuando:
(a) Falla Connect() o PConnect(), o
(b) Una funcion que ejecuta un enunciado SQL como Execute() or SelectLimit() tiene un error.
(c) Parezca que GenID() esta en un ciclo sin fin.
La variable $errorstring generada por ADOdb contra informacion util de depuracion similar a los datos del error.log siguiente. El archivo adodb-errorhandler.inc.php debe de ser incluido antes de crear cualquier objeto ADOConnection.
Si se define error_reporting(0), ningun error llegara al manejador de errores. Si se define error_reporting(E_ALL), todos los errores llegaran al manejador de errores. Ademas es ncesario usar ini_set("display_errors", "0" or "1") para controlar el despliegue de errores.
<?php
error_reporting(E_ALL); # pasa cualquier mensaje de error al manajeador de errores
include('adodb/adodb-errorhandler.inc.php');
include('adodb/adodb.inc.php');
include('adodb/tohtml.inc.php');
$c = NewADOConnection('mysql');
$c->PConnect('localhost','root','','northwind');
$rs=$c->Execute('select * from productsz'); # Table invalida productsz');
if ($rs) rs2html($rs);
?>
Si desea llevar una bitacora de los mensajes de error, puede definir las siguientes constantes opcionales ADODB_ERROR_LOG_TYPE y ADODB_ERROR_LOG_DEST. ADODB_ERROR_LOG_TYPE es el tipo de mensaje (ver error_log en el manual de PHP). En este ejemplo lo asignamos a 3 que significa registar en el archivo definido por la constante ADODB_ERROR_LOG_DEST.
<?php
error_reporting(E_ALL); # reporta todos los errores
ini_set("display_errors", "0"); # pero no los muestra en la pantalla
define('ADODB_ERROR_LOG_TYPE',3);
define('ADODB_ERROR_LOG_DEST','C:/errors.log');
include('adodb/adodb-errorhandler.inc.php');
include('adodb/adodb.inc.php');
include('adodb/tohtml.inc.php');
$c = NewADOConnection('mysql');
$c->PConnect('localhost','root','','northwind');
$rs=$c->Execute('select * from productsz'); ## Tabla invalida productsz
if ($rs) rs2html($rs);
?>
El siguiente mensaje se registrara en el archivo error.log:
(2001-10-28 14:20:38) mysql error: [1146: Table 'northwind.productsz' doesn't exist] in
EXECUTE("select * from productsz")
<?php
include('adodb/adodb-errorpear.inc.php');
include('adodb/adodb.inc.php');
include('adodb/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>';
}
?>
Puedes usar una clase derivada de la clase PEAR_Error definiendo la constante ADODB_PEAR_ERROR_CLASS antes de incluir adodb-errorpear.inc.php. Para facilitar la depuracion, se puede fijar el manejador por omision al principio el codigo PHP a PEAR_ERROR_DIE, lo cual provocara que se muestre el mensaje de error y que se detenga la ejecucion del codigo:
include('PEAR.php');
PEAR::setErrorHandling('PEAR_ERROR_DIE');
Toma en cuenta que ADOdb no regresa un objeto PEAR_Error cuando ocurre un error. Se regresa falso. Hay que llamar a ADODB_Pear_Error() para obtener el ultimo error o usa la tecnica de PEAR_ERROR_DIE.
SI tu necesitas mensajes que error que funcionen en varios manejadores de bases de datos, entonces usa MetaError(), que regresa un numero de error virtual basado en el sistema de numeracion de errores de PEAR DB, y MetaErrMsg().
Los mensajes de error son mostrados usando el metodo estatico ADOConnnection::outp($msg,$newline=true). Normalmente se manda el mensaje al cliente (IE, Netscape, Mozilla, etc.). Se puede modificar esto para efectuar un registro de errores.
ADOdb ahora tambien soporta conectarse usando DSN con el estilo de PEAR. Un nombre DSN es una cadena de texto con el siguiente formato:
$dsn = "$driver://$usuario:$contraseña@$servidor/$basededatos";
Un ejemploe:
$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>";
}
Mas informacion y ejemplos de conexion usando el formato DSN.
DB_Common
query - si regresa PEAR_Error si hay error
limitQuery - si regresa PEAR_Error si hay error
prepare - no regresa PEAR_Error si hay error
execute - no regresa PEAR_Error si hay error
setFetchMode - maneja ASSOC y ORDERED
errorNative
quote
nextID
disconnect
getOne
getAssoc
getRow
getCol
DB_Result
numRows - regresa -1 si no esta soportado
numCols
fetchInto - no maneja indicar el fetchmode
fetchRows - no maneja indicar el fetchmode
free
ADOdb maneja el caching de recordsets usando las funciones CacheExecute( ), CachePageExecute( ) y CacheSelectLimit( ). Son similares a las funciones sin cache excepto que tienen un nuevo primer parametro, $secs2cache.
Un ejemplo:
<?php
include('adodb/adodb.inc.php'); # carga el codigo comun de ADOdb
$ADODB_CACHE_DIR = '/usr/ADODB_cache';
$conn = &ADONewConnection('mysql'); # crea la conexion
$conn->PConnect('localhost','userid','','agora');# se conecta a agora
$sql = 'select CustomerName, CustomerID from customers';
$rs = $conn->CacheExecute(15,$sql);
El primer parametros es el numero de segundos a almacenar la busqueda. Las siguientes llamadas a esa misma busqueda usaran la version almacenda en memoria en el directorio $ADODB_CACHE_DIR. Para provocar que un busqueda se ejecute y se limpie del cache, hay que inviocar CacheExecute() con el primer parametro en cero. Tambien sirve invocar la funcion CacheFlush($sql).
Por seguridad se recomienda que tengas register_globals=off en el archivo php.ini si usas $ADODB_CACHE_DIR.
A partir de la vsersion 1.80 de ADOdb, el parametro secs2cache es opcional en las funciones CacheSelectLimit() y CacheExecute(). Si se omiten, usaran el valor que tenga el parametro $connection->cacheSecs, por omision son 60 minutos.
$conn->Connect(...);
$conn->cacheSecs = 3600*24; # 24 horas de cache
$rs = $conn->CacheExecute('select * from table');
Observe que magic_quotes_runtime debe de estar desactivado. Mas informacion, y no cambie $ADODB_FETCH_MODE (o SetFetchMode) ya que el recordset en memoria usara el valor de $ADODB_FETCH_MODE que tenia cuando el SQL fue ejecutada.
Desde la version 2.30, ADOdb maneja la generacion de SQL para crear tablas pivote, tambien conocidas como tablas cruzadas. Para una mayor explicacion lea este tutorial de DevShed Cross-Tabulation tutorial. Suponemos que la base de datos maneja la expresion SQL case-when.
En este ejemplo se usara la base de datos Northwind de MS Access. En la base de datos hay un tabla de productos, y deseamos analizar esta tabla proveedores versus categoria de productos. Se mostraran los proveedores uno en cada renglon, y tabulado contra categoria. De esta manera en base a la tabla de la izquierda se generara la tabla pivote de la derecha:
|
--> |
|
El seiguiente codigo generara el SQL para la tabla pivote:
# Consultar la tabla principal de "productos" # Poner los renglones al campo CompanyName # y las columnas al valor de Categories # definir las ligas para unir las tablas de busqueda # "categories" y "suppliers" # include "adodb/pivottable.php"; $sql = PivotTableSQL( $conn, # conexion adodb 'products p ,categories c ,suppliers s', # tablas 'CompanyName', # rows (multiple fields allowed) 'CategoryName', # column to pivot on 'p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID' # joins/where );
Esto generara el siguiente 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
Tambien se puede tomar como eje una columna (campo) numerico y generar totales usando rangos. Este codigo se reviso en la version 2.41 de ADOdb y no es compatible con versiones anteriores. El segundo ejemplo es:
$sql = PivotTableSQL( $conn, # conexion adodb 'products p ,categories c ,suppliers s', # tablas 'CompanyName', # renglones (se permiten, muiples campos) array( # rango de columnas ' 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 );
Lo anterior generar este enunciado SQL:
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
Los parametros de funcion encerrados entre [ ] son opcionales.
Si el API de la base de datos no cuenta el numero de registros encontrados por el enunciado SELECT, la funcion RecordCount() es simulada cuando la variable global $ADODB_COUNTRECS tiene el valor true, que es el valor por omision. Esto se simula almacenando los registros, lo cual puede consumir mucha memoria para recordset muy grandes. Asignele el valor falso a esta variable para un mejor rendimiento. El valor de esta variable se verifica cada vez que se ejecuta una consulta, por lo cual se puede escoger cuales recordsets se desean contar.
Si se utiliza la memoria intermedia (cache), esta variable contiene el directorio donde se almacenan los recordsets. Hay que definirla antes de invocar cualquier funcion de cache como CacheExecute( ). Por razones de seguridad se recomienda tener register_globals=off en el archivo php.ini si se usa el cache.
Con Unix y Apache, hay que modificar los permisos del directorio de cache a algo similar a lo siguiente:
chown -R apache /ruta/al/cache
chgrp -R apache /ruta/al/cache
Nos indica cuando hay que eliminar los espacios a la derecha de los campos CHAR (y tambien VARCHAR en el caso de ibase/firebird). Hay que asignarle true para que los elimine, el valor por omision es false. Por el momento funciona para los drivers de oci8po, ibase y firebird. Se agrego en la version 4.01 de ADOdb.
Determina el lenguaje que usa la funcion MetaErrorMsg(). El valor por omision es 'en', que significa mensajes en ingles. Para ver que lenguajes estan disponibles, vea los archivos en adodb/lang/adodb-$leng.inc.php, donde $leng son los lenguajes disponibles.
Determina como se obtienen los arreglos generados por los recordsets. Los recordsets salvan este valor cuando se crean (ej. al Execute( ) o SelectLimit( )), y cualquier cambio siguiente al valor de $ADODB_FETCH_MODE no tiene efecto en los recordsets existentes, unicamente en los recordsets creados posteriormente.
Se difinen la siguientes constantes:
define('ADODB_FETCH_DEFAULT',0);
define('ADODB_FETCH_NUM',1);
define('ADODB_FETCH_ASSOC',2);
define('ADODB_FETCH_BOTH',3);
Un ejemplo:
$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); # muestra array([0]=>'v0',[1] =>'v1')
print_r($rs2->fields); # muestra array(['col1']=>'v0',['col2'] =>'v1')
Como se observa en el ejemplo anterior, cada recordset almacena y usa un metodo diferente en base al valor que tenia $ADODB_FETCH_MODE cuando se creo el recordset al llamar el Execute().
Si no se le asigna valor, el valor por omision es ADODB_FETCH_DEFAULT. El comportamiento en este modo es diferente en cada driver, por lo cual no confie en ADODB_FETCH_DEFAULT. Para portabilidad, se recomienda usar ADODB_FETCH_NUM o ADODB_FETCH_ASSOC. Algunos drivers no manejan ADODB_FETCH_BOTH.
Funcion SetFetchMode
Algunos programadores prefieren usar una solucion mas orientada a objetos, donde el metodo de recuperacion se selecciona por medio de una funcion del objeto (metodo), SetFetchMode. Una vez que esta funcion se usa para un objeto de conexion, este objeto ignorara la variable global $ADODB_FETCH_MODE y solo usara la propiedad interna fetchMode.
$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); # muestra array([0]=>'v0',[1] =>'v1')
print_r($rs2->fields); # muestra array(['col1']=>'v0',['col2'] =>'v1')
Para obtener el valor anterior del metodo de recuperacion, se puede usar la propiedad $db->fetchMode, o el valor regresado por SetFetchMode( ).
Para algunos drivers se puede controlar si los nombres de los campos de los indices de los arreglos asociativos esten en mayusculas o minusculas. Para los drivers de sybase, oci8po, mssql, odbc e ibase y todos los otros drivers derivados de ellos, ADODB_ASSOC_CASE generara por omision recordset donde los nombres de los campos esten en minusculas. Hay tres posibles valores de la constante ADODB_ASSOC_CASE:
0 = Nombres de campo en minusculas. $rs->fields['orderid']
1 = Nombres de campo en mayusculas. $rs->fields['ORDERID']
2 = Nombres de campo sin cambio. $rs->fields['OrderID'] -- Valor por
omision desde ADOdb 2.90.
Para usarla hay que declarala antes de incluir adodb.inc.php.
define('ADODB_ASSOC_CASE', 2); # No cambiar las letras para ADODB_FETCH_ASSOC
include('adodb/adodb.inc.php');
Ve el tutorial de GetUpdateSQL.
Objeto que realiza la conexion a la base de datos, ejecuta enunciados SQL y tiene un conjunto de funciones de utileria para estandirzar el formato de enunciados SQL para cosas coma la concatenacion y el formateo de fechas.
databaseType: Nombre del sistema de base de datos al cual nos conectamos. Ej. odbc o mssql o mysql.
dataProvider: El mecanismo subyacente usado para conectarse a la base de datos. Normalmente vale native, a menos que se use odbc o ado.
host: Nombre del servidor o DSN a conectarse.
database: Nombre de la base de datos a conectarse. Si se usa ado contiene el proveedor de datos (ado data provider).
user: Nombre del usuario para conectarse a la base datos de datos. Por seguridad la contraseña no se almacena.
raiseErrorFn: Permite definir una funcion para el manejo de errores. Para un ejemplo ve el archivo adodb-errorhandler.inc.php.
debug: Con el valor true provoca que se muestren los mensajes de depuracion.
concat_operator: Normalmente con valor '+' o '||'. Es el operador usado para concatenar cadenas en SQL. Lo usa la funcion Concat.
fmtDate: El formato usado por la funcion DBDate para enviar fechas a las base de datos. Ej. '#Y-m-d#' para Microsoft Access, y ''Y-m-d'' para MySQL.
fmtTimeStamp: El formato usado por la funcion DBTimeStamp para enviar campos timestamp/datetime a la base de datos.
true: El valor usado para representar 'verdadero' .Ej. '.T.' para Foxpro, '1' para Microsoft SQL.
false: El valor usado para representar 'falso'. Ej. '.F.' para Foxpro, '0' para Microsoft SQL.
replaceQuote: La cadena usada para protejer las comillas. Ej. dos comillas sencillas ('') para Microsoft SQL, y diagonal invertida-comilla (\") para MySQL. Usado por la funcion qstr.
autoCommit: Indica si esta habilitado el 'commit' automatico. Por omision el valor es true.
charSet: Indica el conjunto de caracteres por omision. Actualmente solo lo maneja interbase.
dialect: Indica el dialecto por omision a usar. Actualmente solo lo maneja interbase.
role: Asigna el rol. Actualmente solo interbase/firebird lo manejan.
metaTablesSQL: Enunciado SQL para obtener la lista de las tablas disponibles. Ej. SHOW TABLES para MySQL.
genID: El ultimo identificador generado por la funcion GenID(), si lo maneja la base de datos.
cacheSecs: El numero de segundos para guardar en cache los recordsets si se omite el parametro #secs2cache en la funciones CacheExecute() o CacheSelectLimit(). El valor por omision es 60 minutos.
sysDate: Cadena que contiene el nombre de la funcion de la base de datos que genera la fecha fecha actual. Util en los INSERT y UPDATE.
sysTimeStamp: Cadena que contiene el nombre de la funcion de la base de datos que genera el valor actual en formato current timestamp/datetime.
leftOuter: Cadena que contiene el operador para hacer 'left outer join'. Si no se conoce con valor false.
rightOuter: Cadena que contiene el operador para hacer 'right outer join'. Si no se conoce con valor false.
ansiOuter: Valor boleano que es verdadero si se permite hacer 'outer joins' con la sintaxis ANSI. Ej. select * from table1 left join table2 on p1=p2.
connectSID: Valor boleano que indica si se debe considerar el parametro $database en la conexion como SID para el driver oci8. Lo normal es falso. Utill para las version 8.0.5 o anteriores de Oracle.
autoRollback: Si tiene valor true las conexiones persistentes hacen un rollback automatico al momento del PConnect( ). El valor por omision es false.
ADOConnection( )
Funcion constructor. No se invoque directamente. En su lugar usar ADONewConnection( ).
Connect($host,[$user],[$password],[$database])
Conexion no persistente al DSN o servidor $host, usando el usuario $user y la contraseña $password. Si el servidor maneja varias bases de datos, se conecta a la base de datos $database.
Regresa true/false dependiendo de la conexion.
Nota para ADO: Si usas Microsoft ADO y no OLEDB, el parametro $database puede tener el 'OLEDB data provider' utilizado.
PostgreSQL: Otra manera de conectarse a la base de datos es mandando en el primer parametro $host la cadena de conexion estandard de PostgreSQL, y de esa forma se ignoran los demas parametros.
Para Oracle y Oci8, hay dos maneras de conectarse. La primera usando el nombre TNS deinido en el archivo local tnsnames.ora (o ONAMES o HOSTNAMES). Colocar el nombre en el parametro $database, y poner el parametro $host a false. Como alternativa poner el servidor en $host, y el SID en $database , esto se brinca el archivo tnsnames.ora.
Ejemplos:
# $oraname en tnsnames.ora/ONAMES/HOSTNAMES
$conn->Connect(false, 'scott', 'tiger', $oraname);
$conn->Connect('server:1521', 'scott', 'tiger', 'ServiceName'); # bypass tnsnames.ora
Hay varios ejemplos de conexiones a bases de datos en la parte de ejemplos.
PConnect($host,[$user],[$password],[$database])
Para conexiones persistententes al DSN o servidor $host, usando el usuario $user y contraseña $password. Si el servidor maneja multiples bases de datos, se conecta a la base de datos $database.
Ahora se realiza un rollback en las conexiones persistentes para algunas bases de datos desde la version 2.21, como se recomienda en el manual de PHP. Ver la bitacora de cambios o el codigo fuente para ver cuales bases de datos se afectaron.
Regresa true/false dependiendo de la conexion. Para mas informacion vea Connect( ).
Desde ADOdb 2.21, se incluye el rollback automatico, ejemplo de uso:
$conn = &NewADOConnection('mysql');
$conn->autoRollback = true; # el valor por omision es false
$conn->PConnect(...); # aqui hace el rollback
Con esto al hacer una conexion persistente con PConnect( ), ADOdb realizara primero un rollback. Esto porque el documento que PHP no garantiza que se haga un rollback de las transacciones que fallen cuando se usan transacciones persistentes. Actualmente funciona para Oracle, MySQL, PgSQL, MSSQL, ODBC.
Desde ADOdb 3.11 se puede forzar el uso de conexiones no persistentes aunque se invoque PConnect definiendo la constante ADODB_NEVER_PERSIST antes de invocar PConnect.
Desde ADOdb 4.23, se regresa null si la extension no esta cargada.
NConnect($host,[$user],[$password],[$database])
Siempre genera una nueva conexion. En comparacion con PHP que algunas veces reutiliza las conexiones cuando se usa Connect() o PConnect(). Por lo pronto solo funciona con mysql (PHP 4.3.0 o posterior), postgresql y drivers derivado de oci8. Para los otros drivers NConnect() funciona como Connect().
Regresa true si esta conectado a la base de datos. Se agrego en la version 4.53.
Ejecuta el enunciado SQL en $sql y regresa un objeto de la clase ADORecordSet si es correcto. Observe que si se ejectuta correctamente el SQL, siempre regresa un recordset, aun si se ejecuto un insert o un update. Tambien se puede mandar como parametro $sql un enunciado preparado con prepared Prepare().
Regresa un objeto derivado de la clase ADORecordSet. Ej. si esta conectado a mysql, se obtiene un objeto de la clase ADORecordSet_mysql. Se regresa False si hubo un error en la ejecucion del sql.
El parametro $inputarr puede ser usado para ligar variables a parametros. A continuacion un ejemplo con Oracle:
$conn->Execute("SELECT * FROM TABLE WHERE COND=:val", array('val'=> $val));
Otro ejemplo usando ODBC, usa ?:
$conn->Execute("SELECT * FROM TABLE WHERE COND=?", array($val));
Ligando variables a parametros SQL (binding)El uso de variables en los enunciados SQL acelera la compilacion y el almacenamiento de los enunciados SQL, resultando en un mayor desepeño. Actualmente Oracle, Interbase y ODBC manejan los SQL con variables. El estilo de variables con ? de Interbase/ODBC se emula en las bases de datos que no manejan los SQL con variables. No hay que encerrar entre comillas las cadenas de cacrateres si se usa este metodo.
El manejo de variables en SQL para los drivers odbc, interbase y oci8po es:
$rs = $db->Execute('select * from table where val=?', array('10'));
Manejo de variables SQL para el driver oci8:
$rs = $db->Execute('select name from table where val=:key', array('key' => 10));
Liga de parametros en masa (Bulk binding)
Desde la version ADOdb 3.80, se maneja la liga de parametros en masa en el Execute(), habiendo que pasar una arreglo bidimencional para que se ligue al enunciado INSERT, UPDATE o DELETE.
$arr = array(
array('Ahmad',32),
array('Zulkifli', 24),
array('Rosnah', 21)
);
$ok = $db->Execute('insert into table (name,age) values (?,?)',$arr);
Esto proporciona un gran rendimiento ya que el enunciado SQL se prepara primero. El enunciado ya preparado se ejecuta sucesivamente para cada renglon del arreglo hasta que se procesan todos los renglones o hasta que ocurra un error. Es muy util para importar datos.
CacheExecute([$secs2cache,]$sql,$inputarr=false)
Es similar al Execute, excepto que el recordset es almacenado en cache por $secs2cache segundos en el directorio $ADODB_CACHE_DIR, y $inputarr solo recibe arreglos de una dimension (no soporte 'bulk'). Si se ejecuta CacheExecute() otra vez con los mismos parametros de $sql, $inputarr, y tambien la misma base datos, usuario, y el recordset almacenado en cache no a caducado, se regresa el recordset almacenado en el cache.
<?php
include('adodb/adodb.inc.php');
include('adodb/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'); # en cache por 15 secs
rs2html($rs); /* muestra el recordset como tabla html */
?>
Como alternativa, desde la version 1.80 de ADOdb, el parametro $secs2cache es opcional:
$conn->Connect(...);
$conn->cacheSecs = 3600*24; // en cache por 24 horas
$rs = $conn->CacheExecute('select * from table');
Si se omite el parametro $secs2cache, se usa el valor en $connection->cacheSecs
(el valor por omision es de 3600 segundos, o 1 hora).
Use CacheExecute() unicamente con enunciados SELECT.
Nota del desempeño: Haciendo varias medidas de desempeño (benchmarks) encontre que varian tanto que es mejor hablar de cuando es de beneficio el uso del cache. Cuando el servidor de base de datos es mas lento que tu servidor Web o si la base de datos esta muy sobrecargada entonces el cache de ADOdb es bueno porque reduce la carga a tu servidor de base de datos. Si tu servidor de base de datos esta con poca carga o es mucho mas rapido que tu servidor Web, entonces el uso del cache podria de hecho reducir el desempeño.
ExecuteCursor($sql,$cursorName='rs',$parameters=false)
Ejecuta un procedimiento almacenado (SP) de Oracle, y regresa una variable de cursor REF de Oracle como un recordset de ADOdb. No funciona con ninguna otra base de datos excepto oci8. Gracias a Robert Tuttle por el diseño.
$db = ADONewConnection("oci8");
$db->Connect("foo.com:1521", "uid", "pwd", "FOO");
$rs = $db->ExecuteCursor("begin :cursorvar := getdata(:param1); end;",
'cursorvar',
array('param1'=>10));
# $rs es ahora como cualquier otro objeto recordset de ADOdb
rs2html($rs);
ExecuteCursor() es una funcion de ayuda que internamente hace esto:
$stmt = $db->Prepare("BEGIN :RS := SP_FOO(); END;", true);
$db->Parameter($stmt, $cur, 'RS', false, -1, OCI_B_CURSOR);
$rs = $db->Execute($stmt);
ExecuteCursor solo acepta un parametro de salida. Si tu SP tiene 2 parametros, usa:
$vv = 'A%';
$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'
esto para el siguiente PL/SQL:
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)
Si tiene exito regresa un recordset, en caso contrario regresa false. Ejectuta un enunciado select, simulando la clausula "LIMIT $numrows OFFSET $offset" del enunciado SELECT de PostgreSQL.
En PostgreSQL, SELECT * FROM TABLE LIMIT 3 da como resultado los primeros 3 registros
unicamente. Lo equivalente es $connection->SelectLimit('SELECT * FROM TABLE',3).
Esta funcionalidad se simula para las bases de datos que no poseen esta caracteristica.
SELECT * FROM TABLE LIMIT 3 OFFSET 2 regresara los registros 3, 4 y 5 (es decir
despues del registro 2, regresa 2 registros). Lo equivalente en ADOdb es
$connection->SelectLimit('SELECT * FROM TABLE',3,2).
Observa que es lo contrario de la clausula LIMIT de MySQL. Tambien se puede usar
$connection->SelectLimit('SELECT * FROM TABLE',-1,10) para obtener los
registros del 11 al ultimo.
El ultimo parametros $inputarr es para aquellas bases de datos que manejan la liga de variables a parametros como Oracle oci8. Esto reduce significativamente la demora por la compilacion de enunaciados SQL. Aqui hay un ejemplo con Oracle :
$conn->SelectLimit("SELECT * FROM TABLE WHERE COND=:val", 100,-1,array('val'=> $val));
El driver oci8po (driver portable de Oracle) usa el metodo mas estandar de definir los parametros para las variables ?:
$conn->SelectLimit("SELECT * FROM TABLE WHERE COND=?", 100,-1,array($val));
Ron Wilson informa que SelectLimit no funciona con UNIONs.
CacheSelectLimit([$secs2cache,] $sql, $numrows=-1,$offset=-1,$inputarr=false)
Similar a SelectLimit, excepto que el recordset obtenido se almacene en el cache por $secs2cache segundos en el directorio $ADODB_CACHE_DIR.
Desde la version 1.80, $secs2cache es opcional y se puede definir el tiempo de cache en $connection->cacheSecs.
$conn->Connect(...);
$conn->cacheSecs = 3600*24; // cache de24 horas
$rs = $conn->CacheSelectLimit('select * from table',10);
CacheFlush($sql=false,$inputarr=false)
Elimina (borra) cualquier recordsets en el cache $ADODB_CACHE_DIR del enunciado SQL en $sql.
Si no se manda ningun parametro, todos los archivos adodb_*.cache son eliminados.
Si se desean borrar todos los archivos de cache en forma manual, hay que ejecutar el
siguiente codigo PHP (funciona unicamente en Unix/linux):
system("rm -f `find ".$ADODB_CACHE_DIR." -name
adodb_*.cache`");
Para una limpieza general de los archivos caducos, se recomienda el uso de
crontab
en Unix, o de at.exe en Windows, y un archivo de comandos similiar al
siguiente:
#------------------------------------------------------
# Este ejemplo en particular borra archivos en el
# directorio TMPPATH # con la cadena de caracteres ".cache"
# en el nombre que tengan mas de 7 dias.
#------------------------------------------------------
AGED=7
find ${TMPPATH} -mtime +$AGED | grep "\.cache" | xargs rm -f
Regresa un numero de error virtual, en base a la numeracion del DB de PEAR. Se puede necesitar incluir adodb-error.inc.php antes de invocar esta funcion. El parametro $errno es el numero de error nativo que se desea convertir. Si no se manda ningun parametro, MetaError invocara ErrorNo() para convertirlo. Si el numero de error no tiene equivalente virtual, MetaError regresara -1 (DB_ERROR).
Recibe el numero de error generado por MetaError() para obtener el equivalente mensaje de error virtual.
Regresa el ultimo mensaje de error. El mensaje de error se cambia despues de cada llamado a la funcion Execute().
Puede regresar un texto aun si no ocurrio un error. No es necesario llamar esta funcion a menos que la funcion ADOdb regrese falso.
Nota: Si esta habiliado debug, los mensajes de error SQL se despliegan cada vez que la funcion Execute es llamada.
Regresa el ultimo numero de error. Este numero de error se actualiza despues de cada invocacion de Execute(). Si se obtiene el valor 0, es que no hubo error.
Tenga en cuenta que las versiones antiguas de PHP (antes de 4.0.6) no generan numero de error para conexiones ODBC. En lo general no es necesario invocar esta funcion a menos que la funcion ADOdb regrese el valor falso.
IgnoreErrors($saveErrHandlers)
Te permite ignorar errores para que StartTrans()/CompleteTrans() no se vea afectado, asi como tampoco sea invocado el menajador de erroes 'normal' en caso de ocurra un error. Es util si qiueres verificar si existe un campo o una table sin que se invoque un error si no existe.
Uso:
$saveErrHandlers = $conn->IgnoreErrors();
$rs = $conn->Execute("select campo from alguna_table_que_pueda_no_existir");
$conn->IgnoreErrors($saveErrHandlers);
Advertencia: no invoques StartTrans()/CompleteTrans() dentro de un bloque que usa IgnoreErrors().
Asigna el modo para obtener los resultados para la conexion y lo almacena en $db->fetchMode. Los modos permitidos son ADODB_FETCH_ASSOC y ADODB_FETCH_NUM. Para mas informacion vea $ADODB_FETCH_MODE.
Regresa el metodo anterior, o falso si SetFetchMode( ) no habia sido llamado con anterioridad.
CreateSequence($seqName = 'adodbseq',$startID=1)
Crea una secuencia. La siguiente vez que se invoque GenID( ), el valor que regrese sera $startID. Se agrego en la version 2.60.
DropSequenceD($seqName = 'adodbseq')
Borra una secuencia. Se agrego en la version 2.60.
GenID($seqName = 'adodbseq',$startID=1)
Genera un numero en secuencia. Funciona para interbase, mysql, postgresql, oci8, oci8po, mssql, y los drivers basados en ODBC. Utiliza $seqName como el nombre de la secuencia. GenID() creara automaticamente la secuencia si no existe (con la condicion de que el usuario tenga permiso de crearla). Si no habra que crear la secuencia primero.
Si el driver de su base de datos emula a las secuencias, el nombre de la tabla es el nombre de la secuencia. La tabla tiene una columna, 'id' la cual deberia de ser de tipo entero, o si se necesita algo mayor, numeric(16).
Para ODBC y bases de datos que no manejan secuencias en forma nativa (ej mssql, mysql), se crea la tabla para cada secuencia. Si la secuencia no habia sido definida anteriormente se creara con el valor inicial de $startID.
Nota, el driver de mssql anterior a la version 1.90 generaba GenID() de 16 bytes (GUID).
UpdateBlob($table,$column,$val,$where)
Permite almacenar el valor blob de $val en la columna $column de la tabla $table en el renglon que cumpla el criterio $where.Uso:
# para oracle
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, empty_blob())');
$conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');
# las demas bases de datos (excepto oracle)
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');
Regresa verdadero si tiene existo, faslo en caso contrario. Sirve para MySQL, PostgreSQL, Oci8, Oci8po e Interbase. Otros drivers pueden funcionar, dependiendo del estado de su desarrollo (informix ya funciona).
Nota, cuando se lee un blob de Interbase blob con un SELECT, todavia necesita ser decodificado usando $connection->DecodeBlob($blob); para obtener el valor original en versiones de PHP anteriores a 4.1.0.
Para PostgreSQL, se pueden almacenar blob en campos OID o bytea.
Se pueden usar campos bytea pero no OID con UpdateBlob( ). Y UpdateBlobFile( ) maneja
OID, pero no bytea.
Si el parametro no es un OID, entonces UpdateBlob() asume que se esta almacenando
en un campo bytea.
UpdateClob($table,$column,$val,$where)
Permite almacenar el valor clob en la variable $val en la columna $column de la tabla $table en el renglon que cumpla el criterio $where. Es similar a UpdateBlob anterior, pero para 'Character Large OBjects'.Uso:
# para oracle
$conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, empty_clob())');
$conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');
# las demas bases de datos (excepto oracle)
$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 a UpdateBlob, excepto que se pasa como parametro el nombre del archivo que contiene el blob.
Para PostgreSQL, si estas usando OID, use esta interfase. Esta interfase no maneja campos bytea.
Regresa verdadero si tiene exito, falso en caso contrario.
Agunas bases de datos requieren que los blobs se codifiquen manualmente antes de ser almacenados. Nota, si se usa UpdateBlob( ) o UpdateBlobFile( ) la conversion es automatica y no hay necesidad de llamar esta funcion. Para PostgreSQL, BlobEncode() puede unicamente ser usada en campos bytea.
Regresa el valor del blob codificado.
Nota, hay una propiedad del objeto conexion llamada blobEncodeType el cual tiene 3 valor legales:
false - no hay necesidad de realizar codificacion ni decodificacion.
'I' - Se requiere la codificacion de blobs, y se obtiene un valor numerico (no hay
necesidad de encerrar entre comillas).
'C' - Se requiere la codificacion de blobs, y se obtiene un valor alfanumerico (si
requiere que se encierre entre comillas).
Esto es solo para efectos de documentacion, para que el programa que maneja varios drivers de bases de datos sepa que es lo correcto cuando procesa blobs.
Algunas bases de datos requieren que los blobs sean decodificados manualmente despues de ejecutar el select. Si la base de datos no requiere la decodificacion, esta funcion regresara el blob sin cambio. Actualmente BlobDecode es requerido unicamente para una base de datos, PostgreSQL, y unicamente si se usan campos OID (si se usan campos bytea se decodifican automaticamente). El valor por omision maximo de un blob esta en $connection->maxblobsize, que vale 256K en adodb 4.54.
En ADOdb 4.54 y posterior el valor del blob es el parametro de salida.EN versiones anteriores el valor del blob se mandaba a stdout.
$rs = $db->Execute("select bloboid from postgres_table where id=$key");
$blob = $db->BlobDecode( reset($rs->fields) );
Replace($table, $arrFields, $keyCols,$autoQuote=false)
Intenta hacer un UPDATE al registro, si no encuenta el registro, se genera y ejecuta un INSERT. Regresa 0 si falla, 1 si efectuo el update y 2 si no se encontro el registro y el insert fue con exito. Es diferente al replace de MySQL el cual borra el registro e inserta uno nuevo. Esto tambien significa que no se puede actualizar la llave primaria. La unica excepcion es con Interbase y sus derivados, que si usan delete e insert debido a algunas limitantes del API de Interbase.
Los parametros son el nombre de la tabla ($table), $arrFields que es un arreglo asociativo donde las llaves son los nombres de los campos y $keyCols es el nombre del campo llave primaria o un arreglo de nombres de campos si es una llave compuesta. Si $autoQuote tiene el valor true, entonces Replace() encerrara entre comillas todos los valor que no son numericos, los NULLs no se encomillan. Observe que este encomillado automatico no funcionara si se usan funciones SQL u operadores.
Ejemplos:
# Llave primaria de un solo campo
$ret = $db->Replace('atable',
array('id'=>1000,'firstname'=>'Harun','lastname'=>'Al-Rashid'),
'id',$autoquote = true);
# genera UPDATE atable SET firstname='Harun',lastname='Al-Rashid' WHERE id=1000
# o INSERT INTO atable (id,firstname,lastname) VALUES (1000,'Harun','Al-Rashid')
# Llave compuesta
$ret = $db->Replace('atable2',
array('firstname'=>'Harun','lastname'=>'Al-Rashid', 'age' => 33, 'birthday' => 'null'),
array('lastname','firstname'),
$autoquote = true);
# sin el encomillado automatico
$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)
Desde la version 4.56 de ADOdb, puedes genrerar y ejecutar automaticamente INSERTs y UPDATEs en la tabla indicada con esta funcion, la cual encapsula a GetInsertSQL() y GetUpdateSQL().
AutoExecute() inserta o actualiza la tabla $table dado un arreglo de campos ($arrFields), donde la llave es el nombre del campo y el valor del arreglo es el valor del campo a almacenar. Toma en cuenta que hay un costo debido a que la tabla primero es consultada para obtener informacion de las llaves antes de que se genere el SQL. Se genera un INSERT o un UPDATE en base al valor de $mode (ver en seguida).
Valores permitidos de $mode
Tu tienes que definir las constantes DB_AUTOQUERY_UPDATE y DB_AUTOQUERY_INSERT o incluir el archivo adodb-pear.inc.php.
La clausula $where es obligatoria si $mode == 'UPDATE'. Si $forceUpdate=false entonces primero se consulta la base de datos y verificamos si el valor del campo obtenido por la consulta coincide con el valor del arreglo; solo si son diferentes se actualiza el campo.
Regresa true si es correcto, false si hay error.
Un ejemplo de esto es:
$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%'";
Nota: Una de las fortalezas del AutoExecute() de ADOdb es que solo los nombres de campo validos de la tabla $table son actualizados. Si $arrFields contiene campos que no son de la tabla, son ignorados. Esto tiene un costo ya que hay que consultar la base de datos para obtener el nombre de los campos, pero ya que tu no estas codificando el SQL, significa