• Publicidad

Manejar datos desde fetchall_arrayref({})

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Manejar datos desde fetchall_arrayref({})

Notapor zozo666 » 2008-03-04 06:44 @322

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.
zozo666
Perlero nuevo
Perlero nuevo
 
Mensajes: 139
Registrado: 2007-05-26 10:36 @483

Publicidad

Notapor monoswim » 2008-03-04 06:53 @329

¿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?
MonoSwim
Perl Programming Language
Avatar de Usuario
monoswim
Perlero nuevo
Perlero nuevo
 
Mensajes: 452
Registrado: 2003-11-18 16:13 @717
Ubicación: Buenos Aires

Notapor zozo666 » 2008-03-04 07:04 @336

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.
zozo666
Perlero nuevo
Perlero nuevo
 
Mensajes: 139
Registrado: 2007-05-26 10:36 @483

Notapor explorer » 2008-03-04 18:17 @803

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!
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor zozo666 » 2008-03-04 20:46 @907

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.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $variable= $resp->fetchall_arrayref({});
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


¿Cómo saco de la variable $variable solamente los valores de Nombre, Apellido? No es que quiera hacer esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $variable = $resp->fetchall_arrayref({Nombre,Apellido});
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


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.
Última edición por zozo666 el 2008-03-05 11:11 @508, editado 1 vez en total
zozo666
Perlero nuevo
Perlero nuevo
 
Mensajes: 139
Registrado: 2007-05-26 10:36 @483

Notapor monoswim » 2008-03-05 07:39 @360

El tema de los arrays es que para tomar los valores no puedes usar nombres, sino el lugar donde está; sería algo como

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$$eventos[0][0]
$$eventos[0][1]
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El primer 0 sería el primer registro,
el segundo 0 sería el nombre y el 1 el apellido...

Por eso yo siempre prefiero usar el hashref porque me es más cómodo usarlo por nombre que por posición...

Saludos
PD: El while es muy conveniente cuando necesitas cambiar la estructura de los datos, si en tu HTML::Template usas la misma estructura que viene desde tu SELECT pues envíar toda la estructura de datos como parámetro...

EDITADO: había un error de sintaxis, eran $$ y no $
Última edición por monoswim el 2008-03-05 10:58 @499, editado 1 vez en total
MonoSwim
Perl Programming Language
Avatar de Usuario
monoswim
Perlero nuevo
Perlero nuevo
 
Mensajes: 452
Registrado: 2003-11-18 16:13 @717
Ubicación: Buenos Aires

Notapor explorer » 2008-03-05 08:29 @395

A ver si lo aclaramos:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $eventos = $rs->fetchall_arrayref();
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

devuelve la estructura que te comenté antes: una referencia a un array de arrays. Así, para sacar el tercer campo del quinto registro, es
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
print $eventos->[4]->[2];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Si solo nos interesa el primer campo de todos los registros:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $eventos = $rs->fetchall_arrayref([0]);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Si solo nos interesa los dos últimos campos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $eventos = $rs->fetchall_arrayref([-2,-1]);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Otra cosa distinta es lo que comentas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $eventos = $rs->fetchall_arrayref({});
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

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:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
print $eventos->[2341]->{Nombre};
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Si solo nos interesan los campos de Nombre y Apellidos, entonces lo llamamos así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $eventos = $rs->fetchall_arrayref({Nombre => 1, Apellidos => 1});
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


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

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $evento ( @$eventos ) {
    push @nombres, $evento->[0];
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Si, en cambio, usamos fetchall_arrayref({});, entonces será

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $evento ( @$eventos ) {
    push @nombres, $evento->{Nombre};
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Una vez que tienes todos los @nombres, puedes meterlos todos en un único escalar, con join:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$nombres = join(" ", @nombres);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


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.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
        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();
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor zozo666 » 2008-03-05 11:48 @533

Muchísimas gracias, explorer, por la ayuda que me has dado, pero tengo un problemita con esto.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $evento ( @$eventos ) {
    push @nombres, $evento->{Nombre};
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


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.
zozo666
Perlero nuevo
Perlero nuevo
 
Mensajes: 139
Registrado: 2007-05-26 10:36 @483

Notapor kidd » 2008-03-05 12:20 @555

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:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$nombres[1]
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Saludos
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Notapor explorer » 2008-03-05 13:37 @609

A ver si con un ejemplo nos aclaramos más...

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/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;
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


La salida (en mi caso) es:
Código: Seleccionar todo
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.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Siguiente

Volver a Intermedio

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados