Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-06-2004
CHiCoLiTa CHiCoLiTa is offline
Miembro
 
Registrado: may 2003
Posts: 102
Poder: 21
CHiCoLiTa Va por buen camino
Key violation. Continuar con siguiente registro

Hola,

Estoy copiando datos de unas tablas a otras, en SQL Server usando ADO en Delphi 6.

Como las tablas estan en distintas bases de datos, voy recoriendo los registros deseados y asignandoselos a los campos que quiero.

Cuando se va a copiar un registro duplicado, trato la excepcion en el OnPostError, aviso de que registro se trata, hago un rollback y termino con un abort. Todo bien

Mi pregunta es la siguiente.

Hay algun modo de tratar la excepcion indicandole cual es el registro que no se ha podido copiar, pero no parar el programa y seguir con la copia del resto de registros?
Responder Con Cita
  #2  
Antiguo 18-06-2004
Avatar de cbrrr
cbrrr cbrrr is offline
Miembro
 
Registrado: jun 2004
Posts: 57
Poder: 20
cbrrr Va por buen camino
En lugar de usar el OnPostError, puedes usar contro de excepciones

Código Delphi [-]
 while not tabla1.eof do
 begin
   //asignamos los campos o montamos sentencia SQL de Insert (casi preferible)
   try
     Query.ExecSQL; // o bien Tabla2.Post;
   except
     // si el dato está duplicado, salta la excepción pero el bucle continua
   end;
 end;

Espero que te sirva
__________________
Si no tienes algo que decir más importante que el silencio, cállate
Responder Con Cita
  #3  
Antiguo 18-06-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Hola chicolita!.

Cita:
Empezado por chicolita
Hay algun modo de tratar la excepcion indicandole cual es el registro que no se ha podido copiar
¿¿¿Indicandole a quien, o donde????
__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #4  
Antiguo 18-06-2004
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por jachguate
¿¿¿Indicandole a quien, o donde????
Yo supongo que se refiere a guardar en algún archivo log la lista de registros duplicados, lo cual puede hacer entre el except y el end de la solución que plantea cbrrr.

// Saludos
Responder Con Cita
  #5  
Antiguo 19-06-2004
CHiCoLiTa CHiCoLiTa is offline
Miembro
 
Registrado: may 2003
Posts: 102
Poder: 21
CHiCoLiTa Va por buen camino
Creo que me he expresado un poco mal. Escribi el mensaje un poco deprisa.
En ese volcado de datos en teoria no tiene que haber ni un solo duplicado. Pero para eso existe el usuario, para crear duplicados y hacernos la vida mas dificil.

Cuando detecto un error de clave duplicada, capturo la excepcion, hago un rollback para que cuando el error este corregido puedan empezar el proceso de nuevo, cierro las querys... y muestro en una ventana de dialogo cual es el registro que esta duplicado y termino con Abort, y como salta excepcion se para el proceso de volcado.

Los usuarios han de revisar ese registro para no volcarlo, y volver a empezar el proceso

Todo esto esta bien, y no hay ningun problema. Lo que quiero saber es si el volcado puede seguir haciendose automaticamente saltandose ese registro despues de indicar en la ventana de dialogo cual era. Que la excepcion se detectada y mostrada, pero NO INTERRUMPA la ejecucion del programa

cbrrr, cuando digo que trato la excepcion en el OnPostError, evidentemente hago el try, except, que es lo mismo hacerlo alli que donde me indicaste. Personalmente prefiero ponerla alli para ir separando codigo y tenerlo separado por funciones pequeñas

Última edición por CHiCoLiTa fecha: 19-06-2004 a las 14:04:57.
Responder Con Cita
  #6  
Antiguo 19-06-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Para que el proceso siga normal podrias hacer algo como:

Código Delphi [-]
IniciarTransaccion;
while not eof Table1 do
Begin
  try
    InsertarRegistroActual;
  except
    on RegistroDuplicado do
    Begin
      Table2.cancel;  // para cancelar la inserción iniciada y dejarle en status dsBrowse
      ShowMessage('Registro duplicado!');
    End;
  end;
  Table1.Next;
end;
commit;

Sin hacer abort, ni rollback... de esa manera "matas" la excepción y continua normalmente el ciclo.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #7  
Antiguo 19-06-2004
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por CHiCoLiTa
Todo esto esta bien, y no hay ningun problema. Lo que quiero saber es si el volcado puede seguir haciendose automaticamente saltandose ese registro despues de indicar en la ventana de dialogo cual era. Que la excepcion se detectada y mostrada, pero NO INTERRUMPA la ejecucion del programa
Como dice jachguate no veo necesidad para hacer ningún rollback, tal como lo estructura él es más que suficiente. No obstante creo que no tiene caso mostrar el registro duplicado cada vez ya que esto de cualquier manera detiene el proceso mientras el usuario oprime OK. Para mi lo mejor sería crearte una tabla auxiliar para guadar los registros duplicados. Sería una tabla con la misma estructura que la que estás procesando pero sin la restricción de la clave duplicada. Cada vez que el ciclo te detecte un registro duplicado en el try-except, guardas una copia de este registro en la tabla auxiliar y continuas sin mandar ningún mensaje al usuario. Cuando termine el proceso le presentas un grid con los registros que quedaron en la tabla auxiliar.

// Saludos
Responder Con Cita
  #8  
Antiguo 23-06-2004
CHiCoLiTa CHiCoLiTa is offline
Miembro
 
Registrado: may 2003
Posts: 102
Poder: 21
CHiCoLiTa Va por buen camino
El rollback lo hacia, porque si el proceso se para por clave duplicada y la ejecucion del programa termina, cuando vuelven a empezar todos los registros ya estarian duplicados porque los copio en la primera pasada.

Y el abort, para evitar que me muestre el mensaje de error, y mostrar el que yo quiera, no los 2

Al hacer lo que me comento jachguate, el programa sigue parando al encontrar un duplicado

Este es el codigo que tengo puesto ahora mismo para hacer las pruebas con lo que me dijeron, por si veis algo anormal

Código Delphi [-]
procedure TDataModule2.TCt_totalPostError(DataSet: TDataSet;
  E: EDatabaseError; var Action: TDataAction);
var
   Texto : string;
begin
   if (E is EDatabaseError) then
     if Pos('PRIMARY KEY', UpperCase(E.Message)) <> 0 then
     begin
        Texto := 'Duplicado el registro con ID: ' + QEasy.FieldByName('ID_CT').AsString;
        Application.MessageBox(PChar(Texto), 'Registro duplicado',mb_Ok+MB_ICONEXCLAMATION);
        TCT_TOTAL.cancel;
     end;
end;

QEasy es la tabla origen
TCT_TOTAL es la talba destino
Conexion con ADO y las 2 tablas estan en diferentes bases de datos, por eso no hago el insert

De este modo es como copio los datos de una tabla a otra

Código Delphi [-]
           while not QEasy.Eof do
           begin
              TCT_TOTAL.Append;
              for i := 0 to QEasy.Fields.Count - 1 do
                  TCT_TOTAL.Fields[i].Value := QEasy.Fields[i].Value;
              TCT_TOTAL.Post;
              QEasy.Next;
           end;

Última edición por CHiCoLiTa fecha: 23-06-2004 a las 16:29:37.
Responder Con Cita
  #9  
Antiguo 23-06-2004
Avatar de marto
marto marto is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona, Catalunya
Posts: 882
Poder: 21
marto Va por buen camino
Código Delphi [-]
   while not QEasy.Eof do
   begin
      TCT_TOTAL.Append;
      for i := 0 to QEasy.Fields.Count - 1 do
          TCT_TOTAL.Fields[i].Value := QEasy.Fields[i].Value;
      try
        TCT_TOTAL.Post;
      except
        on E: EDatabaseError do
        begin
          if Pos('KEY VIAOLATION', E.Message) > 0) then
          begin
            Texto := 'Duplicado el registro con ID: ' + QEasy.FieldByName('ID_CT').AsString;
            Application.MessageBox(PChar(Texto), 'Registro duplicado',mb_Ok+MB_ICONEXCLAMATION);
            TCT_TOTAL.cancel;
          end else
            raise;
        end;
      end;
      QEasy.Next;
   end;

Lo que quieren decir los compañeros es esto... y cárgate el OnPostError
__________________
E pur si muove
Responder Con Cita
  #10  
Antiguo 23-06-2004
CHiCoLiTa CHiCoLiTa is offline
Miembro
 
Registrado: may 2003
Posts: 102
Poder: 21
CHiCoLiTa Va por buen camino
Pues si que soy duro de mollera Ya lo decia mi madre
No lo veia, y lo tenia hecho. Ahora que me has abierto los ojos marto, ya entiendo todo

Al hacer yo mismo el try except, controlo directamente la excepcion, pero si lo hago en el OnPostError, el programa ya lo ha detenido haciendo directamente el raise. Es mas o menos correcto este razonamiento?

Muchas a gracias a todos
Responder Con Cita
  #11  
Antiguo 24-06-2004
Avatar de marto
marto marto is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona, Catalunya
Posts: 882
Poder: 21
marto Va por buen camino
Cita:
Empezado por CHiCoLiTa
Es mas o menos correcto este razonamiento?
Po sí, el razonamiento es ese
__________________
E pur si muove
Responder Con Cita
  #12  
Antiguo 14-02-2007
Alejandro Ruiz Alejandro Ruiz is offline
Registrado
 
Registrado: feb 2007
Posts: 1
Poder: 0
Alejandro Ruiz Va por buen camino
Yo tengo un problema parecido, un mensaje de SQL de error al duplicar la llave primaria, sin embargo trato de cachar el error en el OnPostError y no me lo toma en cuenta , ayudenme!!!!

Última edición por Alejandro Ruiz fecha: 14-02-2007 a las 21:51:38.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 21:47:09.


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
Copyright 1996-2007 Club Delphi