• Publicidad

Edición de múltiples registros de una tabla de MySQL

Todo acerca de las bases de datos que existen: SQL, MySQL, Oracle, Postgres, CSV, etc.

Edición de múltiples registros de una tabla de MySQL

Notapor caribesoft » 2006-05-26 10:48 @492

Hola a todo el mundo :

Necesito hacer un Perl script que lea una tabla, despliegue la información en renglones y columnas y pueda editar cada campo de tabla desplegado, tipo excel.

Lo que hago es un query, despliego los datos dentro de un formulario HTML, y luego lo puedo enviar para dar el UPDATE de la tabla.

Pero mi pregunta es, cómo le puedo asignar nombres distintos a cada campo (del formulario) que se derivan de la tabla, para que cuando lo envie (SEND) los lea como parámetros y luego pueda hacer el UPDATE a la tabla.

A ver si me entienden, es bienvenido cualquier tip,

Saludos,

Caribesoft
caribesoft
Perlero nuevo
Perlero nuevo
 
Mensajes: 73
Registrado: 2006-05-09 22:01 @959
Ubicación: Cancun

Publicidad

Notapor explorer » 2006-05-26 11:04 @503

Con
Código: Seleccionar todo
my @campos = @{$sth->{NAME}};
se leerían los nombres de los campos.
El como transformarlos a campos de formulario depende de cómo quieras llamarles. Puede ser simplemente ponerlos en minúsculas... lo principal es que luego sepas hacer el camino a la inversa: derivar los nombres de los campos a partir de los del formulario.
¿No tienes algo de código de prueba para enseñarnos?
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Si exactamente allí es donde me pierdo

Notapor caribesoft » 2006-05-26 11:18 @513

El código es así:
Código: Seleccionar todo
#!/usr/bin/perl
use CGI qw (:standard);
use CGI::Carp qw(fatalsToBrowser);
print "Content-type:text/html\n\n";
use POSIX;
use DBI;
$q = new CGI;
$action    = $q->param(action);
$bln    = $q->param(bln);

#### Abre la conexion a la base de datos
$dbh = DBI->connect("DBI:mysql:database=api;host=localhost","","",{'RaiseError' =>1});


######  OPCIONES  ######
if($action eq 'almacen'){
    &ver_almacen;
}elsif($action eq 'actualiza'){
    ####  AQUI PONDRIA EL CODIGO PARA RECIBIR DATOS Y DAR EL UPDATE ###3
    $fechain    = $q->param(fechain);
    $llegomerc  = $q->param(llego_merc);
    $ubicacion  = $q->param(ubicacion);
   
    #####  etcetera, pero aqu es donde me pierdo, como relaciona cada registro
   
    $sth = $dbh->prepare("UPDATE bldt SET fechain='$fechain',llegomerc='$llegomerc',ubica='$ubica' where bln = '$bln' ");
    $sth->execute();
   
}else{
 exit;
}


##########################  VER ENTRADADAS AL ALMACEN  ###################
sub ver_almacen {

print<<HTML;
<html>
<head>
<meta http-equiv="Content-Language" content="es">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Facturas</title>
<LINK REL="stylesheet" HREF="$ruta4/stylesheet.css" TYPE="text/css">
</head>
 <body topmargin=0>
HTML

print "<table border=0 cellpadding=1 width=100% align=center>";
print "<form method=post action=test-alm.pl name=forma1>";
print "<tr bgcolor=#ABC8E6>";
print "<td align=center><font face=Arial size=2>Contenedor</font>";
print "<td align=center><font face=Arial size=2>Fecha</font>";
print "<td align=center><font face=Arial size=2>¿Llego?</font>";
print "<td align=center><font face=Arial size=2>Ubicacion</font>";
print "<td align=center><font face=Arial size=2>Tipo Cont</font>";
print "<td align=center><font face=Arial size=2>Selec</font>";
$iz=0;
          $query3 = "SELECT registro,blnumb,voyagenum,marks,qty,kind,container_num,contents,container_type,estatus_ing,estatus_des,ubicacion from bldt  order by container_num,blnumb";
          $sth3 = $dbh->prepare($query3);
          $sth3->execute();
         while (my $ref = $sth3->fetchrow_hashref()) {
           $record    = $ref->{'registro'};
           $bln       = $ref->{'blnumb'};
           $marks     = $ref->{'marks'};
           $qty       = $ref->{'qty'};
           $kind      = $ref->{'kind'};
           $cont_num  = $ref->{'container_num'};
           $cont      = $ref->{'contents'};
           $contclas  = $ref->{'container_type'};
           $estatusin = $ref->{'estatus_ing'};
           $estatusdes = $ref->{'estatus_des'};
           $ubica     = $ref->{'ubicacion'};
           $cont = substr($cont,0,25);
           if($iz%2 == 0) {
               print "<tr bgColor=#efefef>";
            }else{
              print "<tr>";
           }
           print "<td align=right><font face=Arial size=2>$cont_num</td>";
           print"<td align=center><input type=text name=fechain size=10 value='$date2'></td>
           <td align=cente><select size=1 name=llego_merc>
                 <option value='$llego_merc'>$llego_merc</option>
           <option value=SI>SI</option>
           <option value=NO>NO</option>
           </select><font face=Arial size=2></td>";
           print"<td align=center>
                <select size=1 name=ubicacion>
                 <option value='$ubicacion'>$ubicacion</option>
           <option value=Patios>Patios</option>
           <option value=Almacen>Almacen</option>
           <option value=Vacios>Vacios</option>
           </select>
                <td align=center><font face=Arial size=2>$kind</td>
                <td align=center><input type=text name=marks size=10 value=$marks></td>";
          $iz++;
          }

 print<<HTML;
  <table border=0 cellpadding=1 align=center >
  <TR BGCOLOR="#e0e0e0">
   <TD COLSPAN=$colspan ALIGN=CENTER>
    <INPUT TYPE=HIDDEN NAME=entry VALUE=NO>
    <INPUT TYPE=HIDDEN NAME=folio VALUE=$folio>
    <INPUT TYPE=HIDDEN NAME=action VALUE=actualiza>
    <INPUT TYPE=SUBMIT NAME=ACTION VALUE=Enviar>

    </TD>
  </TR>
  </form>
HTML
print "<table border=0 cellpadding=1 align=center>";
} # End of subroutine Ver Detalle Manifiestos
caribesoft
Perlero nuevo
Perlero nuevo
 
Mensajes: 73
Registrado: 2006-05-09 22:01 @959
Ubicación: Cancun

Notapor kidd » 2006-05-26 19:55 @871

Hola:

En primer lugar bienvenido al foro. Ahora, es buena sintáxis llamar a la funciones de la siguiente manera:
Código: Seleccionar todo
funcion();


Ahora, en cuanto a tu problema, aún no me queda muy en claro que es lo que necesitas, pero si te digo que la parte que tienes:
Código: Seleccionar todo
  $sth = $dbh->prepare("UPDATE bldt SET fechain='$fechain',llegomerc='$llegomerc',ubica='$ubica' where bln = '$bln' ");
  $sth->execute();


La llamada la deberías de hacer de la siguiente manera:
Código: Seleccionar todo
  $sth = $dbh->prepare("UPDATE bldt SET fechain=?,llegomerc=?,ubica=? WHERE bln=?");
  $sth->execute($fechain,$llegomerc,$ubica,$bln);


De esta manera permites que el DBI haga el escape de tus campos por ti, así evitas exploits del MySQL y en caso de que haya caracteres especiales no te cambiará el sentio de tu query.


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

Mi problema es el siguiente ....

Notapor caribesoft » 2006-05-26 20:56 @914

Primero, gracias por tus observaciones, cada día se aprende algo nuevo y más en este fabuloso sitio.

Lo que quiero hacer es lo siguiente:

1. Hago un query de una tabla :
Código: Seleccionar todo
$query = "SELECT registro,container,indate,llego,ubicacion from bldt order by container";
$sth = $dbh->prepare($query);
$sth->execute();


2. Despliego la información del query, dentro de un formulario HTML, para poder editar o cambiar los valores de los campos (tipo hoja excel):
Código: Seleccionar todo
print "<table border=0 cellpadding=1 width=100% align=center>";
print "<form method=post action=test-alm.pl name=forma1>";
print "<tr bgcolor=#ABC8E6>";
print "<td align=center><font face=Arial size=2>Contenedor</font>";
print "<td align=center><font face=Arial size=2>Fecha</font>";
print "<td align=center><font face=Arial size=2>¿Llego?</font>";
print "<td align=center><font face=Arial size=2>Ubicacion</font>";
print "<td align=center><font face=Arial size=2>Tipo Cont</font>";

while (my $ref = $sth3->fetchrow_hashref()) {
           $rec     = $ref->{'registro'};
           $cont    = $ref->{'container'};
           $fecha  = $ref->{'indate'};
           $llego    = $ref->{'llego'};
           $ubica   = $ref->{'ubicacion'};

print "<td align=right><font face=Arial size=2>$cont</td>";
print"<td align=center><input type=text name=fechain size=10 value='$fecha'></td>
   <td align=cente><select size=1 name=llego>
                 <option value='$llego'>$llego</option>
           <option value=SI>SI</option>
           <option value=NO>NO</option>
           </select><font face=Arial size=2></td>";
 print"<td align=center>
                <select size=1 name=ubicacion>
                 <option value='$ubica'>$ubica</option>
           <option value=Patios>Patios</option>
           <option value=Almacen>Almacen</option>
           <option value=Vacios>Vacios</option>
           </select>
               </td>";
           } 
print" <INPUT TYPE=HIDDEN NAME=action VALUE=actualiza>
    <INPUT TYPE=SUBMIT NAME=ACTION VALUE=Enviar>";


3. Envio el contenido y actualizo la tabla con un UPDATE.

Mis preguntas :

1. ¿Cómo le asigno los nombres a los campos? Por cada registro leído tiene que haber un nombre de campo diferente.
Ej : si fueran 3 registros
fechainx1,fechainx2,fechainx3
llegox1,llegox2,llegox3
ubicax1,ubicax2,ubicax3


2. Y que defina los nombres como los asigno para el UPDATE
Código: Seleccionar todo
$llego1  = $q->param(llegox1);
$llego2  = $q->param(llegox2);
$llego3  = $q->param(llegox3);

$fecha1 = $q->param(fechainx1);
$fecha2 = $q->param(fechainx2);
$fecha3 = $q->param(fechainx3);

$ubica1 = $q->param(ubicax1);
$ubica2 = $q->param(ubicax2);
$ubica3 = $q->param(ubicax3);


3. y al Final hago el UPDATE como me lo explicas ...

Pero ¿que pasa si son 1000 registros? ¡¡¡¡ No quiero definir 1000 variables !!!!

¿A ver si me entienden?

Saludos,
caribesoft
Perlero nuevo
Perlero nuevo
 
Mensajes: 73
Registrado: 2006-05-09 22:01 @959
Ubicación: Cancun

Notapor kidd » 2006-05-27 08:44 @405

Hola:

Explorer ya te mostró como puedes automatizar los nombres de los campos de la base de datos a un arreglo para a base de ello crear el formulario para hacer el update, si así lo quieres.

Lo primero es que puedes automatizar la parte para leer los campos recibidos en un par de líneas:

Código: Seleccionar todo
use CGI;

my $query = new CGI;
my %Input = $query->Vars;


Ahora tu hash %Input contiene una seria de llaves-valores que son los que recibiste por medio del formulario.

Entonces a partir de él podrías hacer:

Código: Seleccionar todo
$sth = $dbh->prepare('UPDATE bldt SET ' . join(',',map{ "$_=?" } sort keys %Input) . ' WHERE bln=?');


Y en el execute, algo así como:

Código: Seleccionar todo
$sth->execute(sort values %Input);


Ahora, el único problema con esta solución es que lee TODAS las variables que envías, así que si envías algunos campos que no son del mismo database entonces te las incluirá en el SELECT.

Hay un par de soluciones más que se me ocurren, siguiendo más o menos la idea que te presenté podrías crear un array con los nombres de los campos que vas a editar, ese array lo puedes usar tanto para la construcción de tu formulario, así como para el update de la misma base de datos.

También hay una función del mismo CGI.pm que sirve para recuperar todos los nombres de los campos envíados en tu formulario:
Código: Seleccionar todo
my @names = $query->param;



Lo que también podrías hacer es al momento de construir tu formulario, nombrar todos los campos que correspondan a la base de datos con un subfijo inicial, por ejemplo:

Código: Seleccionar todo
bd_nombre
bd_apellido
bd_edad
...


Entonces al leer los campos ya puedes realizar la automatización sabiendo que todos los campos que tengan un subfijo bd_ son campos de tu base de datos.

Hay varias soluciones por la cual puedes optar, selecciona la que sea más adecuada a tu proyecto.


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 » 2006-05-27 11:11 @508

No hay forma (que yo conozca) para evitar enviar nombres de formularios todos iguales, SALVO en el caso de que generes un formulario distinto por cada fila de registros y, aún así, en tu cgi deberás saber qué formulario se ha activado, con lo que estamos en lo mismo: cada formulario tiene que tener un nombre distinto. Quizás sea la mejor solución, ya que simplifica mucho la generación del html.

De otra forma, tenemos que generar nombres de campos todos distintos.

Partiendo del bucle while tuyo, puedes incluir una variable contador para que nos ayude a ir numerando los registros o, mejor aún: si uno de los campos de tu base de datos es de tipo autonumérico -y por lo tanto es el id del registro, único e irrepetible-, lo utilizaremos. Como en tu base de datos veo que el campo 'registro' no lo usas para nada, creo que ese es el campo que se debe utilizar.

Modificamos entonces el código para que quede así:
Código: Seleccionar todo
while (my $ref = $sth3->fetchrow_hashref()) {
    $rec     = $ref->{'registro'};
    $cont    = $ref->{'container'};
    $fecha   = $ref->{'indate'};
    $llego   = $ref->{'llego'};
    $ubica   = $ref->{'ubicacion'};

    print qq(<td align="right">$cont</td>);
    print qq(
<td align="center"><input type="text" name="fechain_$rec" size="10" value="$fecha"></td>
<td align="center"><select size="1" name="llego_$rec">
    <option value="$llego">$llego</option>
    <option value="SI">SI</option>
    <option value="NO">NO</option>
</select></td>);
    print qq(
<td align="center"><select size="1" name="ubicacion_$rec">
    <option value="$ubica">$ubica</option>
    <option value="Patios">Patios</option>
    <option value="Almacen">Almacen</option>
    <option value="Vacios">Vacios</option>
</select></td>\n);
}

Como ves, en el nombre de los campos editables hemos hecho un cambio: le agregamos el valor de $rec. De esa forma, cuando recibamos todos los campos de vuelta, como te ha indicado kidd, vamos leyendo uno a uno, lo pasamos por una expresión regular:
Código: Seleccionar todo
($rec) = $campo =~ /_(.+)/;
y así sabemos a qué registro hace referencia ese campo. Lo ideal es agruparlos todos bajo el mismo registro para saber dónde hay que hacer el UPDATE.

Otra forma: si se trata de poner los registros uno por línea, agregar un botón submit a la derecha de todos los campos, con un nombre construído como se indica aquí. De esa manera, cuando tu cgi se llame, lo primero será saber qué botón se pulsó, y de ahí, sabes qué registro es el que el usuario quiere modificar. Es mucho más rápido (más feo porque hay en pantalla un montón de botones, pero...).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Buena idea

Notapor caribesoft » 2006-05-27 12:08 @547

Muchas gracias a Kidd y Explorer, son excelentes ideas , pero perdon por mi ignorancia, no entendi como utilizar y en donde la expresion :

Código: Seleccionar todo
($rec) = $campo =~ /_(.+)/;


Seria despues de :

Código: Seleccionar todo
my @names = $q->param;


Me das otra pista, Explorer ??

Muchas gracias,
caribesoft :roll:
caribesoft
Perlero nuevo
Perlero nuevo
 
Mensajes: 73
Registrado: 2006-05-09 22:01 @959
Ubicación: Cancun

Notapor explorer » 2006-06-22 13:22 @598

Sí, cuando vayas a leer el resultado enviado por el usuario...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Bases de datos

¿Quién está conectado?

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