Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Modificar registro sin crear uno nuevo (https://www.clubdelphi.com/foros/showthread.php?t=91659)

yuyidt 28-03-2017 14:29:56

Modificar registro sin crear uno nuevo
 
Buenas. se me esta presentado el siguiente problema:
tengo resgistros agregados en la bdd. En un formulario a través de el evento onchange de un edit busco ese registro, por supuesto el id de los registros es incremental,
por ejemplo tengo un registro con el id 19, cuando abro el form me llena de una vez el edit del id con el numero 20,
el asunto es que cuando hago una búsqueda en el edit del los resgistros existentes y voy actualizar dicho registro, al darle guardar, no se me actualiza el registro, sino que me crea otro con el id siguiente al que esta guardado en la tabla. No se que me esta faltando, necesito ayuda por favor.
codigo de onchange del edit:
Código Delphi [-]
procedure TForm5.Edit3Change(Sender: TObject);
begin
with datamodule2.FDQuery3 do
  begin
    close;
        sql.Text:='SELECT * FROM eva_maestro where id_exa=:idex';
        parambyname('idex').AsString:=edit3.Text;
    open;
        edit1.Text:=datamodule2.FDQuery3.FieldByName('nombre_examen').AsString;
  end;
with datamodule2.FDQuery7 do
  begin
  Close;
  SQL.Clear;
  SQL.Add('SELECT eva_maestro.id_exa, eva_detalle.tipo_pregunta, eva_detalle.pregunta,eva_detalle.opcion1,eva_detalle.opcion2,eva_detalle.opcion3,eva_detalle.opcion4  ,eva_detalle.respuesta');
  SQL.Add('FROM eva_maestro, eva_detalle');
  SQL.Add('WHERE eva_maestro.id_exa = eva_detalle.id_exama');
  SQL.Add('AND eva_detalle.id_exama = :idexa');
  ParamByName('idexa').AsString:= edit3.Text;
  Open;
  end;
  Bitbtn3.Enabled:= (Edit3.Text <> '');
end;


Codigo del boton donde guardo los nuevos registros y las actualizaciones:
Código Delphi [-]
procedure TForm5.BitBtn1Click(Sender: TObject);
var
  a:integer;
  begin
    with datamodule2.FDQuery6 do
    begin
      close;
      sql.Text:='SELECT ced_est FROM eva_estudiantes WHERE ced_est=:cedes';
      ParamByName('cedes').Value:='i';
      open;
      begin
        close;
        sql.Text:='INSERT INTO eva_maestro (nombre_examen,fecha_ini,fecha_fin,nota) VALUES (:nomex,:feini,:fefin,:not)';
        ParamByName('nomex').Value:=edit1.Text;
        ParamByName('feini').value:=formatdatetime('YYYY-MM-DD',DateTimePicker1.Date);
        ParamByName('fefin').value:=formatdatetime('YYYY-MM-DD',DateTimePicker2.Date);
        Parambyname('not').Value:=combobox2.Text;
        ExecSQL;
        close;
        sql.Text:='SELECT max(id_exa) as ultimo FROM eva_maestro';
        open;
        a:=FieldByName('ultimo').AsInteger;
        close;
        sql.Text:='INSERT INTO eva_detalle (id_exama,pregunta,tipo_pregunta,Opcion1,Opcion2,Opcion3,Opcion4,respuesta,puntos) SELECT '+
                    inttostr(a)+',pregunta,tipo_pregunta,Opcion1,Opcion2,Opcion3,Opcion4,respuesta,puntos FROM eva_estudiantes WHERE ced_est=:cedes';
        ParamByName('cedes').Value:='i';
        ExecSQL;
        close;
        sql.Text:='TRUNCATE eva_estudiantes';
        execsql;
        datamodule2.FDQuery5.close;
        datamodule2.FDQuery5.close;
        limpiar;
      end;
    end;
end;
Ayuda por favor, quisiera modificar es el registro que se me muestra en los edit. cuyo id lo muestra el edit3

TOPX 28-03-2017 14:49:09

Buenas.

Para modificar registros se utiliza la sentencia UPDATE.
-

yuyidt 28-03-2017 15:40:24

si utilizo update pero...
 
Hola, utilizo update dentro del mismo boton que guarda el examen, lo tengo asi:
Código Delphi [-]

procedure TForm5.BitBtn1Click(Sender: TObject);
var
  a:integer;
  begin
    with datamodule2.FDQuery6 do
    begin
      close;
      sql.Text:='SELECT ced_est FROM eva_estudiantes WHERE ced_est=:cedes';
      ParamByName('cedes').Value:='i';
      open;
      begin
        close;
        sql.Text:='INSERT INTO eva_maestro (nombre_examen,fecha_ini,fecha_fin,nota) VALUES (:nomex,:feini,:fefin,:not)';
        ParamByName('nomex').Value:=edit1.Text;
        ParamByName('feini').value:=formatdatetime('YYYY-MM-DD',DateTimePicker1.Date);
        ParamByName('fefin').value:=formatdatetime('YYYY-MM-DD',DateTimePicker2.Date);
        Parambyname('not').Value:=combobox2.Text;
        ExecSQL;
        close;
        sql.Text:='SELECT max(id_exa) as ultimo FROM eva_maestro';
        open;
        a:=FieldByName('ultimo').AsInteger;
        close;
        sql.Text:='INSERT INTO eva_detalle (id_exama,pregunta,tipo_pregunta,Opcion1,Opcion2,Opcion3,Opcion4,respuesta,puntos) SELECT '+
                      inttostr(a)+',pregunta,tipo_pregunta,Opcion1,Opcion2,Opcion3,Opcion4,respuesta,puntos FROM eva_estudiantes WHERE ced_est=:cedes';
        ParamByName('cedes').Value:='i';
        ExecSQL;
        close;
        sql.Text:='TRUNCATE eva_estudiantes';
        execsql;
        datamodule2.FDQuery5.close;
        datamodule2.FDQuery5.close;
        limpiar;
      end;
    end;
     begin
        with datamodule2.FDQuery3 do
       begin
       close;
        sql.Text:='SELECT * FROM eva_maestro WHERE id_exa=:idex';
       ParamByName('idex').value:=edit3.Text;
        open;

        if not isempty then
            begin
            sql.Text:='UPDATE eva_maestro SET id_exa=:idex,nombre_examen=:nomex,nota=:not,fecha_ini:fini,fecha_fin=:ffin';
            parambyname('idex').Value:=edit3.Text;
            ParamByName('nomex').Value:=edit1.Text;
            ParamByName('feini').value:=formatdatetime('YYYY-MM-DD',DateTimePicker1.Date);
            ParamByName('fefin').value:=formatdatetime('YYYY-MM-DD',DateTimePicker2.Date);
            Parambyname('not').Value:=combobox2.Text;
            ExecSQL;
            datamodule2.FDQuery3.Transaction.Commit;
            ExecSQL;
            Datamodule2.FDQuery3.Transaction.Commit;
            datamodule2.FDQuery3.SQL.Text:='select * from eva_maestro' ;
            end;
       end;
    end;
end;
Pero algo no esta bien porque me sigue creando un registro nuevo, no me modifica. Que le falta al código? o será que tengo algo que no debe ir?

Neftali [Germán.Estévez] 28-03-2017 16:45:44

Para código Delphi, utilizad las etiquetas adecuadas.
Gracias.

yuyidt 28-03-2017 17:25:38

disculpa neftali
 
pero no se como hacerlo

ecfisa 28-03-2017 17:38:49

Cita:

Empezado por yuyidt (Mensaje 514821)
pero no se como hacerlo

Hola.

Como usar las etiquetas:



Saludos :)

yuyidt 28-03-2017 17:55:55

Gracias ecfisa. Siempre tan amable

yuyidt 28-03-2017 17:59:55

si me pueden ayudar con esto por favor
 
utilizo update para modificar registros pero me sigue apareciendo uno nuevo, ayuda por favor

Código Delphi [-]
procedure TForm5.BitBtn1Click(Sender: TObject);
var
  a:integer;
  begin
    with datamodule2.FDQuery6 do
    begin
      close;
      sql.Text:='SELECT ced_est FROM eva_estudiantes WHERE ced_est=:cedes';
      ParamByName('cedes').Value:='i';
      open;
      begin
        close;
        sql.Text:='INSERT INTO eva_maestro (nombre_examen,fecha_ini,fecha_fin,nota) VALUES (:nomex,:feini,:fefin,:not)';
        ParamByName('nomex').Value:=edit1.Text;
        ParamByName('feini').value:=formatdatetime('YYYY-MM-DD',DateTimePicker1.Date);
        ParamByName('fefin').value:=formatdatetime('YYYY-MM-DD',DateTimePicker2.Date);
        Parambyname('not').Value:=combobox2.Text;
        ExecSQL;
        close;
        sql.Text:='SELECT max(id_exa) as ultimo FROM eva_maestro';
        open;
        a:=FieldByName('ultimo').AsInteger;
        close;
        sql.Text:='INSERT INTO eva_detalle (id_exama,pregunta,tipo_pregunta,Opcion1,Opcion2,Opcion3,Opcion4,respuesta,puntos) SELECT '+
                      inttostr(a)+',pregunta,tipo_pregunta,Opcion1,Opcion2,Opcion3,Opcion4,respuesta,puntos FROM eva_estudiantes WHERE ced_est=:cedes';
        ParamByName('cedes').Value:='i';
        ExecSQL;
        close;
        sql.Text:='TRUNCATE eva_estudiantes';
        execsql;
        datamodule2.FDQuery5.close;
        datamodule2.FDQuery5.close;
        limpiar;
      end;
    end;
     begin
        with datamodule2.FDQuery3 do
       begin
       close;
        sql.Text:='SELECT * FROM eva_maestro WHERE id_exa=:idex';
       ParamByName('idex').value:=edit3.Text;
        open;

        if not isempty then
            begin
            sql.Text:='UPDATE eva_maestro SET id_exa=:idex,nombre_examen=:nomex,nota=:not,fecha_ini:fini,fecha_fin=:ffin';
            parambyname('idex').Value:=edit3.Text;
            ParamByName('nomex').Value:=edit1.Text;
            ParamByName('feini').value:=formatdatetime('YYYY-MM-DD',DateTimePicker1.Date);
            ParamByName('fefin').value:=formatdatetime('YYYY-MM-DD',DateTimePicker2.Date);
            Parambyname('not').Value:=combobox2.Text;
            ExecSQL;
            datamodule2.FDQuery3.Transaction.Commit;
            ExecSQL;
            Datamodule2.FDQuery3.Transaction.Commit;
            datamodule2.FDQuery3.SQL.Text:='select * from eva_maestro' ;
            end;
       end;
    end;
end;
Pero algo no esta bien porque me sigue creando un registro nuevo, no me modifica. Que le falta al código? o será que tengo algo que no debe ir?

Neftali [Germán.Estévez] 28-03-2017 20:11:46

Con este código que tienes siempre va a pasar por el INSERT.
Haces una búsqueda con un SELECT, realizas el Open, luego cierras y luego haces un INSERT.
Siempre va a pasar por ahí.

Código Delphi [-]
with datamodule2.FDQuery6 do
    begin
      close;
      sql.Text:='SELECT ced_est FROM eva_estudiantes WHERE ced_est=:cedes';
      ParamByName('cedes').Value:='i';
      open;
      begin
        close;
        sql.Text:='INSERT INTO eva_maestro (nombre_examen,fecha_ini,fecha_fin,nota) VALUES (:nomex,:feini,:fefin,:not)';
        ParamByName('nomex').Value:=edit1.Text;
        ParamByName('feini').value:=formatdatetime('YYYY-MM-DD',DateTimePicker1.Date);
        ParamByName('fefin').value:=formatdatetime('YYYY-MM-DD',DateTimePicker2.Date);
        Parambyname('not').Value:=combobox2.Text;

Tal vez no acabo de entender muy bien lo que quieres hacer.
Lo lógico tal vez sería hacer el SELECT y después de hacer el Open, preguntar si lo ha encontrado o no para hacer un INSERT o un UPDATE.
Algo así:

Código Delphi [-]
  FDQuery6.sql.text :='SELECT * ...'
  FDQuery6.Open;
  // No ha encontrado ninguno?
  if (FDQuery6.isEmpty) then begin
    // Aqui hago el INSERTY
    ....
  end
  else begin
    // Si llega aquí, es que lo ha encontrado, por lo tanto hago el UPDATE
    ...
  end;

  ...

ecfisa 28-03-2017 20:14:13

Hola yuyidt.

Es que la modificación de un registro debería ser simplemente algo similar a esto,
Código Delphi [-]
...
begin
  with datamodule2  do
  begin
    // Preparar la consulta de actualización
    FDQuery3.Close;
    FDQuery3.SQL.Clear;
    FDQuery3.SQL.Add('UPDATE EVA_MAESTRO SET NOMBRE_EXAMEN = :NOMEX,');
    FDQuery3.SQL.Add('NOTA = :NOT, FECHA_INI = :FINI, FECHA_FIN = :FFIN');
    FDQuery3.SQL.Add('WHERE ID_EXA = :IDEX');

    // Asignar valores a los parámetros
    ParamByName('NOMEX').AsString := Edit1.Text;
    Parambyname('NOT').AsString   := ComboBox2.Text;
    ParamByName('FINI').AsDate    := DateTimePicker1.Date;
    ParamByName('FFIN').AsDate    := DateTimePicker2.Date;
    ParamByName('IDEX').AsString  := Edit3.Text;  // clave única o campo ID
   
    // Ejecutar la consulta
    FDQuery3.ExecSQL;
  end;
end;
y no ejecutar una inserción previamente...

Saludos :)

edito: ( Mientras escribía este, Neftalí ya te había indicado lo mismo :) )

yuyidt 28-03-2017 20:35:20

Ok, no se si me explique bien,
el query6 esta conectado a la tabla temporal que es donde se van guardando las preguntas mientras no he guardado el examen.
query3 esta conectado con la tabla eva_maestro.
Si busco un examen y existe, quiero poder agregar mas preguntas a dicho examen, (recordando que estas preguntas se van guardando en tabla temporal, así que para el update creo que necesitare ambos querys - el 3 y el 6)
pero no se como implementar el uso de los 2 query.
Por ejemplo,
en fdquery3 busco el examen y si existe entonces agrego mas preguntas(las cuales se van agregando a tabla de fdquery6)
cuando voy a guardar el examen, necesito saber si la tabla temporal(fdquery6), tiene registros, si es así entonces:
- actualizo el examen
- y envío los registros de tabla temporal a eva_detalle(que es donde están todas las preguntas)

ecfisa 28-03-2017 21:28:38

Hola.

Ví las definiciones de tablas en este hilo: modificar tablas maestro_detalle.

Pero no logro entender la lógica con que estas implementando la relación master-detail. Es decir, si ya completaste los datos referentes a la evaluación (maestro), sólo deberías ir agregando los datos de las preguntas en la tabla detalle con su campo de relación (ID_EXAMA) apuntando a la evaluación correspondiente.

Si tu problema es que todavía no has guardado la fila en la tabla EVA_MAESTRO y por tanto no tienes su ID, en estos enlaces se habla del tema :De no encontrar una solución en los enlaces anteriores, especifica con mas detalle la lógica de la relación y el gestor de base de datos con que estas trabajando.

Saludos :)

yuyidt 28-03-2017 23:25:44

ok, agregue el siguiente codigo para modificar el examen:

Código Delphi [-]
procedure TForm5.BitBtn4Click(Sender: TObject);
begin
  with DataModule2.FDQuery16 do
  begin
    Close;
    SQL.Clear;
    SQL.Add('UPDATE eva_maestro');
    SQL.Add('SET nombre_examen = :nomex, fecha_ini = :fini,');
    SQL.Add('fecha_fin = :ffin, nota = :not');
    SQL.Add('WHERE id_exa = :idex');
    ParamByName('nomex').AsString := Edit1.Text;
    ParamByName('fini').AsDate       := DateTimePicker1.Date;
    ParamByName('ffin').AsDate       := DateTimePicker2.Date;
    ParamByName('not').AsString          := ComboBox2.Text;
    ParamByName('idex').AsString       := edit3.Text;
    ExecSQL;
  end;
end;
actualiza el examen muy bien,
el asunto es que como le agrego nuevas preguntas a dicho examen? (Recordando que las preguntas se guardan en la tabla temporal eva_estudiantes, dicha tabla conectada al fdquery6).
agrego varias preguntas y se guardan en esa tabla temporal, quiero que cuando actualice el examen, las preguntas de la tabla temporal, se pasen a eva_detalle con el id del examen que se muestra en el edit 3.

ecfisa 29-03-2017 03:52:54

Hola.
Cita:

Empezado por yuyidt (Mensaje 514858)
...
el asunto es que como le agrego nuevas preguntas a dicho examen? (Recordando que las preguntas se guardan en la tabla temporal eva_estudiantes, dicha tabla conectada al fdquery6).
agrego varias preguntas y se guardan en esa tabla temporal, quiero que cuando actualice el examen, las preguntas de la tabla temporal, se pasen a eva_detalle con el id del examen que se muestra en el edit 3.

Me refiero a que la tabla maestro no debe modificarse a cada nueva pregunta, sino que cada nueva pregunta debe agregarse a la tabla detalle poniendo en el campo referente, el correspondiente ID de la tabla maestro, graficando:

Tabla MAESTRO:
Código:

ID    |  CAMPO_1  | CAMPO_N
------+-------------+--------
 1    |  wwww      | xxxx
 2    |  yyyy      | zzzz 
...

Tabla DETALLE:
Código:

ID    |  CAMPO_1  | CAMPO_N | COL_REFER
------+-------------+---------+----------
 1    |  aaaa      | bbbb    |  1
 2    |  cccc      | dddd    |  1
 3    |  eeee      | ffff    |  2 
 4    |  gggg      | hhhh    |  3
...

Donde la referencia queda establecida en la tabla DETALLE mediante la columna COL_REFER que contiene los valores ID de la tabla MAESTRO.

Luego y a modo de ejemplo, si desearamos consultar la información de todas las preguntas pertenecientes a determinada línea de la tabla MAESTRO, ejecutando la consulta:
Código SQL [-]
SELECT * 
FROM DETALLE 
WHERE COL_REFER = :IDMASTER
con el valor "1" en el parámetro IDMASTER, obtendríamos:
Código:

ID    |  CAMPO_1  | CAMPO_N | COL_REFER
------+-------------+---------+----------
 1    |  aaaa      | bbbb    |  1
 2    |  cccc      | dddd    |  1

Saludos :)


La franja horaria es GMT +2. Ahora son las 12:03:26.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi