Mar Mar 04, 2008 5:44 am
|
 |
zozo666
Perlero Frecuente

|
Registrado: 26 May 2007
Mensajes: 137
|
|
| Manejar datos desde fetchall_arrayref({}) |
|
|
Buenas, gente. Necesitaría saber cómo tomar, o mejor dicho, de qué forma vienen los datos en el fetchall_arrayref({}).
Por ejemplo, tengo una tabla con 4 campos y tengo ingresados 10 registros, a la consulta le hago $valores = $consulta->fetchall_arrayref({}). ¿De qué forma puedo extraer toda la información de los campos 2 y 3 de $valores?
Para esto necesitaría saber cómo me devuelven los valores cuando hago un fetchall_arrayref({}). ¿Cómo me los devuelve?
En la documentación me dice que me devuelve todas las filas y las columnas en una referencia a un hash, pero de qué manera leo todas las filas de cada campo, o sea del campo que yo quiero. Sé que esto se puede obtener más fácilmente haciendo un fetchall_hashref({}) pero quiero saber hacerlo con fetchall_arrayref({}).
Gracias perleros por este fantástico foro. |
|
|
|

Mar Mar 04, 2008 5:53 am
|
 |
monoswim
Vive para Perl en Español

|
Registrado: 18 Nov 2003
Mensajes: 716
Ubicación: Buenos Aires
|
|
|
|
|
¿Estás seguro que es arrayref y no hashref?
Porque creo que no existe arrayref...
Con
while (my $all = fetchall_hashref())
te da una referencia a la estructura de datos en $all; entonces luego haces
$$all{'nombre'}
$all->{'apellido'}
Cualquiera de los 2 métodos es correcto...
Espero que te sirva.
Saludos
PD: ¿Por qué le colocas un hash ({}) como parámetro? |
|
Mar Mar 04, 2008 6:04 am
|
 |
zozo666
Perlero Frecuente

|
Registrado: 26 May 2007
Mensajes: 137
|
|
|
|
|
Sí, sí, es fetchall_arrayref({}). En la documentación está descrito y se utiliza también conjuntamente con HTML::Template para colocar los datos entre las etiquetas <TMPL_LOOP nombre> </TMPL_LOOP>.
Eso lo sabía. Igualmente muchas gracias por contestar. |
|

Mar Mar 04, 2008 5:17 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4082
Ubicación: Valladolid, España
|
|
|
|
|
fetchall_arrayref y fetchall_hashref existen. Los dos devuelven toda la consulta (no es necesario hacer ningún bucle como indica monoswim). La diferencia entre ellos es que el primero devuelve un escalar que es una referencia a un array en que cada elemento contiene un array con los elementos de cada registro. Y el segundo devuelve una referencia a un hash en que las claves son los valores del campo indicado como índice en la llamada a la función. Y los valores correspondientes a esas claves son a su vez hashes conteniendo los valores de cada registro, indexados por los nombres de los campos de la consulta (¡uff!).
Os recuerdo: ¡Data::Dumper es nuestro amigo! |
|

Mar Mar 04, 2008 7:46 pm
|
 |
zozo666
Perlero Frecuente

|
Registrado: 26 May 2007
Mensajes: 137
|
|
|
|
|
Ok, gracias, explorer. Ahora tengo una duda: ¿y cómo leo los datos que me tira un fetchall_arrayref({}) ??
A ver si me explico bien: yo hago una consulta a una tabla de Nombre, Apellido, Edad y Sexo. Y genero este código luego de la consulta.
| Perl: | my $variable= $resp->fetchall_arrayref({}); |
¿Cómo saco de la variable $variable solamente los valores de Nombre, Apellido? No es que quiera hacer esto:
| Perl: | my $variable = $resp->fetchall_arrayref({Nombre,Apellido}); |
Lo que querría hacer es algo parecido a lo que se hace con el fetchrow_hashref. Se ve en el ejemplo de monoswim.
Algo como que dé $nombres = $variable[Nombre] y que $nombres sea un string con todos los nombres.
No sé si me explico bien pero quiero leer los valores del fetchall_arrayref({}); de una manera parecida a la que se hace con el fetchall_hashref(); o sea, usando el bucle y demás cosas.
Arriba me dijiste que el fetchall_arrayref devuelve un escalar que es una referencia a un array en que cada elemento contiene un array con los elementos de cada registro.
¿Cómo hago para sacar de este escalar solamente Nombre y Apellido?
Muchas gracias. Esto me sería de gran ayuda. Adiós.
Ultima edición por zozo666 el Mie Mar 05, 2008 10:11 am, editado 1 vez |
|


Mie Mar 05, 2008 7:29 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4082
Ubicación: Valladolid, España
|
|
|
|
|
A ver si lo aclaramos:
| Perl: | my $eventos = $rs->fetchall_arrayref(); |
devuelve la estructura que te comenté antes: una referencia a un array de arrays. Así, para sacar el tercer campo del quinto registro, es
| Perl: | print $eventos-> [4]-> [2]; |
Si solo nos interesa el primer campo de todos los registros:
| Perl: | my $eventos = $rs->fetchall_arrayref([0]); |
Si solo nos interesa los dos últimos campos:
| Perl: | my $eventos = $rs->fetchall_arrayref([-2,-1]); |
Otra cosa distinta es lo que comentas:
| Perl: | my $eventos = $rs->fetchall_arrayref({}); |
La presencia del hash anónimo ({}) provoca que el resultado sea una referencia a un array en que cada elemento es un hash anónimo en que las claves son los nombres de los campos. Así, para sacar el Nombre del registro número 2341 es:
| Perl: | print $eventos-> [2341]-> {Nombre }; |
Si solo nos interesan los campos de Nombre y Apellidos, entonces lo llamamos así:
| Perl: | my $eventos = $rs->fetchall_arrayref({Nombre => 1, Apellidos => 1}); |
Pero en estos casos en los que solo nos interesan ciertos campos, es mucho mejor rehacer la consulta SQL para que nos devuelva los campos interesantes, y luego hacer el fetchall, sin restricciones.
Si, una vez que tienes toda la información sacada con el fetchall, quieres obtener, en una variable separada, todos los nombres, entonces depende de la estructura que le pediste a fetchall. Así, si usaste la forma fetchall_arrayref();, entonces debemos saber qué posición ocupa el campo Nombre dentro de la consulta. Si suponemos que es el primer campo, entonces con
| Perl: | foreach my $evento ( @ $eventos ) {
push @nombres, $evento-> [0];
} |
Si, en cambio, usamos fetchall_arrayref({});, entonces será
| Perl: | foreach my $evento ( @ $eventos ) {
push @nombres, $evento-> {Nombre };
} |
Una vez que tienes todos los @nombres, puedes meterlos todos en un único escalar, con join:
| Perl: | $nombres = join(" ", @nombres); |
Y en cuanto al HTML::Template, hay módulos como el HTML::Template::Associate, que ayudan mucho en la presentación de datos de una consulta en una plantilla HTML. De hecho, se hace todo en unas pocas líneas.
| Perl: | use DBI;
use HTML:: Template;
use HTML:: Template:: Associate;
my $results_foo = $dbh-> selectall_hashref (
'SELECT foo FROM bar WHERE baz = ?',
'foo_id',
{},
$baz
);
my $associate = HTML:: Template:: Associate-> new( {
target => 'DBI',
create => [ {
results => $results_foo,
name => 'my_loop',
type => 'selectall_hashref'
},
]
} );
my $template = HTML:: Template-> new (
filename => 'test.tmpl',
associate => [ $associate ],
die_on_bad_params => 0
);
print $template-> output();
|
|
|

Mie Mar 05, 2008 10:48 am
|
 |
zozo666
Perlero Frecuente

|
Registrado: 26 May 2007
Mensajes: 137
|
|
|
|
|
Muchísimas gracias, explorer, por la ayuda que me has dado, pero tengo un problemita con esto.
| Perl: | foreach my $evento ( @ $eventos ) {
push @nombres, $evento-> {Nombre };
} |
Cuando pongo @nombres[1] me tendría que tirar el registro encontrado número 2, pero no lo devuelve, estará mal algo en mi script, el fetchall_arrayref({}), si lo uso conjuntamente con el LOOP del template anda perfecto, pero cuando quiero sacar solamente todos los nombres como hiciste vos anteriormente, no me muestra nada, o sea la variable @nombres está vacía.
¿Dónde puede estar el error? Gracias. |
|
Mie Mar 05, 2008 11:20 am
|
 |
kidd
Creador de Perl en Español

|
Registrado: 15 Oct 2003
Mensajes: 1389
Ubicación: México
|
|
|
|
|
Hola:
Si ya tienes tu array @nombres como está creado con el código que te proporcionó explorer, entonces para accesar el segundo nombre lo tienes que hacer de la siguiente manera:
Saludos |
|

Mie Mar 05, 2008 12:37 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4082
Ubicación: Valladolid, España
|
|
|
|
|
A ver si con un ejemplo nos aclaramos más...
| Perl: | #!/usr/bin/perl -l
use warnings;
use strict;
use DBI;
use Data:: Dumper;
my $dbh = DBI-> connect("DBI:mysql:database=guiacolor;host=localhost", 'guiacolor', 'gu1asw7');
my $sth = $dbh-> prepare("SELECT * from valladolid where epigrafe like 'ASCENSOR%'");
$sth-> execute;
print "Número de registros: ", $sth-> rows;
my $ascensores;
my @nombres;
my $tipo_de_peticion_es_array = 1; # 0 o 1
if ( $tipo_de_peticion_es_array ) {
# Recuperamos los datos en forma de array de arrays
$ascensores = $sth-> fetchall_arrayref();
#print Dumper $ascensores;
# Segunda empresa de ascensores. El nombre es el tercer campo
print $ascensores-> [1]-> [2];
# Sacamos todos los nombres
foreach my $empresa ( @ $ascensores ) {
push @nombres, $empresa-> [2];
}
}
else {
# O en forma de array de hashes
$ascensores = $sth-> fetchall_arrayref({});
#print Dumper $ascensores;
# Segunda empresa de ascensores (su nombre)
print $ascensores-> [1]-> {nombre };
# Sacamos todos los nombres
foreach my $empresa ( @ $ascensores ) {
push @nombres, $empresa-> {nombre };
}
}
# ¡Data::Dumper es nuestro amigo!
print Dumper \ @nombres;
# Nombre de la segunda empresa
print $nombres[1];
# Cerramos
$sth-> finish;
$dbh-> disconnect;
|
La salida (en mi caso) es:
| Código: |
atari@aprosi43:~/desarrollo/perl$ ./fetchall.pl
Número de registros: 17
ASCENSORES ENOR
$VAR1 = [
'ASCENSORES EMBARBA',
'ASCENSORES ENOR',
'ASCENSORES HELVETIA',
'ASCENSORES INELSA ZENER',
'ASCENSORES ORONA',
'ASCENSORES SCHINDLER, S.A.',
'ASCENSORES ZENER',
'CASTELLANA DE ASCENSORES',
'HERAS ELEVADORES, S.L.',
'HERMON ELEVADORES, S.L.',
'INELTRA, S.L.',
'IZA ELEVADORES, S.L.',
'MELCO ASCENSORES',
'SISCYL S.L. SUBVENCIONES',
'THYSSEN KRUPP ELEVADORES, S.A.',
'ZARDOYA OTIS, S.A.',
'ZARDOYA OTIS, S.A.'
];
ASCENSORES ENOR |
En caso de duda sobre lo que contiene una variable, usar Data::Dumper. |
|

Mie Mar 05, 2008 7:37 pm
|
 |
zozo666
Perlero Frecuente

|
Registrado: 26 May 2007
Mensajes: 137
|
|
|
|
|
Ok. Muchas gracias. Me sirvió de mucho esto... tenía yo un problema en el script; por eso no funcionaba. Muchas gracias y espero que este hermoso foro siga así.
Saludos a todos los perleros hispanohablantes. |
|
Powered by phpBB © 2001, 2005 phpBB Group
|