Perl y DBI

Para efectuar acceso a bases datos a través de la web utilizando el lenguaje de programación Perl, se hace uso de una librería incorporada en el mismo, que facilita la programación sobre bases de datos. Se trata de la librería DBI (Data Base Interface). Con el DBI de Perl, podremos acceder a cualquier base de datos (al ser independiente de la base de datos con la que se esté trabajando), y con solo unas pocas líneas de código.

En esta página le mostramos una breve introducción al mismo, mostrándole sus objetos y métodos más importantes.

Lectura del módulo DBI y conexión a la base de datos

Para poder hacer uso de DBI, lo primero que hay que hacer en nuestro script de Perl, es leer el módulo DBI en la cabecera del mismo. Para ello usaremos la sentencia:

use DBI;

Después, y para cualquier tarea que se desee realizar, hay que abrir una conexión con la base de datos. La información que se utiliza para establecer la conexión es:

  • Nombre de la fuente de datos: Cadena que contiene los siguientes elementos, separados por dos puntos:
    • dbi
    • Nombre del driver. Por ejemplo: odbc, mysql, etc.
    • Nombre de la base de datos.
  • Usuario: Nombre del usuario que se va a conectar a la base de datos. En nuestros Planes de Alojamiento Web, el nombre de usuario coincide con el nombre de la base de datos.
  • Password: Contraseña de acceso a la base de datos.
  • Host (OPCIONAL): Máquina donde está la base de datos.
  • Puerto (OPCIONAL): Puerto que se va a usar para conectarse a la base de datos.

Una vez se ha terminado de trabajar con la base de datos se debe cerrar la conexión con la misma, algo no estrictamente necesario, pero si aconsejable, ya que algunas bases de datos pueden no terminar sus transacciones correctamente.

Ejemplo:

Veamos un ejemplo de un script en Perl que conecta y desconecta a un sistema de bases de datos MySQL:

#Usamos las librerías de acceso a BD
use DBI;

my $host="servidor"; #Servidor donde se aloja la base de datos
my $base_datos="basedatos";  #Nombre de las base de datos
my $usuario="basedatos";  #Usuario de la BD
my $clave="password";  #Password de la BD
my $driver="mysql";  #Utilizamos el driver de mysql

#Conectamos con la BD. Si no podemos, mostramos un mensaje de error
my $dbh = DBI-> connect ("dbi:$driver:database=$base_datos;
host=$host", $usuario, $clave)
|| die "nError al abrir la base datos: $DBI::errstrn";

# ################################ #
# Operaciones con la base de datos #
# ################################ #

#Nos desconectamos de la BD. Mostramos un mensaje en caso de error
$dbh-> disconnect ||
warn "nFallo al desconectar.nError: $DBI::errstrn";

Consultas sobre la base de datos

Una de las tareas más comunes en un script en Perl con acceso a base de datos, es obtener datos de la misma. Para las consultas sobre bases de datos en Perl, se utiliza el lenguaje estándar SQL.

El proceso de obtener datos usando DBI se divide en cuatro etapas:

  1. Preparación. En esta etapa se analiza y valida la sentencia SQL y se devuelve un manejador de sentencia representando la consulta en la base de datos. Se utiliza el método prepare (con la consulta SQL como parámetro) del manejador de la base de datos, devolviendo el manejador de la sentencia.
  2. Ejecución. En esta etapa se ejecuta el manejador de sentencia obtenido en la etapa anterior. Se hace la consulta y se almacenan los datos en las estructuras de datos correspondientes de la base de datos, aunque en esta etapa, el script en Perl no puede acceder a los datos obtenidos. Se utiliza el método execute del manejador de sentencia.
  3. Extracción. En esta etapa se extraen los datos de la base de datos usando el manejador de sentencia. Se almacenan los datos consultados, en las estructuras de datos de Perl, para que sean posteriormente manipulados por el script.
  4. Liberación. En esta fase se liberan los recursos ocupados por el manejador de sentencia y por la base de datos. Se utiliza el método finish del manejador de sentencia.

Ejemplo

Veamos un ejemplo donde se realiza una consulta para obtener información de la base de datos:

#Usamos las librerías de acceso a BD
use DBI;

my $host="servidor"; #Servidor donde se aloja la base de datos
my $base_datos="basedatos";  #Nombre de las base de datos
my $usuario="basedatos";  #Usuario de la BD
my $clave="password";  #Password de la BD
my $driver="mysql";  #Utilizamos el driver de mysql

#Conectamos con la BD. Si no podemos, mostramos un mensaje de error
my $dbh = DBI-> connect ("dbi:$driver:database=$base_datos;
host=$host", $usuario, $clave)
|| die "nError al abrir la base datos: $DBI::errstrn";

#Mostramos aviso en caso de éxito
print "nSe ha conectado con la BD $base_datos del driver $drivern";

#Realizamos la etapa de preparación de la sentencia
my $sth = $dbh->prepare("SELECT id,nombre FROM articulos;");

#Realizamos la etapa de ejecución de la sentencia
$sth->execute();

#Realizamos la etapa de extracción de datos. Mostramos los registros.
while ( @registro=$sth->fetchrow_array()) {
print "Id:$registro[0]  Nombre: $registro[1]n";
}

#Realizamos la etapa de liberación de recursos
$sth->finish();

#Nos desconectamos de la BD. Mostramos un mensaje si hay fallo
$dbh->disconnect || warn "nFallo al desconectar.nError: $DBI::errstrn";

La clase DBI y los manejadores de sentencia y base de datos: métodos y propiedades principales

Como hemos comentado, DBI hace uso de una serie de “objetos” para el manejo de bases de datos y sentencias. Le mostramos a continuación una referencia rápida de ayuda a los métodos y atributos más importantes de los mismos para su consulta.

Métodos generales de la clase DBI

Nombre Descripción Ejemplo
connect Establece una conexión con la base de datos especificada, devolviendo un manejador de base de datos.
En el primer parámetro, los campos de ‘$nombrehost’ (nombre de máquina) y ‘$puerto’ (número de puerto) son opcionales.
$dbhandle = DBI -> connect (DBI: $driver: $basedatos: $nombrehost: $puerto, $usuario, $password);
available_drivers Devuelve un array con los drivers disponibles.
Si alguno de los drivers está oculto por algún driver de igual nombre, muestra un aviso, que se puede eliminar llamando a la función con el parámetro opcional ‘$silencio’ con valor 1.
@drivers = DBI -> available_drivers($silencio);
data_sources Devuelve un array con las bases de datos disponibles para el driver indicado. @datasources = DBI -> data_sources($driver);
trace Ofrece información de seguimiento (traza) sobre DBI.
‘$trace_level’ puede tomar el valor 0 (sin traza), 1 (traza normal) o 2 (traza detallada).
El parámetro ‘$trace_file’ especifica un archivo y es opcional. Si se indica, el resultado de la traza se almacena en el mismo.
DBI -> trace($trace_level, $trace_file);
neat Devuelve una representación formateada del contenido del parámetro ‘$value’, y truncada a ‘$maxlen’ caracteres.
Se usa internamente por el DBI para el seguimiento (trace). NO usar para dar formato a cadenas para su uso en la base de datos.
$neatvalue = DBI::neat($value, $maxlen);
neat_list Llama a DBI::neat para cada elemento de ‘@listref’ y devuelve una cadena con los resultados unidos por ‘$separador’ y truncada a ‘$maxlen’ caracteres.
NO debe ser usada para formatear valores para usarlos en la base de datos.
$neat_list = DBI::neat_list(@listref, $maxlen, $separador);
dump_results Extrae todos los registros de una manejador de sentencia ($sth), llama a la función DBI::neat_list para cada registro y escribe el resultado en el descriptor de fichero ($fh), que por defecto es STDOUT (salida estándar -pantalla-).
El separador de línea ($lsep) es por defecto ‘n’, el separador de campos ($fsep) es por defecto ‘,’ y la máxima longitud ($maxlen) es 35.
$rows = DBI::dump_results($sth, $maxlen, $lsep, $fsep, $fh);

Propiedades de la clase DBI

Nombre Descripción Ejemplo
$DBI::err Obtiene el código de error devuelto por la base de datos, según la última función del driver ejecutada.
Es equivalente al método general de manejador: ‘err’
$error_code = $DBI::err;
$DBI::errstr Devuelve el mensaje de error devuelto por la base de datos, según la última función del driver ejecutada.
Es equivalente al método general de manejador: ‘errstr’
$error_string = $DBI::errstr;
$DBI::state Devuelve el código de error SQLSTATE.
Es equivalente al método general de manejador: ‘state’
$error_state = $DBI::state;

Métodos generales de los manejadores

Nombre Descripción Ejemplo
err Obtiene el código de error devuelto por la base de datos, según la última función del driver ejecutada. $error_code =
$dbhandler -> err;
errstr Devuelve el mensaje de error devuelto por la base de datos, según la última función del driver ejecutada. $error_string =
$dbhandler-> errstr;
state Devuelve el código de error SQLSTATE. $estado =
$dbhandler -> state;
trace Similar a DBI:trace, excepto que solo muestra la traza del manejador que esté siendo utilizado. $traza = $dbhandler -> trace($trace_level);

Propiedades de los manejadores

Nombre Descripción Ejemplo
Warn Activa mensajes de aviso útiles. Está habilitado por defecto . $dbhandler ->{Warn} = 1;
PrintError Atributo usado para forzar a los errores a generar mensajes de aviso además de los códigos de error. Por defecto DBI->connect tiene activado PrintError. $dbhandler ->{PrintError} = 1;
RaiseError Usado para obligar a los errores a crear excepciones justo antes de devolver un código de error. Por defecto, no está activado. $dbhandler ->{RaiseError} = 1;

Métodos de los manejadores de bases de datos

Nombre Descripción Ejemplo
prepare Prepara una sentencia SQL para su ejecución y devuelve una referencia al manejador de la sentencia ($sthandler). $sthandler = $dbhandler -> prepare($sql);
do Prepara y ejecuta una sentencia SQL. Devuelve el número de registros obtenidos, o -1 si no es conocido, o undef si hay un error.
Método usualmente usado para sentencias que no son consultas, las cuales no necesitan ser preparadas o ejecutadas por separado.
$numfilas =
$dbhandle -> do($sql);
commit Este método hace persistente una operación realizada en la BD.
No es soportado por algunos tipos de base de datos, como p.ej. MySQL.
$dbhandle -> commit;
rollback Deshace lo ejecutado por el método commit. $dbhandle -> rollback;
disconnect Cierra la conexión entre la base de datos y el manejador de la base de datos.
Se suele usar justo antes de terminar la aplicación.
$dbhandle->disconnect;
ping Comprueba si el servidor de bases de datos y la conexión siguen funcionando.
Es un método muy poco usado.
$resultado = $dbhandle
-> ping;
quote Escapa caracteres especiales (comillas, etc.) en las cadenas y añade las comillas externas.
No es aplicable a todos los tipos de entrada (P.ej., datos binarios).
$sql = $dbhandle -> quote($string);

Métodos de los manejadores de sentencias

Nombre Descripción Ejemplo
execute Ejecuta una sentencia preparada y devuelve ‘true’ si hay éxito y ‘undef’ si ocurre un error.
Para las sentencias que no son SELECT (UPDATE, INSERT, etc.) el valor de retorno es el número de registros afectados. Para sentencias SELECT se necesita usar uno de los métodos de extracción (fetch), explicados a continuación, para obtener los datos.
$resultado =
$sthandle->execute;
fetchrow_arrayref Extrae el siguiente registro con datos y devuelve una referencia a un array con los valores de los campos. Si no hay más registros, devuelve ‘undef’. $fila = $sthandle -> fetchrow_arrayref;
fetchrow_array Igual a ‘fetchrow_arrayref’ excepto que devuelve un array con los valores de los campos, en lugar de una referencia a un array. @array = $sthandle
-> fetchrow_array;
fetchrow_hashref Otro método para extraer registros. Devuelve una referencia a una memoria asociativa (hash) conteniendo para cada campo el nombre y el valor. Las claves de la memoria asociativa (hash) son los mismos que los nombres de los campos devueltos. $hashref = $sthandle
-> fetchrow_hashref;
fetchall_arrayref Usado para obtener todos los datos (registros) devueltos por una sentencia SQL. Devuelve una referencia a un array de arrays de referencias. $filas = $sthandle-> fetchall_arrayref;
finish Libera los recursos asociados al manejador de sentencia. Es utilizado cuando no se van a extraer más datos, antes de que sea preparado de nuevo o destruido. $sthandle -> finish;
rows Devuelve el número de registros afectados por la última sentencia no-select ejecutada. $numfilas =
$sthandle -> rows;