PDA

Ver la Versión Completa : Update duplica registro


FerCastro
27-10-2008, 02:18:54
Hola al foro,

Tengo una pequeña aplicación la cual estaba trabajando aparentemente bien hasta hace unos dias que comenzó a hacer algo sumamente extraño.

Cuando quiero modificar los datos de un registro al momento de grabar me duplica el registro. No se que haya podido suceder para que esto sucediera, pues anteriormente no lo hacía. Alguna idea? dejo el código que tengo:



With Data.qEditaEmpleado do
Begin
Close;
SQL.Clear;
SQL.Add('SELECT * FROM empleado WHERE IDEmpleado = ' + IntToStr(Data.qEmpleado.FieldByName('IDEmpleado').AsInteger));
Open;
Edit;
FieldValues['IDEmpresa']:=FMain.oVariables.nEmpresa;
FieldValues['Apaterno']:=cPaterno.Text;
FieldValues['AMaterno']:=cMaterno.Text;
FieldValues['Nombre']:=cNombre.Text;
Post;
Close;
End;



Muchas gracias
Fernando Castro
México

marcoszorrilla
27-10-2008, 05:49:21
No se aprecia motivo para este fenómeno en el código que adjuntas, supongo que pueda deberse a algún evento que hace que el código se ejecute dos veces en vez de una ....?

Un Saludo.

FerCastro
27-10-2008, 14:36:50
Hola Marcos, gracias por tu atención. Fijate que el proceso no se ejeceuta dos veces, de hecho haciendo el debug inmediatamente después del post actualizo la vista de mi tabla y ahi esta ya duplicado el registro.

No tengo idea del por qué de este comportamiento, pero te comento que no lo hacía, lo comenzó a hacer de repente.

Saludos!!

poliburro
27-10-2008, 14:47:36
amigo, no te convendría más ejecutar un query?

marcoszorrilla
27-10-2008, 16:43:24
Esto me hace sospechar que algo le paso a la tabla, porque no la creas de nuevo y le traspasas los datos y pruebas a ver que pasa.

Un Saludo.

roman
27-10-2008, 16:51:07
Y, el registro duplicado, ¿es exactamente igual en todos sus campos? El campo IDEmpleado, ¿es un campo llave?.

// Saludos

egostar
27-10-2008, 17:07:19
Respuesta Repetida. :(

Parece que también aquí hay un problema de duplicados:D:D:D

Salud OS

egostar
27-10-2008, 17:11:14
Hola

Yo creo que deberias de validar que existan datos antes de hacer el edit.


with Data.qEditaEmpleado do begin
Close;
SQL.Clear;
SQL.Add('SELECT * FROM empleado WHERE IDEmpleado = ' + IntToStr(Data.qEmpleado.FieldByName('IDEmpleado').AsInteger));
Open;
if recordcount > 0 then begin //Validamos que existan datos y no editar un registro vacio.
Edit;
FieldValues['IDEmpresa']:=FMain.oVariables.nEmpresa;
FieldValues['Apaterno']:=cPaterno.Text;
FieldValues['AMaterno']:=cMaterno.Text;
FieldValues['Nombre']:=cNombre.Text;
Post;
end;
Close;
end;


Salud OS

FerCastro
27-10-2008, 19:56:55
Gracias por las respuestas:

- Egostar, ya hice lo que me comentas y sigue duplicando.
- Marcos, ya creé de nuevo la tabla, pasé los registros y sigue dulpicando.
- Román, si es un campo llave.

Gracias!! y saludos a todos

FCG

roman
27-10-2008, 20:02:29
¿¡¡¡Es un campo llave y aún así se duplica el registro!!!? ¿Pues qué gestor usas? :eek:

// Saludos

FerCastro
27-10-2008, 20:08:25
Román, el registro se duplica excepto en el campo llave. Pero en efecto, el campo llave es autoincrementable y toma el siguiente ID manteniendo todos los demás valores en un nuevo registro

BlueSteel
27-10-2008, 20:13:05
Gracias por las respuestas:

- Egostar, ya hice lo que me comentas y sigue duplicando.
- Marcos, ya creé de nuevo la tabla, pasé los registros y sigue dulpicando.
- Román, si es un campo llave.

Gracias!! y saludos a todos

FCG


mmm... extraño sintoma.... pero si IdEmpleado es un campo llave, no debiera duplicarte el registro o al menos deberia darte un error de duplicado...

Por que no haces un Refresh despues del post ??? a ver k tal..., o lo otro seia cambiar de forma de actualizar el registro...

With Datos Do
Begin
AQ_Actualiza.Close;
AQ_Actualiza.SQL.Clear;
AQ_Actualiza.SQL.Add('Update Empleado Set Emp_Empresa=:v01, Emp_Paterno=:v02, Emp_Materno=:v03, Emp_Nombre=:v04');
AQ_Actualiza.SQL.Add('Where Id_Empleado =:Var05');
AQ_Actualiza.Parameters[0].Value :=FMain.oVariables.nEmpresa;
AQ_Actualiza.Parameters[1].Value := cPaterno.Text;
AQ_Actualiza.Parameters[2].Value := cMaterno.Text;
AQ_Actualiza.Parameters[3].Value := cNombre.Text;
AQ_Actualiza.Parameters[4].Value :=Data.qEmpleado.FieldByName('IDEmpleado').AsInteger;
AQ_Actualiza.ExecSQL;
End;

bueno, no se con que componentes haces tu sentencia... el ejemplo anterior es usando SQL Server y ADO....

Salu2:p:D

FerCastro
28-10-2008, 00:41:04
Gracias, siguiendo los consejos de Poli y del Ego esto ya quedo arreglado:



cCadena := ' UPDATE empleado SET '+
' IDEmpresa = '+ QuotedStr(IntToStr(FMain.oVariables.nEmpresa))+
' , IDSucursal = '+ QuotedStr(IntToStr(FMain.oVariables.nSucursal))+
' , IDDepartamento = '+ QuotedStr(IntToStr(nIDDepartamento))+
' , IDPuesto = '+ QuotedStr(IntToStr(nIDPuesto))+
' , IDRegistro = '+ QuotedStr(cRegistro.Text)+
' , IDNomina = '+ QuotedStr(cNomina.Text)+
' , Apaterno = '+ QuotedStr(cPaterno.Text)+
' , AMaterno = '+ QuotedStr(cMaterno.Text)+
' , Nombre = '+ QuotedStr(cNombre.Text)+
' , NombreCompleto = '+ QuotedStr(TRIM(cPaterno.Text) + ' ' + TRIM(cMaterno.Text)+ ' ' + TRIM(cNombre.Text))+
' , CentroCostos = '+ QuotedStr(cCostos.Text)+
' , Sucursales = '+ QuotedStr(FDatosEmpleado.cSucursalesEvento)+
' , FNacimiento = '+ QuotedStr(DatetoStr(dCumple.Date))+
' , FIngreso = '+ QuotedStr(DatetoStr(dCumple.Date))+
' , Telefono = '+ QuotedStr(cTelefono.Text)+
' , Correoe = '+ QuotedStr(cCorreo.Text)+
' , Dir1 = '+ QuotedStr(cDir1.Text)+
' , Dir2 = '+ QuotedStr(cDir2.Text)+
' , Dir3 = '+ QuotedStr(cDir3.Text)+
' , CURP = '+ QuotedStr(cCURP.Text)+
' , Ciudad = '+ QuotedStr(cCiudad.Text)+
' , Estado = '+ QuotedStr(cEstado.Text)+
' , CP = '+ QuotedStr(cCP.Text)+
' , Activo = '+ QuotedStr(IntToStr(1))+
' , Usuario = '+ QuotedStr('FCastro')+
' , U_Fecha = '+ QuotedStr(DateToStr(now))+

' WHERE IDEmpleado = '+ QuotedStr(IntToStr(Data.qEmpleado.FieldByName('IDEmpleado').AsInteger));

With Data.qEditaEmpleado do
Begin
SQL.Text := cCadena;
ExecSQL;
end;



Ahora, porque lo metí a una cadena de texto? la verdad es que si no lo dejaba así el query no se ejecutaba, enigmas de la vida no?

Mil gracias a todos en el foro por la ayuda. "Agradezco a san poli por los favores y las ayudas recibidas"

Saludos!

FerCastro
28-10-2008, 18:26:23
Siguiendo con el mismo hilo, pero con diferente tema, estoy modificando los comandos que tenía por sentencias Update, pero tengo el siguiente problema:

Cuando quería registrar los cambios en un cambio datetime, tomando en cuenta solo la hora hacía esto:


FieldValues['HoraInicio1']:=TimeToStr(dsInicio1.Time);
FieldValues['HoraInicio2']:=TimeToStr(dsInicio2.Time);
FieldValues['HoraInicio3']:=TimeToStr(dsInicio3.Time);



Pero la momento de querer hacer lo mismo para generar la sentencia SQL, que queda así:


' , HoraInicio1 = '+ QuotedStr(TimeToStr(dsInicio1.Time))+
' , HoraInicio2 = '+ QuotedStr(TimeToStr(dsInicio2.Time))+
' , HoraInicio3 = '+ QuotedStr(TimeToStr(dsInicio3.Time))+


EL resultado en SQL queda asi:


HoraInicio1 = '09:00:00 a.m.' ,
HoraInicio2 = '04:00:00 p.m.' ,
HoraInicio3 = '12:00:00 a.m.'


Pero me manda el siguiente error :

Error de conversión al convertir una cadena de caracteres a datetime.

Quiero hacer la sentencia con un convert, por consejo de Poliburro, pero pues no doy pie con bola.

Alguien sabe que se tiene que hacer? por que no me está aceptando los datos en la sentencia SQl?

Muchas gracias por la ayuda

FCG

roman
28-10-2008, 18:31:35
Lo recomendado siempre en estos casos es usar parámetros y suplir su valor con los métodos adecuados al tipo:


Query1.ParamByName('HoraInicio1').AsDateTime := dsInicio1.Time


De esta forma le dejas el trabajo y pormenores de la conversión al componente en sí.

// Saludos

FerCastro
28-10-2008, 18:34:05
Hola Román,

La verdad es que nunca he usado parámetros, dónde puedo hallar un ejemplo pequeño de cómo hacerlo?

Gracias

Fernando

FerCastro
28-10-2008, 18:42:41
Hallé esto en el foro:


cadena := 'Update Documentos set doc_apel1=:apel1 ,doc_apel2=:apel2';
cadena := cadena + ', doc_nombre=:nombre';
cadena := cadena + ', usuario=:usu, fechagrab=:Fecha';
cadena := cadena + ' where doc_id=:id and doc_NH=:NH';
ADOQVarios.Active:=false;
ADOQVarios.SQL.Clear;
ADOQVarios.SQL.Add(cadena);
ADOQVarios.Parameters.ParamByName('id').DataType := ftInteger;
ADOQVarios.Parameters.ParamByName('id').Value :=cod;
ADOQVarios.Parameters.ParamByName('apel2').DataType := ftString;
ADOQVarios.Parameters.ParamByName('apel2').Value := eApe2.text;
ADOQVarios.Parameters.ParamByName('apel1').DataType := ftString;
ADOQVarios.Parameters.ParamByName('apel1').Value := eApe1.text;
ADOQVarios.Parameters.ParamByName('Nombre').DataType := ftString;
ADOQVarios.Parameters.ParamByName('Nombre').Value := eNombre.text;
ADOQVarios.Parameters.ParamByName('NH').DataType := ftInteger;
ADOQVarios.Parameters.ParamByName('NH').Value :=StrToInt(eNH.text);
ADOQVarios.Parameters.ParamByName('Fecha').DataType := ftDateTime;
ADOQVarios.Parameters.ParamByName('Fecha').Value := Now;
ADOQVarios.Parameters.ParamByName('Usu').DataType := ftString;
ADOQVarios.Parameters.ParamByName('Usu').Value :=MFunciones.GetLoginName;
ADOQVarios.ExecSQL;

Solo una pregunta, los parámetros se tiene que declarar todos y cada uno como variables?

Perdon por la pregunta, solo es una duda.

Saludos

Delphius
28-10-2008, 18:55:49
Se puede interpretar a los parámetros como unas variables especiales que luego serán sustituídas por los valores que se desean suministrar. Un parámetro se distingue en el SQL anteponiendo los dos puntos. Algo como:

SELECT tus_campos
FROM tu_tabla
WHERE Campo1 = :ElParametro

En este caso el parámetro se llama ElParametro.

Luego, se debe indicar de donde va obtener los datos el parámetro. Esto se hace con:

TQuery1.Params.ParamByName('NombreParametro').AsTipo := ....

Recomiendo la lectura de la ayuda que proporciona al respecto.
Como podrás comprobar, si haces unas búsquedas encontrarás muchos hilos que hablan al respecto.

Saludos,

FerCastro
28-10-2008, 18:57:02
Román y todos, muchas gracias por la ayuda, ya quedó.

Hoy aprendí algo, ya me puedo dormir tranquilo ;)

Perdón por las preguntas de párvulo, así pasa cuando uno apenas está aprendiendo.

FCG


cCadena := ' UPDATE segmento SET '+
' IDEmpresa = '+ QuotedStr(IntToStr(FMain.oVariables.nEmpresa))+
' , IDSucursal = '+ QuotedStr(IntToStr(FMain.oVariables.nSucursal))+
' , Nombre = '+ QuotedStr(csNombre.Text)+
' , Comentario = '+ QuotedStr(csComentario.Text)+
' , Lapsos = '+ QuotedStr(IntToStr(nLapsos))+
' , Usuario = '+ QuotedStr(FMain.oVariables.cUsuario)+
' , U_Fecha = '+ QuotedStr(DateToStr(Now))+
' , Juntar1 = '+ QuotedStr(FloatToStr (nsJuntar1.Value))+
' , Juntar2 = '+ QuotedStr(FloatToStr (nsJuntar2.Value))+
' , Juntar3 = '+ QuotedStr(FloatToStr (nsJuntar3.Value))+
' , Juntar4 = '+ QuotedStr(FloatToStr (nsJuntar4.Value))+
' , Juntar5 = '+ QuotedStr(FloatToStr (nsJuntar5.Value))+
' , Juntar6 = '+ QuotedStr(FloatToStr (nsJuntar6.Value))+
' , Juntar7 = '+ QuotedStr(FloatToStr (nsJuntar7.Value))+
' , Juntar8 = '+ QuotedStr(FloatToStr (nsJuntar8.Value))+
' , Juntar9 = '+ QuotedStr(FloatToStr (nsJuntar9.Value))+
' , Juntar10 = '+ QuotedStr(FloatToStr (nsJuntar10.Value))+

' , HoraInicio1 = :h1'+
' , HoraInicio2 = :h2'+
' , HoraInicio3 = :h3'+
' , HoraInicio4 = :h4'+
' , HoraInicio5 = :h5'+
' , HoraInicio6 = :h6'+
' , HoraInicio7 = :h7'+
' , HoraInicio8 = :h8'+
' , HoraInicio9 = :h9'+
' , HoraInicio10 = :h10'+

' , HoraFin1 = :f1'+
' , HoraFin2 = :f2'+
' , HoraFin3 = :f3'+
' , HoraFin4 = :f4'+
' , HoraFin5 = :f5'+
' , HoraFin6 = :f6'+
' , HoraFin7 = :f7'+
' , HoraFin8 = :f8'+
' , HoraFin9 = :f9'+
' , HoraFin10 = :f10'+
' Where IDSegmento = '+ QuotedStr(IntToStr(nIDSegmento)) ;

SQL.Clear;
SQL.Add(cCadena);
Parameters.ParamByName('h1').Value := dsInicio1.Time;
Parameters.ParamByName('h2').Value := dsInicio2.Time;
Parameters.ParamByName('h3').Value := dsInicio3.Time;
Parameters.ParamByName('h4').Value := dsInicio4.Time;
Parameters.ParamByName('h5').Value := dsInicio5.Time;
Parameters.ParamByName('h6').Value := dsInicio6.Time;
Parameters.ParamByName('h7').Value := dsInicio7.Time;
Parameters.ParamByName('h8').Value := dsInicio8.Time;
Parameters.ParamByName('h9').Value := dsInicio9.Time;
Parameters.ParamByName('h10').Value := dsInicio10.Time;

Parameters.ParamByName('f1').Value := dFin1.Time;
Parameters.ParamByName('f2').Value := dFin2.Time;
Parameters.ParamByName('f3').Value := dFin3.Time;
Parameters.ParamByName('f4').Value := dFin4.Time;
Parameters.ParamByName('f5').Value := dFin5.Time;
Parameters.ParamByName('f6').Value := dFin6.Time;
Parameters.ParamByName('f7').Value := dFin7.Time;
Parameters.ParamByName('f8').Value := dFin8.Time;
Parameters.ParamByName('f9').Value := dFin9.Time;
Parameters.ParamByName('f10').Value := dFin10.Time;


SQL.Text := cCadena;
ExecSQL;

egostar
28-10-2008, 19:06:52
Román y todos, muchas gracias por la ayuda, ya quedó.

Hoy aprendí algo, ya me puedo dormir tranquilo ;)

Perdón por las preguntas de párvulo, así pasa cuando uno apenas está aprendiendo.

FCG



Ya ves wey, y no querias usar parámetros :D:D:D

Salud OS

roman
28-10-2008, 19:17:01
De todas formas, yo no me quedaría tranquilo. La técnica original debe funcionar, además de que es más sencilla. El componente se encarga de generar la sentencia update. ¿De qué base de datos hablamos?

// Saludos

FerCastro
28-10-2008, 19:18:48
Ya ves wey, y no querias usar parámetros :D:D:D

Salud OS


No quería porque no sabía como, crees que a partir de ahora los voy a dejar de usar?

Gracias Eliseo!!

FerCastro
28-10-2008, 19:21:05
De todas formas, yo no me quedaría tranquilo. La técnica original debe funcionar, además de que es más sencilla. El componente se encarga de generar la sentencia update. ¿De qué base de datos hablamos?

// Saludos

Román, mira la verdad es que sigo pensando en lo mismo, hace dos días funcionaba perfectamente u un buen día decidió que ya no.

Uso MS SQL Server, Delphi 2007 y ADO, sencillo.

Saludos!!

FCG