2012-01-18 12 views
6

¿Con DBI hay una forma de determinar si un identificador de instrucción ejecutado para una instrucción SELECT devolverá cualquier fila sin obtener de ella?

I.e. algo así como:

use DBI; 
... 
my $sth = $dbh->prepare("SELECT ..."); 
$sth->execute; 

if (..$sth will return at least one row...) { 
    ... 
} else { 
    ... 
} 

y quiero realizar la prueba $sth will return at least one row sin realizar ningún método fetch en $sth.

Nota - No necesito el número exacto de filas (es decir $sth->rows), sólo necesito saber si habrá $sth->rows> 0.

Respuesta

8

$ sth-> filas sigue siendo la mejor opción. Como dijo, solo verifique si es más que 0.

if ($sth->rows > 0){ 
    # magic here! 
} 

EXCEPT! la documentación de DBI dice que esto no es confiable para las declaraciones seleccionadas hasta que se hayan obtenido todas las filas. No hay forma de determinar cuántas filas se buscarán de antemano. Si lo que necesita saber esto, el consejo es hacer primero una

select count(*) from <table> 

Ver this section of the DBI documentation.

+0

puede no funcionar dependiendo del conductor, por ejemplo, con DBD :: Oracle, $ sth-> rows devuelve el número de filas afectadas solo por actualizaciones, elimina e inserta, pero -1 por selecciones (http://search.cpan.org/~pythian/DBD-Oracle-1.74/lib/DBD/Oracle.pm# filas) – Fred

1

En lugar de buscar algo en DBI puede usar SQL para eso. Simplemente envuelva SELECCIONAR en otro SELECT con EXISTE condición:

SELECT 1 FROM DUAL WHERE EXISTS (SELECT ...); 

No es SQL portátil: FROM DUAL puede tener un aspecto diferente de su RDBMS, su base de datos no puede apoyar existe y subconsultas. Sin embargo, la mayoría de los DB modernos le permiten cocinar algo como esto.

Debería ser la forma más efectiva, ya que el optimizador puede omitir el orden por, grupo por, límites en la sub consulta. Verifique los planes de ejecución.

SELECT COUNT(*) FROM (SELECT ...) 

También es posible, pero DB tiene que verificar el conjunto de datos para obtener el número correcto de filas.

Si controla el generador de SQL, puede soltar la orden por, agrupe por (solo si no tiene parte también) y aplique un límite además de eso para seleccionar solo una fila.

0

Quizás esto es lo que estás buscando.

"Activo" (boolean, de sólo lectura)

El atributo "Activo" es cierto si el objeto mango es "activo". Esto rara vez se usa en aplicaciones. El significado exacto de activo es algo vago en este momento. Para un manejador de base de datos, normalmente significa que el identificador está conectado a una base de datos ("$ dbh-> disconnect" desactiva "Activo"). Para un identificador de sentencia, normalmente significa que el identificador es un "SELECCIONAR" que puede tener más datos para recuperar. (Recuperar todos los datos o llamar a "$ sth-> finish" desactiva "Activo")

+0

No. Como cito en su respuesta, 'Active 'normalmente significa que un identificador de sentencia * puede * tener más filas para recuperar. Entonces, incluso una sentencia ejecutada que sabemos * a priori * devolverá ninguna fila (bajo controladores típicos como 'DBD :: mysql') informará' Active' hasta que se llame a la primera (y final) 'fetch()'. – pilcrow

2

No creo que haya ninguna manera confiable de comprobar si se pueden recuperar las filas que no sean ir a buscarlas. Por supuesto, una vez que ha buscado la primera fila, no está disponible para su recuperación, y debe mantenerla "en la mano". Pero esto no es demasiado difícil de tratar.

que habría por lo general piensa utilizar expresiones como uno de los dos siguientes:

... 
$sth->execute; 

my @rows; 

my $row = $sth->fetchrow_hashref(); 

if ($row) { 
    do { 
     # do something with $row 
     ... 

     $row = $sth->fetchrow_hashref(); 
    } while ($row); 
} else { 
    # No rows 
} 

o

... 
$sth->execute; 

my @rows; 

while (my $row = $sth->fetchrow_hashref()) { push @rows, $row } 

if (@rows) { 
    # Some rows, now in @rows 
} else { 
    # No rows 
} 
+0

O simplemente use '$ sth-> fetchall_arrayref()' directamente como se describe en https://stackoverflow.com/a/47679059/111036 si los resultados esperados serían de un tamaño razonable. – mivk

Cuestiones relacionadas