Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Evitar un Key Violation (https://www.clubdelphi.com/foros/showthread.php?t=6596)

sitrico 14-01-2004 15:05:15

Evitar un Key Violation
 
Buenas, Estoy retocando una aplicación y quisiera verificar ANTES DE QUE OCURRA la validez de una clave, me explico:

Visitando los foros encontré que una de las maneras de manejar la excepción del Key Violation era:

Código:

Try
    db.Post;
Except
  Mensaje....
End;

Ahora bien, manejarlas de esa manera me obligaría a crear un bloque Try..Excep en cada post de la aplicación. Preferiría usar los eventos de la base de datos OnPostError o mejor OnBeforePost para validar la clave antes de que se genere la excepción. Tengo la dificultad adicional de que parte de la base de datos está filtrada y hay claves ocultas.

¿ Existe alguna función como Function IsValidKey(Registro o clave):Boolean (o algo así) que permita llamar a la BDE para que se verifique la validez de la clave ?

El código debe ser algo así:

Código:

Evento On BeforePost

If Not(IsValidKey(Registro acual)) Then
  Begin
  // Mensaje de clave duplicada
  Abort; // pero debe seguir el insert o edit
  End;


__cadetill 14-01-2004 15:10:23

Existir, no existe, que yo sepa, lo que puedes hacer es en BeforePost lanzar una query sobre la tabla y en el where poner la clave y mirar si devuelve o no registros

o bien utilizar el evento OnPostError y mirar el código de error que devuelve para saber si es debido a un key violation

eduarcol 14-01-2004 16:18:06

No se si te entendi mal, pero lo que tu pides es algo tan facil como crear una funcion donde haces el bloque try ... except para la tabla que le pases por parametro, y al momento de grabar no llamas al post sino a la funcion que te devolvera true si se ejecuto o false si fallo, en el except debes capturar el error en un objeto EDBEngineError

te doy un ejemplo

function Mi Grabado(MiTabla: TTable): Boolean
begin
try
T.Post;
except
on E: EDBEngineError do
begin
ErrorCode := E.Errors[0].ErrorCode;
case ErrorCode of
//distintos casos de error(busca la ayuda)
end
end
end


al llamarla funcionara algo asi
if MiGrabado(Tabla) then


Me parece la solucion mas facil

delphi.com.ar 14-01-2004 16:21:58

O... conociendo la PK puedes preguntar si no existe algún registro con estos datos, esto evitaría que se produzca el error.

Saludos!

roman 14-01-2004 16:35:31


Me gustaría agregar, respecto de la pregunta original, que en mi opinión los errores de violación de acceso no deben tratarse mediante bloques try-except. Son errores graves que puden dejar inestable a la aplicación o a la pc y es mejor revisar qué los causa y retocar el código para que no sea así (verificar que los punteros u objetos no sean nil, que no referenciemos índices de arreglos inválidos, etc,)


Por favor olviden esto. Me confundí entre "Access Violation" y "Key Violation"

// Saludos

marcoszorrilla 14-01-2004 16:58:21

Aquí tienes los códigos más interesantes de error y un ejemplo de como manipular el "KeyViol", yo lo que hago es definir un Procedimiento y le llamo desde cualquier postError de cualquier tabla para evitar la repetición del mismo código.
Código:

const
  eKeyViol = 9729;
  eRequiredFieldMissing = 9732;
  eForeignKey = 9733;
  eDetailsExist = 9734;
  eSqlGralerror = 13059;
 implementation
 
 {$R *.DFM}
 
 procedure TForm1.Table1PostError(DataSet: TDataSet; E: EDatabaseError;
  var Action: TDataAction);
 begin
  if (E is EDBEngineError) then
    if (E as EDBEngineError).Errors[0].Errorcode = eKeyViol then
    begin
    Application.MessageBox('Imposible dar alta ese registro ya existe','Atención',mb_Ok +
    mb_IconQuestion);
    Abort;
  end;
 end;

Un Saludo.

sitrico 16-01-2004 21:45:11

Gracias a todos, opté por la solución de marcoszorrilla porque validar usando un query antes de cada post no debe ser muy bueno para el rendimiento ;-)

lroblesco 16-03-2005 03:40:04

Key volation
 
Saludos
tengo un problemilla cuando se repiten las claves,
Cita:

Empezado por marcoszorrilla
Aquí tienes los códigos más interesantes de error y un ejemplo de como manipular el "KeyViol", yo lo que hago es definir un Procedimiento y le llamo desde cualquier postError de cualquier tabla para evitar la repetición del mismo código.
Código:

  const
    eKeyViol = 9729;
    eRequiredFieldMissing = 9732;
    eForeignKey = 9733;
    eDetailsExist = 9734;
    eSqlGralerror = 13059;
  implementation
 
  {$R *.DFM}
 
  procedure TForm1.Table1PostError(DataSet: TDataSet; E: EDatabaseError;
    var Action: TDataAction);
  begin
    if (E is EDBEngineError) then
      if (E as EDBEngineError).Errors[0].Errorcode = eKeyViol then
      begin
      Application.MessageBox('Imposible dar alta ese registro ya existe','Atención',mb_Ok +
      mb_IconQuestion);
      Abort;
    end;
  end;

Un Saludo.

Saben pongo el codigo como este, y me salta la excepcion, y en el debugger option escojo que no se detenga en las excepciones. Me sale un error mas o menos asi "Los cambios solicitados en la tabla.......' que puedo hecer? manejo una BD Access 2000 gracias

marcoszorrilla 16-03-2005 14:25:18

Aclarar que la rutina que yo facilité en su día es para el BDE, Paradox fundamentalmente, por lo cual no servirá para Access.

Un Saludo.

Ing Harry 01-06-2005 18:06:47

Algo Similar
 
Saludos

Tengo Un Problema Al Validar Llaves Primarias. Resulta Que Yo Hice Una Aplicacion Que Se Alimenta A Partir De Archivos Planos. Yo Valido Usando Una Consulta Que Toma Cada Linea Y La Consulta En La Tabla, En Caso De Que Su Llave Este Duplicada, El Sistema La Actualiza Con Los Demas Campos, En Caso Contrario Crea Un Nuevo Registros Con Estos Datos. El Problema Es Que Al Cargar Un Archivo Con Muchos Registros El Sistema Se Me Pone Lento. Estoy Convencido Que El Problema Radica En La Forma De Validar. Que Me Recomiendan Ustedes Hacer Para Mejorar El Rendimiento.

Agradezco La Atencion.

Atentamente
Ing Harry :d :d :d


La franja horaria es GMT +2. Ahora son las 15:36:08.

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