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


Tal vez pueda interesarte


Compartí este artículo