Você está na página 1de 79

TECNOLOGICO NACIONAL DE MEXICO

CAMPUS TUXTEPEC

ASIGNATURA:
Programacin web avanzada

CARRERA:
Ingeniera en Informtica

SEMESTRE: 10to.

GRUPO: A

CATEDRATICO:
M.S.C. Vctor Manuel Evaristo Salinas
UNIDAD:
IIII
PRESENTA:
Ricardo Vzquez Pavn

Mayo del 2015, San Juan Bautista Tuxtepec, Oaxaca

Introduccion
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 adodbsession.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.

Caracteristicas especiales de ADOdb

Facil para programadores Windows debido a que muchas de las convenciones son
similares al ADO de Microsoft.
A diferencia de otras clases PHP de base de datos que se enfocas unicamente en el
enunciado SELECT. ADOdb soporta codigo para manajar INSERT y UPDATE que
son rapidamente adaptables a multiples bases de datos. Tambien hay metodos para

manejo de fechas, concatenacion de cadenas y encomillado de cadenas para diferentes


bases de datos.
Tiene un systema de metatipos (metatype) para poder determinar cuales tipos como
CHAR, TEXT and STRING son equivalentes en diferentes bases de datos.
Es facil de portar debido a que todo el codigo que depende de la base de datos esta en
funciones. Tu no tienes que portar la logica principal de las clases.
Creacion de tablas e indices portable con las clases de diccionario de datos datadict.
Monitor de rendimiento de base de datos y ajuste de enunciados SQL con la clase de
performance monitoring.
Sesiones en base de datos con la clase session management. Maneja notificacion por
sesion vencida.
Mapeo a Objectos Relacionales uando la clase ADOdb_Active_Record.

Como se esta usando ADOdb


Aqui hay algunos ejemplos de personas que usan ADOdb (para una lista mas larga, visita
http://adodb.sourceforge.net/):

PhpLens es un componente comercial de cudricula de datos que permite tanto a


programadores expertos como a inexpertos desarrollar y mantener bases de datos en la
Web facilmente. Desarrollado por el autor de ADOdb.
PHAkt: PHP Extension for DreamWeaver Ultradev permite hacer programas PHP en el
popular editor de paginas Web. El manejo de la base de datos es con ADOdb.
Analysis Console for Intrusion Databases (ACID): Motor de analisis para buscar y
procesar una base de datos de incidentes de seguridad generada por otros programas
como IDSes y firewalls (e.g. Snort, ipchains). Por Roman Danyliw.
PostNuke es una sistema de control de contenidos muy popular. Maneja un soporte
completo de CSS, cumple con HTML 4.01, un sistema avanzado de bloques, y es
completamente multilenguaje.
EasyPublish CMS es otro sistema de control de contenidos. Para el manejo de
informacion y modulos integrados para tu internet, intranet y extranet. Noruego.
NOLA es una apliacion completa de contabilidad, inventarios y control de trabajo. Su
licencia es GPL, desarrollado por Noguska.

Solicitud de mejoras y reporte de fallas


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.

Guia de Instalacion
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, $contrasea, $database);
$rs = $db->Execute('select * from alguna_tabla_pequea');
print "<pre>";
print_r($rs->GetRows());
print "</pre>";
?>

Instalacion Minima
Para los desarrolladores que quieran distribuir una version minima de ADOdb, se requieren los
siguientes archivos:

adodb.inc.php
adodb-lib.inc.php
adodb-time.inc.php
drivers/adodb-$database.inc.php
license.txt (por razones legales)
adodb-php4.inc.php
adodb-iterator.inc.php (funcionaldiad para PHP5)

Opcionalmente:

adodb-error.inc.php y lang/adodb-$lang.inc.php (si usas MetaError())


adodb-csvlib.inc.php (si usas recordsets en memoria - CacheExecute(), etc)
adodb-exceptions.inc.php y adodb-errorhandler.inc.php (si usas el manejo de errores de
ADOdb o excepciones de PHP5).
adodb-active-record.inc.php si usas Active Records.

Ejemplos de Codigo de Inicio


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
contrasea, 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().

Soporte a Data Source Name (DSN)


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.

Ejemplos de Conexion a Bases de Datos


MySQL y la mayoria de bases de datos
Las conexiones a MySQL son muy sencillas, y los parametros son identicos a mysql_connect:
$conn = &ADONewConnection('mysql');
$conn->PConnect('localhost','usuario','contrasea','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,
$contrasea, $database). Las excepciones se enlistas a continuacion.
PDO
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
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','contrasea','database');

c. dsn:
$dsn = 'postgres://user:pwd@localhost/mydb?persist'; # persist es
opcional
$conn = ADONewConnection($dsn); # no se requiere Connect/PConnect

LDAP
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);

Interbase/Firebird
Hay que definir la base de datos en el parametro $host:
$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

SQLite Sqlite creara la base de datos si no existe.


$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

Oracle (oci8)
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);

DSN-less ODBC (ejemplos con access and mssql)


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


Si estas usando una version de PHP anterior a 4.3.0, Las conexiones DSN-less solo
trabajaran con el ADO de Microsoft, el cual esta basada en las APIs COM de Microsoft.
Un ejemplo de uso de la libreria ADOdb y el ADO de Microsoft:
<?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 de alta velocidad - trucos de optimizacion


La libreria ADOdb es una clase grande, aun asi regularmente derrota a las 'otras' clases
PHP en rendimiento. Esto es por su diseo 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
Execute, CacheExecute
SelectLimit, CacheSelectLimit
MoveNext, Close
qstr, Affected_Rows, Insert_ID
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);


while (!$rs->EOF) {
var_dump($rs->fields);

$rs =& $rs->Execute($sql);


$array = adodb_getall($rs);

$rs->MoveNext();

var_dump($array);

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.

Modfificando ADOdb con seguridad


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.

Caracteristicas para PHP5


A partir de la version 4.02 ADOdb determina automaticamente que version de PHP estas
usando. Si detecta la version PHP5, activa automaticamente las siguientes caracteriticas:

PDO: estan disponibles los drivers de PDO. Ve los ejemplos de conexion.


Actualemte los drivers PDO no son tan poderosos como los drivers nativos, y deben
de ser tomados como experimentales.

Foreach iterators: Es una forma muy clara de procesar un 'recordset':

$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$rs = $db->Execute($sql);
foreach($rs as $k => $row) {
echo "r1=".$row[0]." r2=".$row[1]."<br>";
}

Exceptions: Unicamente hay que incluir adodb-exceptions.inc.php y ya se pueden


atrapar las excepciones conforme ocurran los errores.
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.

Bases de Datos soportadas


La columna nombre es el valor que se le pasa a NewADOConnection($nombre) para crear
el objecto de conexion para esa base de datos.
Nombre

Verificad Base de datos


a

sirve
RecordCount
()

PreSistemas
requisito operativo
s
s

access

Microsoft Access/Jet. Hay que crear el


DSN en el ODBC.

S/N

ODBC

ado

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.

? depende de
la base de
datos

ADO o
Windows
proveedor unicamente
OLEDB

Windows
unicamente

Hay que configurar $db->codePage antes


de conextarse.
ado_access

Microsoft Access/Jet usando ADO. Permite S/N


conexiones DSN-less. Para mejor
rendimiento usar un proveedor OLEDB.

ADO o
Windows
proveedor unicamente
OLEDB

ado_mssql

Microsoft SQL Server usando ADO.


Permite conexiones DSN-less. Para mejor
rendimiento usar un proveedor OLEDB.

ADO o
Windows
proveedor unicamente
OLEDB

db2

DB2. Debe de funcionar satisfactoriamente S/N


porque se base en el driver ODBC based on
ODBC.

S/N

Interfase
CLI/ODB
C 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

Se conecta a DB2 usando la extesion


ODBC generica.

vfp

fbsql
ibase

S/N

Interfase
CLI/ODB
C 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.

Microsoft Visual FoxPro. Hay que crear un S/N


DSN.

ODBC

Windows
unicamente

FrontBase.

Unix y
Windows

Interbase 6 o anterior. Algunos usuarios


S/N
dicen que puedes necesitar esta sintaxis
para conectarte
$db>PConnect('localhost:c:/ibase/employee.gd
b', "sysdba", "masterkey") . Actualmente le
falta Affected_Rows.

cliente
Interbase

Unix y
Windows

Antes de conectarte puedes modificarle


$db->dialect, $db->buffers y $db->charSet.
version Firebird de interbase.

S/N

cliente
Interbase

Unix y
Windows

borland_ibas C
e

version Borland de Interbase 6.5 o


posterior. Desafortunadamente las version
son diferentess.

S/N

cliente
Interbase

Unix y
Windows

informix72

Versiones Informix anteriores a 7.3 que no


soportan SELECT FIRST.

S/N

Cliente
Informix

Unix y
Windows

informix

Driver generico para informix.

S/N

Cliente
Informix

Unix y
Windows

ldap

Driver LDAP driver. Ver el ejemplo para


informacion de uso.

Extension
LDAP

firebird

mssql

Microsoft SQL Server 7 y posterior.


S/N
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!

cliente
Mssql

Unix y
Windows.
Guia de
instalacion
de Unix y
otra mas.

mssqlpo

Driver portable de mssql. Es identico al


S/N
driver de mssqk anteriorm excepto que el
operador de concatenacion '||' se convirtio a
'+'. Esto es util para migrar codigo desde
otras versiones de SQL.

Cliente
Mssql

Unix y
Windows.
Guia de
instlacion
en Unix.

mysql

MySQL sin manejo de transacciones.


Puedes usar $db->clientFlags antes de
conectarte.

S/N

Cliente
MySQL

Unix y
Windows

mysqlt or
maxsql

MySQL con soporte de transacciones.


S/N
Recomendamos usar || como el operador de
concatenacion para una mejor portabilidad.
Esto se logra ejectuando MySQL con:
mysqld --ansi o mysqld --sqlmode=PIPES_AS_CONCAT

Cliente
MySQL

Unix y
Windows

oci8

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.

S/N

Cliente
Oracle

Unix y
Windows

hay dos maneras de conectarse - Con la


direccion IP del servidor y el nombre del
servicio:
PConnect('serverip:1521','scott','tiger','serv
ice')
o en base a un renglon en
TNSNAMES.ORA o ONAMES o
HOSTNAMES:
PConnect(false, 'scott', 'tiger', $oraname).
A partir de la version 2.31, se manejan las
variables de cursores REF directamente
(ver ExecuteCursor).
oci805

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

Driver portable de Oracle 8/9. Esta es casi S/N


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).

Cliente
Oracle

Unix y
Windows

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.
odbc

Driver generico para ODBC, no esta


? depende de
optimizado para ninguna base de datos
la base de
especifica. Para conectarse usa
datos
PConnect('DSN','user','pwd'). Esta es la
clase base para todos los drivers basados en
ODBC .

ODBC

Unix y
Windows.
Trucos para
Unix.

odbc_mssql

Usa ODBC para conectarse a MSSQL

S/N

ODBC

Unix y
Windows.

odbc_oracle

Usa ODBC para conectarse a Oracle

S/N

ODBC

Unix y
Windows.

odbtp

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

Odtbp con soporte unicode

S/N

odbtp

Unix y
Windows

odbtp_unico C
de
oracle

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

Driver para Netezza. Netezza esta basado


en el codigo base de postgres.

postgres

Driver generico PostgreSQL. Actualmente


es identico al driver postgres7.

Cliente
Unix y
PostgreSQ Windows.
L

postgres64

Para PostgreSQL 6.4 y anteriores que no


manejan LIMIT internamente.

Cliente
Unix y
PostgreSQ Windows.
L

postgres7

PostgreSQL que soporta LIMIT y


caracteristicas de la version 7.

Cliente
Unix y
PostgreSQ Windows.
L

postgres8

PostgreSQL que maneja la funcionalidad de S


la version 8.

Cliente
Unix y
PostgreSQ Windows.
L

sapdb

SAP DB. Debe de funcionar bien ya que


esta basado en el driver ODBC.

Cliente
ODBC de
SAPdb

sqlanywhere C

sqlite

S/N

Sybase SQL Anywhere. Debe de funcionar S/N


bien ya que esta basado en el driver ODBC.

Cliente
?
ODBC de
SQL
Anywhere
ODBC

SQLite. Unicamente verificada en PHP5.

Unix y
Windows.

sqlitepo

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.

Unix y
Windows.

En el driver "sqlitepo", el nombre de la


tabla es eliminado del nombre de la
columna. Cuando hay conflictos, el primer
campo tiene preferencia.
sybase

Sybase.

S/N

Cliente
Sybase

Unix y
Windows.

sybase_ase

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.

Tutoriales
Ejemplo 1: SELECT
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.

Ejemplo 2: SELECT Avanzado con objetos de campos

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.

name: Nombre de la columna (campo)


type: Tipo nativo del campo de la columna
max_length: Longitid maxima del campo. Algunas bases de datos como MySQL no
regresan la longitud maxima del campo adecuadamente. En estos casos max_length
contendra -1.

Posteriormente usamos MetaType() para traducir el tipo nativo a un tipo generico.


Actualmente estan definidos los siguientes tipos genericos:

C: Campo caracter que se debe de mostrar en etiquetas <input type="text">.


X: TeXtos, campos de texto largo (indefinido) que se deben de mostrar en
<textarea>
B: Blobs, u Objectos Binarios Largos (BYTE). Normalmente son imagenes.
D: Campo fecha
T: Campo Timestamp o datetime
L: Campo logico (boleano o de bit)
I: Campo entero

N: Campo numerico. Incluye auto incrementales (seriales), numericos, punto


flotante, reales y enteros.
R: Campo serial. Incluye serial, enteros auto incrementales integers. Funciona solo
para algunas bases de datos.

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.

Ejemplo 3: Insert
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');
$conn = &ADONewConnection('access');

# carga el codigo comun de ADOdb


# 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.

Ejemplo 4: Depurando
<?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.

Ejemplo 5: MySQL y Menus


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().

Ejemplo 6: Conectarse a dos bases de datos al mismo tiempo


<?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 ...');
?>

Ejemplo 7: Generando enunciados SQL de Update e Insert

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_TYPE
El 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().

Ejemplo 8: Implementando cursores con Siguiente y Anterior


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:


|< << >> >|

ID First Name Last Name

Date Created

36 Alan

Turing

Sat 06, Oct 2001

37 Serena

Williams

Sat 06, Oct 2001

38 Yat Sun

Sun

Sat 06, Oct 2001

39 Wai Hun

See

Sat 06, Oct 2001

40 Steven

Oey

Sat 06, Oct 2001

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/adodbpager.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 Ivn Oliva and Cornel G.

Ejemplo 9: Exportando a formatos delimitados por tabulador o comas


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.

Ejemplo 10: Filtros a la medida


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.

Ejemplo 11: Transacciones Inteligentes


El metodo anterior de manejo de transaciones requeria que hicieras esto
$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().
$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'.

Usando manejadores de errores a la medida y PEAR_Error


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")

PEAR_ERROR
El segundo manjeador de errores es adodb-errorpear.inc.php. Este crea una objeto de la
clase PEAR_Error cada vez que hay un error. El ultimo objeto PEAR_Error creado puede
ser obtenido usando la funcion ADODB_Pear_Error().
<?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.

MetaError y MetaErrMsg
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().
Mensajes de Error
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.

Nombres de DSN
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:$contrasea@$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.

Compatibilidad con PEAR


Soportamos DSNs (ver arriba), y las siguientes funciones:

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

Guardando recordsets en Memoria Intermedia (Caching)


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.

Tablas Pivote
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:
Proveedor Categoria
proveedor1 categoria1
proveedor2 categoria1
proveedor2 categoria2

categoria1 categoria2 total


--> proveedor1

proveedor2

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

REFERENCIA de la Clase
Los parametros de funcion encerrados entre [ ] son opcionales.

Variables Globales
$ADODB_COUNTRECS
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.

$ADODB_CACHE_DIR
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

$ADODB_ANSI_PADDING_OFF
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.

$ADODB_LANG
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.

$ADODB_FETCH_MODE
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( ).
ADODB_ASSOC_CASE
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');

$ADODB_FORCE_TYPE
Ve el tutorial de GetUpdateSQL.

ADOConnection
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.

Campos (propiedades) de ADOConnection


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
contrasea 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.

Funciones/metodos principales de ADOConnection


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 contrasea
$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
contrasea $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().
IsConnected( )
Regresa true si esta conectado a la base de datos. Se agrego en la version 4.53.
Execute($sql,$inputarr=false)
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 desepeo. 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 desempeo: Haciendo varias medidas de desempeo (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 desempeo.
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 diseo.
$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
MetaError($errno=false)
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).
MetaErrorMsg($errno)
Recibe el numero de error generado por MetaError() para obtener el equivalente mensaje
de error virtual.
ErrorMsg()
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.
ErrorNo()
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().
SetFetchMode($mode)
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.
BlobEncode($blob)
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.
BlobDecode($blob)
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','AlRashid')
# 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

'INSERT' o 1 o DB_AUTOQUERY_INSERT
'UPDATE' o 2 o DB_AUTOQUERY_UPDATE

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 que
tu probablemente no estas tan interesado en velocidad como en conveniencia.
Desde 4.62, el nombre de la tabla puede ser forzado asignandolo en $rs->tableName antes
de invocar AutoExecute(), GetInsertSQL() o GetUpdateSQL().
GetUpdateSQL(&$rs, $arrFields, $forceUpdate=false,$magicq=false)

Genera el enunciado SQL para actualizar una tabla, dandole el recordset $rs, y un arreglo
con los campos modificados a comparar con el recordset ($arrFields, el cual debe de ser un
arreglo asociativo conteniendo el nombre de la columna y el nuevo valor). Si $forceUpdate
vale true, entonces tambien se genera el SQL aun cuando $arrFields sea identico a $rs>fields. Requiere que el recordset sea asociativo. $magicq es utilizado para indicar si se
desea encomillado automatico (ver qstr()). El nombre de los campos en el arreglo puede ser
con mayusculas o minusculas.
Desde la version 4.52, se permite que pasas el parametro $force, y este tiene precedencia
sobre la variable global $ADODB_FORCE_TYPE.
Desde la version 4.62, el nombre de la tabla a usar puede ser modificada usando $rs>tableName antes de llamar a AutoExecute(), GetInsertSQL() o GetUpdateSQL().
GetInsertSQL(&$rs, $arrFields,$magicq=false)
Genera el enunciado SQL para insertar en una tabla, dandole un recordset $rs. Requiere
que este en modo asociativo. $magicq se usa para indicar si se desea el encomillado
automatico de los valores (ver qstr()). El nombre de los campos en el arreglo puede ser con
mayusculas o minusculas.
Desde laversion 2.42, se puede pasar como parametro el nombre de la tabla en lugar del
recordset (parametro $rs), y se generara automaticamente el enunciado de INSERT para
esa tabla.
Desde la version 4.52, se permite que pasas el parametro $force, y este tiene precedencia
sobre la variable global $ADODB_FORCE_TYPE.
Desde la version 4.62, el nombre de la tabla a usar puede ser modificada usando $rs>tableName antes de llamar a AutoExecute(), GetInsertSQL() o GetUpdateSQL().
PageExecute($sql, $nrows, $page, $inputarr=false)
Se usa para procesar un recordset por paginas. La pagina inicial es 1. Vea el Ejemplo 8.
CachePageExecute($secs2cache, $sql, $nrows, $page, $inputarr=false)
Se usa para procesar un recordset por paginas. La pagina inicial es 1. Vea el Ejemplo 8.
version con cache del PageExecute.
Close( )
Cierra la conexion a la base de datos. PHP4 orgullosamente nos indica que ya no es
necesario hacer la limpieza al final de la conexion por que el mecanismo de conteo de PHP4
lo hara por nosotros.

StartTrans( )
Inicia una transaccion monitoreada. Cada enunciado SQL que se ejectute, ADOdb lo
monitoreara buscando errores SQL, y si detecta alguno cuando se invoque
CompleteTrans(), se hara un rollback automatico.
Para entender porque StartTrans() es mejor que BeginTrans(), examinemos algunas
maneras de usar BeginTrans(). A continuacion la manera incorrecta de usar las
transacciones.
$DB->BeginTrans();
$DB->Execute("update table1 set val=$val1 where id=$id");
$DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CommitTrans();

debido a que no se verifica por errores. Es posible que se actualize la tabla table1 y que la
actualizacion de la tabla table2 falle. Esta es una manera mejor (o menos peor):
$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();

Otra manera (con el metodo antiguo) de hacerlo desde la version de 2.0 de ADOdb:
$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);

Es muy engorroso monitorear $ok por todo el codigo. StartTrans() es una mejora debido a
que monitorea todos los erroers SQL por nosotros. Esto es particularmente util si invocas
una funcion de 'caja negra' en el cual se pueden ejecutar varios enunciados SQL.
Adicionalmente,todas las llamadas a BeginTrans, CommitTrans o RollbackTrans dentro
de un bloque StartTrans seran desabilitadas, por lo cual aunque la 'caja negra' haga un
commit, sera ignorado.
$DB->StartTrans();
CallBlackBox();
// Funcion que hace varias cosas
$DB->Execute("update table1 set val=$val1 where id=$id");
$DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CompleteTrans($ok);

Nota los bloques StartTrans son anidables, los bloques interiores son ignorados.
CompleteTrans($autoComplete=true)
Termina una transaccion iniciada con StartTrans(). Esta funcion monitorea por posibles
errores SQL, y hara un 'commit' si no ocurrieron errores, en caso de algun error hara el

'rollback'. Regresa verdadero si efectuo el commit y false si llamo el roolback. Si el


parametro $autoComplete es true se monitorean los errores y hace commit o rollback
segun sea el caso. Con $autoComplete en false se hace rollback aun cuando no se hayan
detectado errores.
FailTrans( )
Aborta una transaccion iniciada con StartTrans(). El rollback se hara hasta que se invoque
CompleteTrans().
HasFailedTrans( )
Verifica si una transaccion inteligente ha fallado, es decir regresa true si ha habido un
error SQL o si se invoco a FailTrans(). Si no esta dentro de una transaccion inteligente
regresa falso.
BeginTrans( )
Inicia una transaccion. Desactiva el Commit automatico. Regresa true si se hace con exito.
Algunas bases de datos siempre regresan false si no esta habilitado el manejo de
transacciones. Cualquier transaccion abierta hara rollback cuando se cierre la conexion.
Algunas de las bases de datos que manejan transacciones son: Oracle, PostgreSQL,
Interbase, MSSQL, ciertas versiones de MySQL, DB2, Informix, Sybase, etc.
Observe que StartTrans() y CompleteTrans() son un metodo superior para el manejo de
transacciones, disponible desde ADOdb 3.40. Para una explicacion vea la documentacion
de StartTrans().
Tambien se puede usar el manejador de errores de ADOdb para matar y hacer rollback de
la transaccion automaticamente. Algunas extensiones de bases de datos problematicas
hacen 'commit' de todas las transacciones pendientes, por lo cual conviene por seguridad
invocar manualmente $DB->RollbackTrans() en el manejador de errores.
Detectando Transacciones
Desde la version 2.50 de ADOdb, se puede detectar si se esta dentro de una transaccion.
Hay que verificar si $connection->transCnt > 0. Esta variable se incrementa cada vez que
se llama a BeginTrans(), y se decrementada cuando se invoca a RollbackTrans() o
CommitTrans().
CommitTrans($ok=true)
Termina una transaccion con exito. Regresa true si funciona. Si la base base de datos no
maneja transaccion tambien regresara true ya que los datos son siempre almacenados.

Si se manda el parametro $ok=false, invocara un 'rollback'. Vea el ejemplo de


BeginTrans().
RollbackTrans( )
Termina la transaccion regresando los cambios ('rollback'). Regresa true si tiene exito. Si
la base de datos no maneja transacciones, regresara false ya que los datos no se pueden
restaurar.
SetTransactionMode($mode )
SetTransactionMode te permite indicar el modo de trasaccion a usar para todas las
transacciones subsecuentes. Nota: si tu tienes conexiones persistentes y usas mssql o mysql,
puedes tener que regresar explicitamente el modo de transaccion alprincipio de cada
pagina. Actualmente solo esta soportado para postgresql, mssql, mysql con InnoDB y oci8.
Por ejemplo:
$db->SetTransactionMode("SERIALIZABLE");
$db->BeginTrans();
$db->Execute(...); $db->Execute(...);
$db->CommiTrans();
$db->SetTransactionMode(""); // lo regreso al valor por omision
$db->StartTrans();
$db->Execute(...); $db->Execute(...);
$db->CompleteTrans();

Valores permitidos son:

READ UNCOMMITTED (permite 'dirty reads', pero es mas rapido)


READ COMMITTED (valor por omision para postgres, mssql y oci8)
REPEATABLE READ (omision para mysql)
SERIALIZABLE (mas lento y mas restrictivo)

Puedes tambiar indicar un valor especifico para tu base de datos como 'SNAPSHOT' para
mssql o 'READ ONLY' para oci8/postgres.
Ve la secccion 'transaction levels' para PostgreSQL, Oracle, MySQL, MS SQL Server e
Informix.
GetAssoc($sql,$inputarr=false,$force_array=false,$first2cols=false)
Regresa un arreglo asociativo para el enunciado SQL solicitado en $sql, opcionalmente
puede tener liga de parametros usando $inputarr. Si el numero de columnas obtenido es
mayor a dos, se genera un arreglo bidimensional con la primera columa del recordset como
la llave del resto de los campos. Si hay exactamente dos columnas, se obtiene un arreglo de
una dimension donde la llave (primera columna) apunta a su valor (segunda columna). A

menos que $force_array tenga el valor true, en cuyo caso se crea un arreglo para cada
valor.
Ejemplos:
Si tenemos los siguientes datos en el recordset:
renglon1: Manzana, Fruta, Comible
renglon2: Cactus, Planta, Incomible
renglon3: Rosa, Flor, Comible
GetAssoc generara el siguiente arreglo asociativo bidimensional:
Manzana => array[Fruta, Comible]
Cactus => array[Planta, Incomible]
Rosa => array[Flor,Comible]
Si el conjunto de datos es:
renglon1: Manzana, Fruta
renglon2: Cactus, Planta
renglon3: Rosa, Flor
GetAssoc generara el siguiente arreglo asociativo (con $force_array==false):
Manzana => Fruta
Cactus=>Planta
Rosa=>Flor
La funcion regresa el arreglo asociativo, o falso si ocurrio un error.
CacheGetAssoc([$secs2cache,] $sql,$inputarr=false,$force_array=false,$first2cols=false)
La version con cache de la funcion GetAssoc anterior.
GetOne($sql,$inputarr=false)
Ejecuta el enunciado SQL y regresa el primer campo del primer renglon. El recordset y el
resto de los renglones son descartados automaticamente. Si hay un error la funcion regresa
false.
GetRow($sql,$inputarr=false)
Ejecuta el enunciado SQL y regresa el primer renglon como un arreglo. El recordset y el
resto de los renglones son descartados automaticamente. Si hay un error la funcion regresa
false.

GetAll($sql)
Ejecuta el enunciado SQL y regresa todos los renglones como un arreglo bidimensional. El
recordset es descartado automaticamente. Si hay un error la funcion regresa false.
GetCol($sql,$inputarr=false,$trim=false)
Ejecuta el enunciado SQL y regresa todos los elementos de la primera columna como un
arreglo dimencional. El recordset es descartado automaticamente. Si ocurre un error
regresa false.
CacheGetOne([$secs2cache,] $sql,$inputarr=false), CacheGetRow([$secs2cache,]
$sql,$inputarr=false), CacheGetAll([$secs2cache,] $sql,$inputarr=false),
CacheGetCol([$secs2cache,] $sql,$inputarr=false,$trim=false)
Similares a las funciones Get* anteriores, excepto que el recordset es almacenado en el
cache indicado en $ADODB_CACHE_DIR por $secs2cache segundos. Es bueno para
acelerar preguntas en datos que cambian poco. El parametro $secs2cache es opcional. Si se
omite se usa el valor de $connection->cacheSecs (normalmente de 3600 segundos o 1 hora).
Prepare($sql )
Prepara (compila) un enunciado SQL para ejecutarse repetitivamente. Los parametros se
representan por ?, excepto para el driver oci8, que emplea el metodo usual de Oracle de
:varname.
Regresa un arreglo que contiene el enunciado SQL original como primera posicion, las
demas posiciones del arreglo varian para cada driver. Si hubo un error o se esta emulando
el Prepare( ), se regresa la cadena $sql original. Esto es porque todo el manejo de errores se
hace en el Execute().
Prepare( ) no puede ser usado en funciones que usan la tecnica de modificar el enunciado
SQL como PageExecute( ) y SelectLimit( ).
Ejemplo:
$stmt = $conn->Prepare('insert into table (col1,col2) values (?,?)');
for ($i=0; $i < $max; $i++)
$conn->Execute($stmt,array((string) rand(), $i));

Tambien revisa InParameter(), OutParameter() y PrepareSP(). Solo esta soportado


internamente por interbase, oci8 y algunos drivers basados en ODBC, en los demas casos es
emulado. No hay ninguna ganancia en el rendimiendo usando Prepare() emulados.
Importante: Debido a las limitaciones o fallas en el PHP, si tienes errores al ejecutar SQLs
preparados, pon $ADODB_COUNTRECS = false antes de prepararlos. Esto ha sido
observado con ODBC.

IfNull($field, $nullReplacementValue)
Funcion IFNULL compatible (NVL para Oracle). Regresa una cadena de caracteres que
representa la funcion que verifica si $field es nulo (NULL), y si lo es, le cambia el valor
regresado por $nullReplacementValue. Ej.
$sql = 'SELECT '.$db->IfNull('name', "'- unknown -'"). ' FROM table';

length
No es una funcion sino una propiedad. Algunas bases de datos tiene la funcion "length" y
otras "len" para medir la longitud de una cadena. Para usar la propiedad:
$sql = "SELECT ".$db->length."(field) from table";
$rs = $db->Execute($sql);

random
Tampoco es una funcion sino una propiedad. Contiene la cadena que representa a la
funcion sql que genera un numero aleatorio entre 0.0 y 1.0 inclusive.
substr
Tambien es una propiedad. Algunas bases de datos tienen la funcion "substr" y otras la
funcion "substring" para recuperar parte de una cadena. Ejemplo de uso:
$sql = "SELECT ".$db->substr."(field, $offset, $length) from table";
$rs = $db->Execute($sql);

Para todas las bases de datos, el primer parametro de substr es el campo, el segundo es el
desplazamiento (1 es el principio) para empezar la sub-cadena, y el tercero es el largo.
Param($name)
Genera el caracter para marcar la posicion de los parametros. En la mayoria de las bases
de datos el caracter es "?". Sin embargo algunas bases de datos usan marcadores con
nombre, Oracle por ejemplo usa ":somevar". Estos nos permite definir enunciados SQL
con parametros que sean compatibles.
$sql = 'insert into table (col1,col2) values ('.$conn->Param('a').','.$conn>Param('b').')';
# genera 'insert into table (col1,col2) values (?,?)'
# o
'insert into table (col1,col2) values (:a,:b)'
$stmt = $conn->Prepare($sql);
$stmt = $conn->Execute($stmt,array('one','two'));

PrepareSP($sql, $cursor=false )

Al llamar procedimientos almaceneados (SP) de mssql y oci8 (oracle), PrepareSP() nos


permite ligar directamente a un parametro que regresa un valor, o el manejo especial de
LOBs.
Regresa el mismo arreglo o cadena $sql como el Prepare( ). Si NO se necesita ligar a un
valor de salido, se deberia de usar Prepare().
El segundo parametro, $cursor solo se usa con oci8. Con valor true provoca que se llame a
OCINewCursor; esto para el manejo de REF CURSOR.
Para ejemplos del uso de PrepareSP( ), vea InParameter( ) a continuacion.
Nota: en el driver de mssql, preparar procedimientos almacenados requiere que se llame a
una funcion especial, mssql_init( ), la cual es invocada por esta funcion. PrepareSP( ) esta
disponible en todos los drivers y es emulado invocando a Prepare( ).
InParameter($stmt, $var, $name, $maxLen = 4000, $type = false )
Liga una variable PHP como entrada a una variable del procedimiento almacenado. El
parametro $stmt es el valor que regreso PrepareSP(), $var es la variable PHP a ligar,
$name es el nombre de la variable del procedimiento almacenado. $maxLen es opcional y es
la longitud maxima de los datos a ligar y $type depende de cada base de datos. Consulte la
documentacion de mssql_bind y ocibindbyname en php.net para mas informacin de los
valores autorizados de $type.
InParameter() es una funcion envolvente que llama Parameter() con $isOutput=false. La
ventaja de esta funcion es que es auto descriptiva, debido a que ya no es necesario el
parametro $isOutput. Actualmente solo para mssql y oci8.
Un ejemplo usando oci8:
# Para Oracle, Prepare y PrepareSP son identicos
$stmt = $db->PrepareSP(
"declare RETVAL integer;
begin
:RETVAL := SP_RUNSOMETHING(:myid,:group);
end;");
$db->InParameter($stmt,$id,'myid');
$db->InParameter($stmt,$group,'group',64);
$db->OutParameter($stmt,$ret,'RETVAL');
$db->Execute($stmt);

Este mismo ejemplo usando mssql:


# @RETVAL = SP_RUNSOMETHING @myid,@group
$stmt = $db->PrepareSP('SP_RUNSOMETHING');
# Observa que el nombre de parametro no tiene @ al principio!
$db->InParameter($stmt,$id,'myid');
$db->InParameter($stmt,$group,'group',64);

# El valor de salida en mssql, RETVAL, es un nombre fijo


$db->OutParameter($stmt,$ret,'RETVAL');
$db->Execute($stmt);

Tome en cuenta que la unica diferencia entre la implementacion de oci8 y mssql es $sql.
En mssql si el parametro $type tiene valor false, $type se determinara dinamicamente en
base al tipo de variable PHP proporcionada. (string => SQLCHAR, boolean
=>SQLINT1, integer =>SQLINT4 o float/double=>SQLFLT8).
Para oci8, $type puede ser OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File),
OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) y OCI_B_ROWID
(ROWID). Para pasar NULL hay que usar $db->Parameter($stmt, $null=null,
'param').
OutParameter($stmt, $var, $name, $maxLen = 4000, $type = false )
Liga una variable PHP con la salida de una variable de un procedimiento almacenado. El
parametro $stmt es el valor que regreso PrepareSP(), $var es la variable PHP que se se
desea ligar, $name es el nombre de la variable del procedimiento almacenado.
Opcionalmente, $maxLen es la longitud maxima de datos a ligar, y $type que depende de
cada base de datos.
OutParameter() es una funcion envolvente que llamada Parameter() con $isOutput=true.
La ventaja de esta funcion es que es auto descriptiva, debido a que ya no es necesario el
parametro $isOutput. Actualmente solo para mssql y oci8.
Para un ejemplo vea InParameter.
Parameter($stmt, $var, $name, $isOutput=false, $maxLen = 4000, $type = false )
Observacion: Esta funcion esta descontinuada, debido a las nuevas funciones InParameter()
y OutParameter(). Estas son mejores porque son auto descriptivas.
Agrega un parametro adecuado para regresar valores o el manejo especial de datos (ej,
LOBs) despues de que el enunciado ha sido preparado con PrepareSP(). Actualmente solo
para mssql y oci8. Los parametros son:
$stmt Enunciado regresado por Prepare() o PrepareSP().
$var Variable PHP a ligar. Asegurarse de inicializarla!
$name Nombre de la variable del procedimiento almacenado a ligarse.
[$isOutput] Indica el sentido del parametro, 0/false=Entrada 1=Salida 2= Entrada/Salida.
Se ignora en el driver oci8 ya que este auto detecta el sentido.
[$maxLen] Longitud maxima de la variable.
[$type] Consulta mssql_bind y ocibindbyname en php.net para mas informacion de los
valores legales de $type.

Por ultimo, para oci8, los parametros pueden ser reusados sin llamar nuevamente a
PrepareSP( ) o Parameters. Esto no es posible con mssql. Un ejemplo con oci8:
$id = 0; $i = 0;
$stmt = $db->PrepareSP( "update table set val=:i where id=:id");
$db->Parameter($stmt,$id,'id');
$db->Parameter($stmt,$i, 'i');
for ($cnt=0; $cnt < 1000; $cnt++) {
$id = $cnt;
$i = $cnt * $cnt; # Funciona para oci8!
$db->Execute($stmt);
}

Bind($stmt, $var, $size=4001, $type=false, $name=false)


Esta es una funcion de bajo nivel manejada unicamente por el driver de oci8. Evite usarla a
menos que unicamente desea dar soporte a Oracle. La funcion Parameter( ) es el metodo
recomendado para ligar variables.
Bind( ) nos permite ligar variables en el enunciado sql. Liga la variable PHP a un nombre
definido en el enunciado SQL de Oracle que fue previamente preparado usando Prepare().
Las variables nombradas de Oracle empiezan con dos puntos (:), y ADOdb necesita que las
variables se llamen :0, :1, :2, :3, etc. La primera vez que se invoque Bind() tomara :0, la
segunda invocacion tomara :1, etc. El uso de Bind() puede proporcionaar un 100% de
incremento de velocidad para enunciados insert, select y update.
Los otros parametros, $size asigna el tamao de memoria para almacenamiento de datos,
$type puede tener los valores OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File),
OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) y OCI_B_ROWID
(ROWID). Por ultimo, en lugar de usar los nombres :0, :1, etc., se pueden definir los
nombres a ligar usando $name.
El siguiente ejemplo usa tres variables a ligar: p1, p2 y p3. Estas variables se ligan a :0, :1 y
:2.
$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:0, :1,
:2)");
$DB->Bind($stmt, $p1);
$DB->Bind($stmt, $p2);
$DB->Bind($stmt, $p3);
for ($i = 0; $i < $max; $i++) {
$p1 = ?; $p2 = ?; $p3 = ?;
$DB->Execute($stmt);
}

Tambien se puede usar variables con nombre:


$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:nombre0,
:nombre1, :nombre2)");
$DB->Bind($stmt, $p1, "nombre0");

$DB->Bind($stmt, $p2, "nombre1");


$DB->Bind($stmt, $p3, "nombre2");
for ($i = 0; $i < $max; $i++) {
$p1 = ?; $p2 = ?; $p3 = ?;
$DB->Execute($stmt);
}

LogSQL($enable=true)
Llama este metodo para instalar el sistema de registro y medicion de enunciados SQL
(usando fnExecute). Todos los enunciados SQL seran registrados en la tabla adodb_logsql
de la base de datos. Si la tabla no existe, ADOdb la creara si tienes los premisos necesarios.
Regresa el estado previo de registro (true para habilitado, false para desabilitado). Este un
ejemplo del DDL para algunas bases de datos:
mysql:
CREATE TABLE adodb_logsql (
created datetime NOT NULL,
sql0 varchar(250) NOT NULL,
sql1 text NOT NULL,
params text NOT NULL,
tracer text NOT NULL,
timer decimal(16,6) NOT NULL
)
postgres:
CREATE TABLE adodb_logsql (
created timestamp NOT NULL,
sql0 varchar(250) NOT NULL,
sql1 text NOT NULL,
params text NOT NULL,
tracer text NOT NULL,
timer decimal(16,6) NOT NULL
)
mssql:
CREATE TABLE adodb_logsql (
created datetime NOT NULL,
sql0 varchar(250) NOT NULL,
sql1 varchar(4000) NOT NULL,
params varchar(3000) NOT NULL,
tracer varchar(500) NOT NULL,
timer decimal(16,6) NOT NULL
)
oci8:
CREATE TABLE adodb_logsql (
created date NOT NULL,
sql0 varchar(250) NOT NULL,
sql1 varchar(4000) NOT NULL,
params varchar(4000),
tracer varchar(4000),
timer decimal(16,6) NOT NULL
)

Uso:
$conn->LogSQL(); // Habilita el registro
:
$conn->Execute(...);
:
$conn->LogSQL(false); // deshabilita el registro
# Muestra un resumen de los resultados del registro
$perf = NewPerfMonitor($conn);
echo $perf->SuspiciousSQL();
echo $perf->ExpensiveSQL();

Una limitante del registro es que el 'rollback' de la transaccion tambien impide que el
enunciado SQL se registre.
Si deseas otro nombre para la tabla a utilizar para almacenar los SQL, tendras que invocar
adodb_perf::table($tablename), donde $tablename es el nuevo nombre de la tabla (tu
tendras que crear la tabla manualmente). Un ejemplo:
include('adodb.inc.php');
include('adodb-perf.inc.php');
adodb_perf::table('my_logsql_table');

Tambien ve los manuales Monitor de rendimiento.


Propiedades fnExecute y fnCacheExecute
Estas dos propiedades nos permiten definir funciones de 'cuello de botella' para todos los
enunciados SQL procesados por ADOdb. Nos permite realizar estadisticas y reescritura de
los enunciados SQL.
Ejemplos de fnExecute
A continuacion un ejemplo del uso de fnExecute para contar todos los queries con cache y
sin cache:
# $conn es el objeto de conexion
function CountExecs($conn, $sql, $inputarray)
{
global $EXECS;
if (!is_array(inputarray)) $EXECS++;
# Maneja arreglos bidimensionales
else if (is_array(reset($inputarray))) $EXECS += sizeof($inputarray);
else $EXECS++;
}
# $conn es el objeto de conexion
function CountCachedExecs($conn, $secs2cache, $sql, $inputarray)

{
global $CACHED; $CACHED++;
}
$conn = NewADOConnection('mysql');
$conn->Connect(...);
$conn->fnExecute = 'CountExecs';
$conn->fnCacheExecute = 'CountCachedExecs';
:
:
# Despues de muchos enunciados sql:`
printf("<p>Total de queries=%d; total en cache=%d</p>",$EXECS+$CACHED,
$CACHED);

La funcion fnExecute se llamada antes del que el sql sea examinado y ejecutado, por eso se
puede reescribir el query. Si mandas como parametro un enunciado preparado entonces
$sql es un arreglo (ver Prepare). La funcion fnCacheExecute se ejecuta unicamente si el
recordset se almacena en cache. Los parametros de la funcion coinciden con las funciones
Execute y CacheExecute, excepto que $this (el objeto conexion) se manda como primer
parametro.
Desde la version 3.91 de ADOdb 3.91, el comportamiento de fnExecute es diferente
dependiendo de si la funcion definida regresa un valor. Si no regresa ningun valor el
enunciado $sql se ejecuta como siempre. Esto es util para reescribir querys o para contar
ejecuciones.
Tambien puedes desear reemplazar la funcion Execute con una propia. En este caso, que tu
funcion regrese un valor. Si se obtiene un valor, el valor se regresa inmediatamente sin
ningun procesamiento. Esto lo uso ADodb internamente para implementar LogSQL().

Funciones de auxilio de ADOConnection


BlankRecordSet([$queryid])
Ya no esta disponible, se quito desde laversion 1.99.
Concat($s1,$s2,....)
Genera la cadena de caracteres para concatenar $s1, $s2, etc. Emplea el texto en la
propiedad concat_operator para generar la concatenacion. Omita la funcion si no se usa un
caracter de concatenacion, como en MySQL.
Regresa la cadena concatenada.
DBDate($date)

Formatea el campo $date en un formato fecha que la base de datos acepte. Se emplea en
enunciados INSERT/UPDATE; para enunciados SELECT emplee SQLDate. El parametro
$date puede ser un entero con la fecha Unix o una cadena en formato ISO Y-m-d. Emplea
la propiedad fmtDate que contiene el formato a emplear. Si le menda como parametro null
o false o '', genera un null de SQL.
Regresa la fecha como una cadena encomillada.
$sql = "select * from atable where created > ".$db->DBDate("$year-$month$day");
$db->Execute($sql);

BindDate($date)
Formatea la fecha ($date) en formato que la base de datos acepte para variables
posicionales. Normalmente esto significa que la cadena no se entre comilla.
$sql = "select * from atable where created > ".$db->Param('0');
// or
$sql = "select * from atable where created > ?";
$db->Execute($sql,array($db->BindDate("$year-$month-$day"));

DBTimeStamp($ts)
Formatea el registro de tiempo $ts en un formato que acepte la base de datos, puede ser un
entero de Unix o una cadena en el formato ISO Y-m-d H:i:s. Emplea el valor de la
propedad fmtTimeStamp, que contiene el formato a emplear. Si le menda como parametro
null o false o '', genera un null de SQL.
Regresa el registro de tiempo como una cadena encomillada.
$sql = "select * from atable where created > ".$db->DBTimeStamp("$year$month-$day $hr:$min:$secs");
$db->Execute($sql);

BindTimeStamp($ts)
Formatea el resgistro de tiempo $ts en formato de variable posicional para ser aceptado
por la base de datos. Esto casi siempre significa que la cadena no sera encomillada.
$sql = "select * from atable where created > ".$db->Param('0');
// or
$sql = "select * from atable where created > ?";
$db->Execute($sql,array($db->BindTimeStamp("$year-$month-$day
$hr:$min:$secs"));

qstr($s,[$magic_quotes_enabled=false])

Encierra entre comillas una cadena a ser enviada a la base de datos. Puede verse extrao el
parametro $magic_quotes_enabled, pero la idea es por si esta encomillando cadenas
obtenidas por POST o GET, se puede mandar get_magic_quotes_gpc() como el segundo
parametro. Esto nos asegura que la variable no se encomille dos veces, una por qstr y la
otra por magic_quotes_gpc.
Ej. $s = $db->qstr(HTTP_GET_VARS['name'],get_magic_quotes_gpc());
Regresa la cadena encomillada.
Quote($s)
Encierra entre comillas la cadena $s, protegiendo el caracter especifico de encomillado de
la base de datos. Anteriormente verificaba el estado de 'magic quotes', pero se deshabilito
desde la version 3.31 para que sea compatible con el paquete DB de PEAR.
Affected_Rows( )
Regresa el numero de renglones afectados por un enunciado update o delete. Regresa falso
si la funcion no esta soportada.
Actualmente no esta soportada para interbase/firebird.
Insert_ID( )
Regresa el ultimo identificador de numeracion automatico insertado (serial). Regresa falso
si la funcion no esta soportada.
Unicamente soportado por bases de datos que manejan auto incrementos o identificador de
objetos (OID) como PostgreSQL, actualmente MySQL y MS SQL Server. PostgreSQL
regresa el OID, que puede cambiar en una recarga de la base de datos.
RowLock($table,$where)
Asegura el renglon de una tabla por la duracion de la transaccion. Por ejemplo, para
asegurar el renglon $id de la tabla 'table1':
$DB->StartTrans();
$DB->RowLock("table1","rowid=$id");
$DB->Execute($sql1);
$DB->Execute($sql2);
$DB->CompleteTrans();

Funciona en db2, interbase, informix, mssql, oci8, postgres, sybase.


MetaDatabases()

Regresa un arreglo con la lista de bases de datos disponibles en el servidor. Debes de estar
conectado al servidor. Solo disponible para ODBC, MySQL y ADO.
MetaTables($ttype = false, $showSchema = false, $mask=false)
Regresa un arreglo de las tablas y vistas de la base de datos actual. El arreglo omitira en lo
posible las tablas del sistema. Para unicamente mostar tablas use db>MetaTables('TABLES'). Para unicamente mostar vistas use $db->MetaTables('VIEWS').
Actualmente el parametro $showSchema solo funciona para DB2, y cuando es verdadero,
agerga el nombre del esquema a la tabla, ej. "SCHEMA.TABLE".
Se puede definir una mascara de coincidencia. Por ejemplo, con $mask = 'TMP%' solo
encontrara las tablas que empiecen con 'TMP'. Por lo pronto solo mssql, oci8, odbc_mssql
y postgres* manejan el parametro $mask.
MetaColumns($table,$toupper=true)
Regresa un arreglo de objetos de la clase ADOFieldObject, un objeto por cada columna de
la tabla $table. Cada instancia tiene definidos las propiedades (name, type, max_length).
Actualmente Sybase no reconoce los tipos de fecha y ADO no puede identificar el tipo
adecuado de datos (por lo que se identifican como 'varchar').
El parametro $toupper determina si hay que convertir a mayusculas el nombre de la tabla
(requerido por algunas bases de datos).
Para el manejo de esquemas, en el parametro $table mande el valor
"$schema.$tablename". Estos solo funciona en algunas bases de datos.
MetaColumnNames($table)
Regresa un arreglo con los nombres de las columnas de la tabla $table. Desde ADOdb 4.22,
es un arreglo asociativo con las llaves en mayusculas.
Es decir, array('FIELD1' => 'Field1', 'FIELD2'=>'Field2')
MetaPrimaryKeys($table, $owner=false)
Regresa un arreglo con el nombre de las columnas que forman la llave primaria de la tabla
$table. Actualmente manejado por mysql, odbc (including db2, odbc_mssql, etc), mssql,
postgres, interbase/firebird, oci8.
Las vistas (y algunas tablas) tienen llave primaria, pero algunas veces esta informacion no
esta disponible para la base de datos. Tu puedes definir una funcion
ADODB_View_PrimaryKeys($databaseType, $database, $view, $owner) que regrese el
arreglo conteniendo los campos que forman la llave primaria. Si esta funcion existe sera

invocada cuando MetaPrimaryKeys() no pueda encontrar la llave primaria para tabla o


vista.
// En este ejemplo: dbtype = 'oci8', $db = 'mydb', $view = 'dataView', $owner
= false
function ADODB_View_PrimaryKeys($dbtype,$db,$view,$owner)
{
switch(strtoupper($view)) {
case 'DATAVIEW': return array('DATAID');
default: return false;
}
}
$db = NewADOConnection('oci8');
$db->Connect('localhost','root','','mydb');
$db->MetaPrimaryKeys('dataView');

ServerInfo($table)
Regresa un arreglo asociativo con dos elementos 'description' y 'version'. El elemento
'description' contiene una cadena con la descripcion de la base de datos. El elemento
'version' contiene una cadena con el numero de version.
MetaForeignKeys($table, $owner=false, $upper=false)
Regresa un arreglo asociativo con las llaves foraneas (foreign keys) de la tabla. o falso si no
esta soportado. Por ejemplo, si la tabla 'empleados' tiene una llave foranea
'empleados.empl_dept' apunta a 'departamentos.dept_clav', y
empleados.empl_puesto=organigrama.orga_puesto y
empleados.empl_cat=organigrama.orga_cat, entonces $conn>MetaForeignKeys('empleados') obtendra como resultado:
array(
'departamentos' => array('empl_dept=dept_clav'),
'organigrama' =>
array('empl_puesto=orga_puesto','empl_cat=orga_cat')
)

Opcionalmente el dueo de la tabla o vista se puede definir en $owner. Si $upper es


verdadero entonces el nombre de las tables (las llaves del arreglo) se convierten a
mayusculas.

ADORecordSet
Cuando se ejectuta satisfactoriamente un enunciado SQL con el metodo
ADOConnection->Execute($sql), se obtiene un objeto ADORecordSet. Este objeto
contiene: un cursor virtual para podernos mover de renglon en renglon, funciones para

obtener informacion acerca de las columnas y sus tipos de datos, y funciones auxiliares
para el formateo de los resultados para ser mostrados al usuario.

Campos/propiedades de ADORecordSet
fields: Arreglo que contiene el renglon actual. No es asociativo, sino un arreglo indexado
del 0 al (columnas - 1). Vea tambien la funcion Fields, que se comprota como un arreglo
asociativo.
dataProvider: El mecanismo subyacente empleado para conectarse a la base de datos.
Normalmete vale native, a menos que sea odbc o ado.
blobSize: Tamao maximo de un objeto char, string o varchar antes de que se considere
como un Blob (Los Blobs se deberan mostar en textareas). Vea la funcion MetaType
function.
sql: Contiene el enunciado sql empleado para generar este conjunto de datos.
canSeek: Con valor verdadero si la funcion Move( ) funciona..
EOF: Verdadero si se ha navegado el cursor despues del ultimo registro.

Funciones/metodos de ADORecordSet
ADORecordSet( )
Constructor. Normalmente nunca hay que llamar a esta funcion.
GetAssoc([$force_array])
Genera un arreglo asociativo del recordset. Observe que esta funcion tambien esta
disponible en el objeto de conexion. Mas detalles se pueden encontar ahi.
GetArray([$number_of_rows])
Genera un arreglo bidimensional de registros desde la position actual del cursor, indexado
desde 0 a ($number_of_rows - 1). Si no se define $number_of_rows, se indexa hasta el final
de recordset (EOF).
GetRows([$number_of_rows])
Genera un arreglo bidimensional de registros desde la posicion actual del cursor,
Sinomimo de GetArray() para tener compatibilidad con Microsoft ADO.
GetMenu($name, [$default_str=''], [$blank1stItem=true], [$multiple_select=false],
[$size=0], [$moreAttr=''])

Genera un menu HTML (<select><option><option></select>). La primera columna del


recordset (fields[0]) contiene el texto a desplegar en la etiqueta option. Si el recordset tiene
mas de 1 columna, la segunda columna (fields[1]) es el valor a enviar al servidor Web. La
variable del menu tendra el nombre $name.
Si esta definido $default_str, entonces si $default_str == fields[0], entonces ese campo se
selecciona. Si $blank1stItem es verdadero, la primera opcion esta en blanco. Tambien se le
puede poner un texto a la primera opcion con $blank1stItem = "$valor:$texto".
$Default_str puede ser un arreglo para una caja de opcion multiple.
Para obtener una caja, asignele a $size un valor diferente de cero (o mande $default_str
como un arreglo). Si $multiple_select es verdadero entonces se generara un caja con $size
elementos (o si $size==0, con 5 elementos) visibles, y se regresera un arreglo al servidor.
Finalmente emplee $moreAttr para agregar atributos adicionales como javascript o styles.
Ejemplo de Menu 1: GetMenu('menu1','A',true) genera el menu:
con los datos (A,1), (B,2), (C,3). Tambien vea el ejemplo 5.
Ejemplo de Menu 2: Con los mismo datos, GetMenu('menu1',array('A','B'),false)
generara un menu con A y B seleccionados:
GetMenu2($name, [$default_str=''], [$blank1stItem=true], [$multiple_select=false],
[$size=0], [$moreAttr=''])
Es casi indentica a GetMenu, excepto que $default_str se compara contra fields[1] (el valor
de la opcion).
Ejemplo de Menu 3: Con el conjunto de datos del ejemplo 1,
GetMenu2('menu1',array('1','2'),false) generara un menu con A y B seleccionados
como en el ejemplo 2, pero en esta ocasion la seleccion se baso en la segunda columna, que
contiene el valor a regresar al servidor Web.
UserDate($str, [$fmt])
Convierte la cadena de caracteres con una fecha $str a otro formato fecha. El formato de
fecha es Y-m-d o un timestamp de Unix. El valor por omision de $fmt es Y-m-d.
UserTimeStamp($str, [$fmt])
Convierte la cadena de caracteres con un timestamp $str a otro formato. El formato de
timestamp es Y-m-d H:i:s, como en '2002-02-28 23:00:12', o un timestamp de Unix.
UserTimeStamp llama a UnixTimeStamp para analizar $str. El valor por omision de $fmt
es to Y-m-d H:i:s.

UnixDate($str)
Analiza la cadena $str por una fecha y la regresa en el formato unix para mktime (es decir
un numero indicando el numero de segundos desde el 1 de enero de 1970). Supone que la
fecha tiene formato Y-m-d H:i:s, excepto para Sybase y Microsoft SQL Server, donde
tambien se acepta M d Y (El mes a 3 letras es controlado por un arreglo global que puede
necesitar tropicalizacion).
La funcion esta disponible tanto para ADORecordSet y ADOConnection desde 1.91.
UnixTimeStamp($str)
Analiza la cadena $str por un timestap y lo regresa en el formato unix para mktime (es
decir un numero indicando el numero de segundos desde el 1 de enero de 1970). Espera la
fecha en formato "Y-m-d, H:i:s" (1970-12-24, 00:00:00) o "Y-m-d H:i:s" (1970-12-24
00:00:00) o "YmdHis" (19701225000000), excepto para Sybase y Microsoft SQL Server,
donde tambien se acepta "M d Y h:i:sA" (Dec 25 1970 00:00:00AM), (El mes a 3 letras se
controla por un arreglo global que puede necesitar tropicalizacion).
La funcion esta disponible tanto para ADORecordSet y ADOConnection desde 1.91.
OffsetDate($dayFraction, $basedate=false)
Regresa una cadena con la funcion SQL nativa para calcular fechas futuras y pasadas en
base $basedate. Si $basedate no esta definida entonces se toma la fecha actual (a las 12 de la
noche). Regresa la cadena SQL que realiza los calculos cuando se procesa por Execute().
Por ejemplo, en Oracle, para encontrar la fecha que esta 2.5 dias en el futuro:
# obtener fecha una semana en el futuro
$fld = $conn->OffsetDate(7); // Regresa "(trunc(sysdate)+7")
# obtener fecha y hora que esta 60 horas en el futuro
$fld = $conn->OffsetDate(2.5, $conn->sysTimeStamp); // regresa
"(sysdate+2.5)"

Esta funcion esta disponible en los driverrs mysql, mssql, oracle, oci8 y postgresql desde
2.13. Puede funcionar con otros drivers siempre y cuando permitan aritmetica de fechas.
SQLDate($dateFormat, $basedate=false) Regresa una cadena que contiene la funcion SQL
nativa para formatear una fecha o el campo fecha $basedate. Es usado en enunciados
SELECT. Para enunciados INSERT/UPDATE use DBDate. Emplea un formato con
mayusculas/minusculas en $dateFormat, que maneja:
Y:
Q:
M:
m:
d:

Ao a 4 digitis
Trimestre (1-4)
Mes (Jan-Dec)
Mes (01-12)
Dia (01-31)

H:
h:
i:
s:
A:

Hora (00-23)
Hora (1-12)
Minuto (00-59)
Segundo (00-60)
Indicador de AM/PM

Todos los demas caracteres se tratan como cadena. Se puede usar \ para escapar
caracteres. Disponible en algunas bases de datos, incluyendo mysql, postgresql, mssql, oci8
y DB2.
Es util para escribir enunciados sql portable que hacen GROUP BY por fechas. Por
ejemplo para mostrar el costo total de los bienes vendidos por cada trimestre (las fecha
estan en el campo llamado postdate):
$sqlfn = $db->SQLDate('Y-\QQ','postdate'); # obtiene el sql que formatea
postdate
$sql = "SELECT $sqlfn,SUM(cogs) FROM table GROUP BY $sqlfn ORDER BY 1 desc";

MoveNext( )
Mueve el cursor al siguiente renglon. El arreglo $this->fields se actualiza automaticamente.
Regresa falso si no lo pudo hacer (normalmente debido a que se encontrol el EOF), en caso
contrario regresa verdadero.
Si se alcanzo el EOF, entonces el arreglo $this->fields tiene valor falso (esto funciona
consistentemente a partir de ADOdb 3.30). Para tener el comportamiento que habia antes
de la version 3.30 en $this->fields (en EOF), ponga la variable global
$ADODB_COMPAT_FETCH = true.
Ejemplo:
$rs = $db->Execute($sql);
if ($rs)
while (!$rs->EOF) {
ProcessArray($rs->fields);
$rs->MoveNext();
}

Move($to)
Mueve el cursor interno al renglon $to. En numero de renglon empieza en 0, es decir 0 es el
primer renglon. El arreglo fields es actualizado automaticamente. Para aquellas bases de
datos que no manejan internamente la navegacion, ADOdb simulara la navegacion para
adelante. Algunas bases de datos no manejan la navegacion para atras. Si $to esta despues
del EOF, $to se movera al final del RecordSet en la mayoria de las bases de datos. Algunas
bases de datos poco claras usando odbc pueden no comportarse de esta manera.

Observacion: Esta funcion emplea posicionamiento absoluto , a comparacion de Microsoft's


ADO.
Regresa verdadero o falso. Si es falso, el cursor interno no se mueve en la mayoria de las
implementaciones, en cuyo caso AbsolutePosition( ) regresara la ultima posicion del cursor
antes del Move( ).
MoveFirst()
Internamente invoca Move(0). Algunas bases de datos no manejan esta funcion.
MoveLast()
Internamente llama Move(RecordCount()-1). Algunas bases de datos no manejan esta
funcion.
GetRowAssoc($toUpper=true)
Regresa un arreglo asociativo conteniendo el renglon actual. Las llaves del arreglo son los
nombres de las columnas. El nombre de las columnas esta en mayusculas para facilitar el
acceso. Para obtener el siguiente renglon todavia es necesario invocar MoveNext().
Por ejemplo:
Array ( [ID] => 1 [FIRSTNAME] => Caroline [LASTNAME] => Miranda [CREATED] =>
2001-07-05 )
Nota: no use GetRowAssoc() con $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC.
debido a que tienen la misma funcionalidad e interfiere uno con el otro.
AbsolutePage($page=-1)
Regresa la pagina indicada. Requiere que se haya llamado PageExecute() o
CachePageExecute(). Ver Ejemplo 8.
AtFirstPage($status='')
Regresa verdadero si esta en la primera pagina, (en base a 1). Requiere que se haya
llamado a PageExecute() o CachePageExecute(). ver Ejemplo 8.
AtLastPage($status='')
Regresa verdadero si esta en la ultima pagina, (en base a 1). Requiere que se haya llamado
a PageExecute() o CachePageExecute(). ver Ejemplo 8.
Fields($colname)

Regresa el valor de la columna $colname. Al nombre de la columna no le afectan las


mayusculas.
Esta funcion solo esta por comodidad. Para un mejor rendimiento use
$ADODB_FETCH_MODE.
FetchRow()
Regresa un arreglo conteniendo el renglon actual, or falso si es EOF. Internamente
FetchRow( ) se mueve al siguiente renglon despues de regresar el renglon actual.
ADVERTENCIA: No mezcle FetchRow() con MoveNext().
Uso:
$rs = $db->Execute($sql);
if ($rs)
while ($arr = $rs->FetchRow()) {
# process $arr
}

FetchInto(&$array)
Pone en el arreglo $array el renglon actual. Regresa un objeto PEAR_Error si EOF, 1 si es
correcto (la constante DB_OK). Si PEAR no esta definido regresa falso cuando encuentra
EOF. Internamente FetchInto() se mueve al siguiente registro despues de regresar el
renglon actual.
Es mas facil de usar FetchRow(). Vea arriba.
FetchField($column_number)
Regresa un objeto conteniendo name, type and max_length de el campo solicitado. Si
max_length no se pueden determinar con confianza, tendra el valor de -1. El numero de
columna esta en base a cero (la primer columna es 0). Ver el ejemplo 2.
FieldCount( )
Regresa el numero de campos (columnas) en el recordset.
RecordCount( )
regresa el numero de renglones en el recordset. Si el numero de registros obtenidos no se
puede determinar del API de la base de datos, se leeran todos los renglones para poderse
contar. Esta lectura puede ser deshabilitada (por rendimiento) asignandole la variable
$ADODB_COUNTRECS = false. Cuando esta deshabilitada, RecordCount( ) regresara -1

en algunas bases de datos. Vea arriba la lista de bases de datos soportadas para mas
detalle.
RowCount es un sinonimo de RecordCount.
PO_RecordCount($table, $where)
Regresa el numero de registros en el recordset. Si la base de datos no lo maneja, ejecutara
un SELECT COUNT(*) en la tabla $table, con el criterio dado $where, para obtener una
estimacion del tamao del recordset.
$numrows = $rs->PO_RecordCount("articles_table", "group=$group");
NextRecordSet()
Para las bases de datos que permiten que un query regrese varios recordsets, esta funcion
permite cambiarse al siguiente recordset. Unicamente soportada para el driver de mssql.
$rs = $db->Execute('execute return_multiple_rs');
$arr1 = $rs->GetArray();
$rs->NextRecordSet();
$arr2 = $rs->GetArray();

FetchObject($toupper=true)
Regresa el renglon actual como un object. Si se manda $toupper = true, entonces los
campos de los objetos estaran en mayusculas. Nota. La nueva funcion FetchNextObject() es
el metodo recomendado para accesar los renglones como objetos. Vea a continuacion.
FetchNextObject($toupper=true)
Obtiene el renglon actual como un objeto y automaticamente avanza al siguiente renglon.
Regresa falso si esta al final del archivo (EOF). Si se manda $toupper = true, entonces los
campos del objeto estaran en mayusculas.
$rs = $db->Execute('select firstname,lastname from table');
if ($rs) {
while ($o = $rs->FetchNextObject()) {
print "$o->FIRSTNAME, $o->LASTNAME<BR>";
}
}

Hay una concesion en la velocidad por usar FetchNextObject(). Si el rendimiento es


importante, se deben de accesar los renglones con el arreglo fields[].
FetchObj()

Regresa el renglon actual como un objeto. Los nombres de los campos no se convierten a
mayusculas al contrario de FetchObject.
FetchNextObj()
Regresa el renglon actual como un objeto y se mueve al siguiente registro. Si hay EOF
regresa falso. Los campos no se convierten a mayusculas al contrario de FetchNextObject.
CurrentRow( )
Regresa el numero del renglon actual, Regresa 0 si es el primer renglon.
AbsolutePosition( )
Sinonimo de CurrentRow para compatibilidad con ADO. Regresa el numero del renglon
actual. 0 si es el primer renglon.
MetaType($nativeDBType[,$field_max_length],[$fieldobj])
Determina el meta tipo generic del tipo de campo nativo $nativeDBType de la base de
datos, y la longitud del campo $field_max_length. Toma en cuenta que field_max_length
puede ser -1 si no es conocido. El objeto del campo regresado por FetchField() puede ser
pasado a $fieldobj o como el primer parametro $nativeDBType. Es util para bases de datos
como mysql que tienen propiedades adicionales en el objeto de campo como primary_key.
Emplea el campo blobSize y lo compara con $field_max_length para determinar si campo
caracter es realmente un blob. Por ejemplo, $db->MetaType('char') will return 'C'.
Regresa:

C: Campo caracter que debe ser mostrador en una etiqueta <input type="text">.
X: Clob (character large objects), o campos de textos largos que deberia de ser
mostrado en <textarea>
D: Campo fecha
T: Campo Timestamp o datetime
L: Campo logico (boleano o de bit)
N: Campo numerico. Incluye decimal, numeric, punto flotante, y real.
I: Campo entero.
R: Campo contador o auto-incremento. Debe de ser numerico.
B: Blob o binario objeto largo.

Desde ADOdb 3.0, MetaType acepta $fieldobj como el primer parametro, en lugar de
$nativeDBType.
Close( )

Cierra el recordset, limpia toda la memoria y recursos asociados con el recordset.


Si no se esta usando la administracion de memoria, no hay necesidad de llamar a esta
funcion ya que los recordset son cerrados por PHP al final del script. Los enunciados SQL
como INSERT/UPDATE/DELETE no regresan realmente un recordset, por lo que no hay
que llamar a Close() para esos enunciados SQL.

function rs2html($adorecordset,[$tableheader_attributes], [$col_titles])


Esta es una funcion independiente (rs2html = recordset a html) que es similar a la funcion
PHP odbc_result_all, imprime un ADORecordSet, $adorecordset como una tabla HTML.
El parametro $tableheader_attributes nos permite controlar los atributos de la tabla
(cellpadding, cellspacing y border). Finalmente se puede reemplazar el nombre de las
columnas de la base de datos con nuestros propios titulos con el arreglo $col_titles. Esta
diseado mas como un mecanismo rapido de depuracion, no como un visor de recordsets
en un sistema en produccion.
Se necesita incluir el archivo tohtml.inc.php.
Ejemplo de rs2html:
<?
include('adodb/tohtml.inc.php'); # Carga el codigo de ADOdb
include('adodb/adodb.inc.php'); # Carga el codigo de ADOdb
$conn = &ADONewConnection('mysql');
# crea la conexion
$conn->PConnect('localhost','userid','','agora');# se conecta a agora db
$sql = 'select CustomerName, CustomerID from customers';
$rs
= $conn->Execute($sql);
rs2html($rs,'border=2 cellpadding=3',array('Customer Name','Customer ID'));
?>

Diferencias entre la libreria ADOdb y Microsoft ADO


1. ADOdb unicamente maneja recordsets creados por el objeto conexion. Los
recordsets no pueden ser creados independientemente.
2. Las propiedades de ADO se implementan como funciones en ADOdb. Esto hace mas
sencillo de implementar cualquier funcionalidad mejorada de ADO en el futuro.
3. La funcion ADORecordSet->Move() de ADOdb emplea posicionamiento
absoluto, no relativo. Los bookmarks no estan soportados.
4. ADORecordSet->AbsolutePosition() no puede ser usada para mover el
cursor del registro.
5. Los objetos de parametros de ADO no estan soportados. En su lugar existe la
funcion ADOConnection::Parameter( ), la cual proporciona una interfase mas

sencilla para nombrar parametros preparados e invocar procedimientos


almacenados.
6. Las propiedades del recordset para paginacion estan disponibles, pero
implementados como en el Ejemplo 8.

Guia para crear manejadores de bases de


datos
Aqui se describe como crear una clase para conectarse a una nueva base de datos. Para
asegurarse que no hay duplicidad de trabajo, por favor mandemelo por correo a
jlim#natsoft.com.my si decies crear una de esas clases.
Primero decide en un nombre en minusculas para noombrar al tipo de la base de datos.
Digamos que se va a llamar 'xbase'.
Entonces hay que crear dos clases ADODB_xbase y ADORecordSet_xbase en el archivo
adodb-xbase.inc.php.
La manera mas sencilla de crear un driver de base de datos es adaptando un driver ODBC
existente. Entonces solo tenemos que crear una clase ADODB_xbase extends ADODB_odbc
que maneja los formatos de date y timestamp, el operador de concatenacion , true y false.
Para la clase ADORecordSet_xbase extends ADORecordSet_odbc se necesita cambiar la
funcion MetaType. Para un ejemplo ver adodb-vfp.inc.php.
Los mas complicado es un driver nuevo que se conecta a una extension de PHP nueva. En
ese caso necesitaras implementar varias funciones, Afortunadamente, no tienes que
modificar la mayoria del codigo comlejo. Unicamente necesitas reescribir algunas
funciones prototipo. Ve adodb-mysql.inc.php para un ejemplo.
El formato por default de ADOdb es internamente YYYY-MM-DD (Ansi-92). Todas las
fechas se deben de convertir a ese formato cuando se pasen a una funcion ADOdb de fecha.
Ve el ejemplo de Oracle que usa ALTER SESSION para cambiar el formato de fecha en
_pconnect y _connect.
Funciones en ADOConnection a Sobreescribir
La definicion de un constructor para la funcion ADOConnection derivada es opcional. No
hay necesidad de llamar el conctructor de la clase base.
_connect: Implementacion de bajo nivel del Connect. Regresa true o false. Debe de asignar
_connectionID.

_pconnect: Implementacion de bajo nivel de PConnect. Regresa true o false. Debe de


asignar _connectionID.
_query: Ejecuta un enunciado SQL. Regresa queryID, o false.
_close: Cierra la conexion -- PHP debe de limpiar todos los recordsets.
ErrorMsg: Almacena el mensaje de error en la variable privada _errorMsg.
Campos de ADOConnection a inicializar
_bindInputArray: Con valor true si se permite la liga (binding) de parametros para
enunciados SQL de insert y update usando ?.
fmtDate
fmtTimeStamp
true
false
concat_operator
replaceQuote
hasLimit maneja SELECT * FROM TABLE LIMIT 10 de MySQL.
hasTop maneja el estilo de Microsoft SELECT TOP 10 * FROM TABLE.
Funciones de ADORecordSet a sobreescribir
Se necesita crear un constructor de tu clase derivada de ADORecordSet que invoque al
constructor de la clase padre.
FetchField: como se documento anteriormente en ADORecordSet
_initrs: inicializacion de bajo nivel del recordset: inicializa los campos _numOfRows y
_numOfFields -- invocada por el constructor.
_seek: busca un registro en particular. No carga los datos en el arreglo de campos. Eso lo
hace _fetch. Regresa true o false. Observe que algunas implementaciones como Interbase
no manejan seek. Poner canSeek a false.
_fetch: Obtiene un renglon usando la funcion de la extension de la base de datos y avanza
al siguiente renglon. Carga el arreglo fields. Si el parametro $ignore_fields es true entonces

no hay necesidad de cargar el arreglo fields, solo se mueve al siguiente renglon. Regresa
true o false.
_close: Cierra el recordset
Fields: es el arreglo regresado por la extension PHP no es un arreglo asociativo, tendras
que reescribirlo. Ve adodb-odbc.inc.php para un ejemplo. Para bases de datos como
MySQL y MSSQL donde se obtiene un arreglo asociativo, no hay necesidad de reescribir la
funcion.
Campos de ADOConnection a inicializar
canSeek: Con valor true si la funcion _seek funciona.

Você também pode gostar