Ver Mensaje Individual
  #2  
Antiguo 11-05-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Reputación: 31
Lepe Va por buen camino
Ahhh, que estas usando Firebird.... pues esos tipos de errores pasaron a la historia amigo.

Una de las formas puede ser esta:
- En la base de datos indicas que el campo es NOT NULL.
- En tu aplicación colocas un ApplicationEvents
- En el evento OnException del applicationsEvents añades el siguiente código.

La filosofía: Al ser NOT NULL, firebird lanzará una excepción cuando se intenta guardar un campo sin valor e indica el siguiente mensaje:
"Violation of constraint FK_FACTURA" (lo digo de memoria)

Lo que hacemos, en el ApplicationEvents, es interceptar la excepción, buscar la palabra "FK_FACTURA" y si está en el mensaje, mostramos nuestro texto en Español. Como es el objeto "Application" en ese evento centralizamos todos los errores de todas las tablas de nuestra aplicación, así usamos el mismo código para toda la Base de datos.

¿Qué es FK_FACTURA?
FK significa Foreign Key, significa que en la tabla FACTURA, se ha definido una clave ajena sobre un campo y este campo no puede ser nulo, así que Firebird crea una restricción (llamada Constraint). También se puede llamar PK_FACTURA, (Primary Key), es decir, en este caso significa que la clave primaria de la tabla FACTURA, no puede tener el valor nulo.

¿Cómo saber que la restricción se llama FK_FACTURA?
Usa el IbExpert, en la tabla que has definido el NOT NULL, aparece una pestaña constraint (restricción) sobre el campo en cuestión, si tienes varios, se llamarán FK_FACTURA_1, FK_FACTURA_2, etc, de ahí sacas el nombre.

En el ApplicationEvents-> OnException
Código Delphi [-]
const saltolinea = #10#13;
        saltodoble = saltolinea + saltolinea;


  if (e is EMDOError) then
  begin
    strDebug := 'SqlCode: ' +inttostr(EMDOError(E).SQLCode) + ' '+ E.ClassName;
    strMessage:=dtm.ParseError(EMDOError(E));
    dtm.log.Add(strMessage + saltolinea + strDebug);
  end;
    ShowMessage('Al usuario: ' + strMessage + saltodoble +
                'Mensaje de Debug: ' + strDebug + saltodoble );

Las funciones de ayuda son:
Código Delphi [-]
type Restriccion= record
      Nombre:string;
      Mensaje:string;
end;
const iRestricciones = 8;
var RestriccionesBD : array [1..iRestricciones,0..1] of string =
        (('FK_ENTREGA_3', 'El Tipo de pago no se puede borrar, se ha usado en una entrega'),
         ('FK_FACTURA_1', 'El Proveedor no se puede borrar, se ha usado en una Factura'),
         ('FK_JORNAL_1', 'El Trabjador no se puede borrar, tiene jornales trabajados'),
         ('FK_OBRA_2', 'El Estado de la obra no se puede borrar, se ha usado en una obra'),
         ('FK_TRABAJADOR_1','La Categoría no se puede borrar, un Trabajador la tiene asignada'),
         ('FK_TRABAJADOR_2', 'La Situación del trabajador no se puede borrar, se ha usado para otro trabajador'),
         ('FK_VENCIMIENTO_2','La Forma de pago no se puede borrar, se ha usado en un Vencimiento'),
         ('FK_VENCIMIENTO_4','El Proveedor no se puede borrar, ha sido usado en un Vencimiento.')
        );

function IsBDConstraint(ExpMessage:string; var SpanishError:string): Boolean;
var i:Integer;
begin
  Result:= False;
  for I := low(RestriccionesBD) to high(RestriccionesBD) do
    if Pos(restriccionesBD[i,0],ExpMessage)<> 0 then
    begin
      Result := True;
      SpanishError := restriccionesbd[i,1];
      Break;
  end;

end;

function Tdtm.ParseError(E: EMDOError):string;
const numeros = ['0'..'9'];
var  idx:Integer;
      strError:string;
begin
  Result := E.Message;
  if IsBDConstraint(E.Message, strError) then
  begin
    Result := strError;
  end
  else if e.SQLCode = -836 then 
  begin  
// es una excepción lanzada desde la BD
// Ejemplo: "exception 1: La cantidad suministrada no es válida"
// quitamos el texto "exception 1:"
    idx := pos(saltolinea,Result);
    if (idx <> 0) and ( idx < 13) then
     Delete(Result,1,idx+1); //fuera el texto : "exception X " + CRLF
  end;
end;

Otra cosa, veo que buscas con un query si la placa ya existe en la BD, eso también pasó a la historia:
- Si es un campo clave primaria, no tendrás problema, ya que no permite duplicados, así que todo el código que he escrito arriba, contempla ese caso.

- Si el campo "placa" no es clave primaria, define un índice único sobre él, así Firebird lanzará un mensaje de error cuando intentes guardar una placa repetida. Se deduce por tanto, que este caso también se contempla con el código de arriba.

Como ves, haciendo ese código una sola vez manejas todos los errores posibles sin tener que hacer virguerías.

En resumen, todo el código funcionaría en tu aplicación, lo único que tienes que modificar la variable RestriccionesBD para añadir tus restricciones, y cambiar la constante iRestricciones.

Saludos y espero que se entienda, si no es así, dime algo en este hilo.
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.

Última edición por Lepe fecha: 11-05-2007 a las 13:21:34.
Responder Con Cita