Este artículo demuestra cómo conectarse a una base de datos PostgreSQL desde un script Perl y ejecutar consultas utilizando el módulo Apache::DBI
.
Este tutorial sirve para cualquier módulo que implemente la interfaz DBI de Perl, no sólo para Apache::DBI
. Por ejemplo podría utilizarse también el módulo DBD:pg
.
En Debian y derivados, el módulo de Perl Apache::DBI es provisto por el paquete libapache-dbi-perl
. DBD:pg
en cambio es provisto por el paquete libdbd-pg-perl
.
Lo único que cambia es la forma de incluir al módulo. Si se emplea Apache::DBI
debe incluirse de la siguiente forma:
use Apache::DBI ();
Si en cambio se usa DBD:pg
:
use DBI;
Luego el código para conectarse y ejecutar consultas es idéntico independientemente del controlador utilizado, ya que ambos módulos implementan la interfaz DBI.
Para comenzar, es conveniente definir los parámetros de conexión en variables locales, estos son: base de datos, nombre de host, puerto,usuario y contraseña.
# parámetros de conexión a la base de datos PostgreSQL my $dbname = 'pg_db'; my $host = 'pg.linuxito.com'; my $port = 5432; my $username = 'readonly'; my $password = 'trustno1';
La conexión a la base se hace empleando el método connect
, este retorna un handle que será utilizado luego para ejecutar las consultas SQL:
# conexión a la base de datos PostgreSQL my $dbh = DBI -> connect("dbi:Pg:dbname=$dbname;host=$host;port=$port", $username, $password, {AutoCommit => 0, RaiseError => 1} ) or die $DBI::errstr;
El primer parámetro es el string de conexión (base de datos, host y puerto), luego vienen usuario y contraseña. El cuarto parámetro especifica opciones de conexión. En este ejemplo se deshabilita el AutoCommit (para que las transacciones puedan ser rolled-back) y se habilita la opción RaiseError (para que los errores arrojen excepciones).
Para otras opciones, ver la documentación de DBI al respecto: DBI - Database Handle Attributes.
Una vez realizada la conexión, se define una sentencia SQL a ejecutar. En este caso se emplea una sentencia preparada para seleccionar dos columnas ("usuario" e "ip") desde la tabla "tickets", filtrando por un parámetro "ticket":
# consulta SQL my $SQL = "SELECT usuario, ip FROM public.tickets WHERE ticket = ?;";
A modo de ejemplo, se define un ticket en una variable local $ticket
y se crea una sentencia preparada invocando al método prepare
del handle. Luego se invoca al método execute
sobre la sentencia preparada creada para ejecutar la sentencia SQL definida en la variable $SQL
con el contenido de $ticket
como parámetro.
my $ticket = "1234"; my $sth = $dbh->prepare($SQL); $sth->execute($ticket);
El método prepare
retorna una referencia a un objeto statement handle.
Las sentencias preparadas tienen una gran ventaja desde el punto de vista de seguridad, y es que son resistentes a SQL injection. Esto se debe a que el parámetro pasado se envía con un protocolo diferente y evita alterar la sentencia desde el parámetro (no es posible inyectar código).
Luego de ejecutar la sentencia es posible extraer los resultados con el método fetchrow_array
sobre la sentencia preparada:
my @row = $sth->fetchrow_array; my $usuario = $row[1]; my $ip = $row[2];
Si se necesita verificar que se hayan obtenido resultados, se puede comprobar si las variables $usuario
e $ip
están definidas:
# verificar resultados if (!defined($usuario)) { # no hay datos en la consulta die "No existe el ticket."; }
Si se desea obtener una única fila y terminar, es conveniente invocar finish
para descartar los datos del handle de la sentencia preparada:
$sth->finish();
Si se van a recuperar todos los datos de la consulta, no se debe utilizar este método pues el controlador lo hace automáticamente.
Para más información, consultar la documentación de la interfaz DBI: DBI - Database independent interface for Perl.
Referencias
- DBI - Database independent interface for Perl
- Apache::DBI - Initiate a persistent database connection
- DBD::Pg - PostgreSQL database driver for the DBI module