Leibvitz escribiste:Hola! Tengo un problema muy curioso. Cuando ejecuto este script, me funciona bien y hace lo que tiene que hacer.
- Código: Seleccionar todo
require "config.conf";
use DBI;
my $nick = "leibvitz";
my $dbh = DBI->connect("DBI:mysql:$db:localhost",$user_db,$pass_db)
or die "No puedo conectarme\n";
my $sth = $dbh->prepare("SELECT COUNT(*) FROM service_admin WHERE admin='$nick';");
$sth->execute();
($num) = $sth->fetchrow_array();
$sth->finish();
$dbh->disconnect;
print "$num\n";
Pero cuando meto esta consulta en un subrutina y la ejecuto des de otro lugar, me dice:
DBD::mysql::st execute warning: at sql.pl line 14, <GEN0> line 36.
DBD::mysql::st fetchrow_array failed: fetch() without execute() at sql.pl line 15, <GEN0> line 36.
Y es que es exactamente lo mismo, solo que no hace execute por lo que veo. Qué puede ser?
Bueno el problema es que se te pudo pasar el execute, pero además, no se si realmente solo pusiste ese código como ejemplo, o es ya el código terminal de tu aplicación, pero tienes algunos detalles importantes que se te pasaron:
1) No encuentro por qué tu archivo en el require no pudo llamarse config.pl, pero además, si estás importando variables que posiblemente luego tengas que cambiar, sería mejor que importaras constantes. Pero aún mejor, genera un archivo en YAML o simplemente en CSV o algo en texto plano, y luego escribe un programa (config.pl) que lo interprete, y te importe un
%config con todo lo que necesitas de configuraciones, esto mas sencillo de manejar, y cualquier cambio en los valores de configuración, no hará que tengas que modificar todo el código o los códigos.
2) Jamás estás usando
strict ni
warnings, y eso está de alguna manera penalizado, el no usarlos en una aplicación en producción es de muy mal estilo, y puedes tener problemas al mantener y depurar tu código.
3) Haz que DBI cargue
RaiseError al inicio, así, cada que algo falle, automáticamente lanzará una excepción con die incluyendo el mensaje de error que provocó dicho fallo, y de esa manera no tienes que andar checando $dbi->errstr ( que no lo haces de todos modos ) para ver que es lo que ocurrió. O si tu prefieres hacer el manejo de errores, mete las sentencias que ejecutará DBI en bloque de
eval y verifica $@ al final para ver que fué lo que sucedió.
4) Estás pasando directamente los parámetros al query sin cuidar que puede haber SQL injection, es decir, sin usar
placeholders que puedan escapar tus parámetros apropiadamente.
Un intento "sano" de tu aplicación podría ser:
- Código: Seleccionar todo
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
require 'config.pl'; #importará %config
my $nick = 'leibvitz';
my $dbh = DBI->connect( "dbi:mysql:$config{db_name}", $config{user}, $config{pass},
{ RaiseError => 1 } ) or die "No se pudo conectar: $DBI::errstr\n";
my $sth = $dbh->prepare( 'SELECT COUNT(*) FROM service_admin WHERE admin=?' );
$sth->execute( $nick );
my ( $num ) = $sth->fetchrow_array;
$sth->finish;
$dbh->disconnect;
print $num, "\n",
Saludos,