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)
-   -   Control de excepciones (https://www.clubdelphi.com/foros/showthread.php?t=54079)

gorsan 08-03-2008 10:38:59

Control de excepciones
 
Hola a todos.
Aunque, creo, que lo que les voy a plantear es algo muy simple para la mayoria, para mi es complejo porque lo desconozco pero me encantaria poder manejar bien estas situaciones.

Trabajo con IBX6 y Delphi 7.
En el diseño de la base de datos tengo definidas algunas excepciones:
Código SQL [-]
CREATE EXCEPTION "MAL_DNI" 'DNI incorrecto. Debe estar comprendido entre 1 y 99999999.';
CREATE EXCEPTION "MAL_N_IDEN" 'Número incorrecto. Debe estar comprendido entre 1 y 99.';
entre otras.
Mi pregunta es ¿como lanzo una excepcion definida en la base de datos desde el código delphi?
Hasta ahora un codigo parecido al siguiente me bastaba:
Código Delphi [-]
procedure TForm1.BotonGrabarClick(Sender: TObject);
begin
   try
      //las acciones a proteger
   except
      //el lanzamiento de la excepcion en caso de error
     ShowMessage('Asignación incorrecta o repetida.');
     raise;
   end;
end;
Pero cuando en la tabla donde se añade el nuevo registro hay varios campos con la restriccion UNIQUE, necesito saber:
1 cual es el que da el error para lanzar una u otra
2 como lanzo las excepciones definidas por mi en la base de datos.

Muchas gracias por su tiempo.

Lepe 08-03-2008 10:49:04

Son dos cosas totalmente separadas.

Crea un trigger before Post en la tabla, verificas allí si el dni está comprendido entre el rango y si no lo está lanzas la excepción.

La filosofía es contraria a lo que piensas. Ahora te olvidas hacer las validaciones en el boton grabar en delphi, directamente dejas pasar los datos a la base de datos, y en los triggers adecuados, el SGBBDD hará saltar la excepción que tu quieras:

Trigger (hecho de memoria....):
Código SQL [-]
Create trigger Check_Valores for tabla before update active position 0
as
begin
  if (new.CampoDNI < 1 or new.CAmpoDNI > 99999999) then
   exception MAL_DNI;
end;

Al saltar la excepción, verás en delphi un MessageBox con el texto de la excepción.

PD: el usuario, a veces no sabe el dni para dar de alta el registro, deberías dejarle introducir un cero para esos casos especiales. Si no.... ya te lo pedirán ;).

Para estos 2 casos, yo no crearía una excepción, sino un "check constraint". Revisa la documentación de Firebird/IB.

Saludos

gorsan 08-03-2008 11:13:55

Muy amable por tu respuesta y respecto a lo del check constraint tienes razon. Lo estudiare.
Gracias Lepe.

gorsan 08-03-2008 12:18:43

Pero ¿como escribo el trigger si la excepcion se produce por la contravencion de un valor UNIQUE?

eduarcol 08-03-2008 14:07:48

Se supone que al definir un campo como unico el manejador de base de datos se encarga de lanzar esa excepcion

gorsan 08-03-2008 14:34:36

Ya. El sistema maneja todas las excepciones pero yo lo que quiero es lanzar mi propia excepcion para que el usuario la vea tal como yo quiero que la vea y lanzarle el mensaje que yo planifique. Da mas sensacion de control.

eduarcol 08-03-2008 15:00:54

Cita:

Empezado por gorsan (Mensaje 271731)
Ya. El sistema maneja todas las excepciones pero yo lo que quiero es lanzar mi propia excepcion para que el usuario la vea tal como yo quiero que la vea y lanzarle el mensaje que yo planifique. Da mas sensacion de control.

Eso que tu propones yo lo hice con el BDE, capturando la excepcion desde delphi, aqui esta el codigo para que te hagas una idea. Pero en Firebird he dejado que el manejador de base de datos se encargue de todo eso, menos trabajo para el programador.

Código Delphi [-]
try
         Result := True;
         T.Active := False;
         T.Exclusive := False;
         T.DatabaseName := cRutaDatos;
         T.TableName := NT;
         T.IndexName := Indices;
         T.Active := True;
      except
      on E: EDBEngineError do
      begin
         ErrorCode := E.Errors[0].ErrorCode;
         case ErrorCode of
            DBIERR_SYSFILEOPEN,
            DBIERR_SYSFILEIO,
            DBIERR_SYSCORRUPT,
            DBIERR_NOCONFIGFILE,
            DBIERR_CFGCANNOTWRITE,
            DBIERR_CFGMULTIFILE,
            DBIERR_REENTERED,
            DBIERR_CANTFINDIDAPI,
            DBIERR_CANTLOADIDAPI,
            DBIERR_CANTLOADLIBRARY,
            DBIERR_TEMPFILEERR,
            DBIERR_MULTIPLEIDAPI,
            DBIERR_SHAREDMEMCONFLICT:
               msgError( msErrorSistema + NT );
            DBIERR_LOCKED,
            DBIERR_UNLOCKFAILED,
            DBIERR_FILEBUSY,
            DBIERR_DIRBUSY,
            DBIERR_FILELOCKED,
            DBIERR_DIRLOCKED,
            DBIERR_ALREADYLOCKED,
            DBIERR_NOTLOCKED,
            DBIERR_LOCKTIMEOUT,
            DBIERR_GROUPLOCKED,
            DBIERR_LOSTTBLLOCK,
            DBIERR_LOSTEXCLACCESS,
            DBIERR_NEEDEXCLACCESS,
            DBIERR_RECGROUPCONFLICT,
            DBIERR_DEADLOCK,
            DBIERR_ACTIVETRAN,
            DBIERR_NOACTIVETRAN,
            DBIERR_RECLOCKFAILED,
            DBIERR_OPTRECLOCKFAILED,
            DBIERR_OPTRECLOCKRECDEL,
            DBIERR_ENLISTFAILED,
            DBIERR_NETFILELOCKED,
            DBIERR_NETMULTIPLE:
               msgError( msTablaBloqueada + NT );
            DBIERR_FILECORRUPT:     msgError(msTablaCorrupta + NT);
            DBIERR_INDEXCORRUPT:    msgError(msIndiceCorrupto +NT);
            DBIERR_READERR:         msgError(msErrordeLectura +NT);
            DBIERR_DIRNOACCESS:     msgError(msSinAccesoaDirectorio + NT);
            DBIERR_FILENOACCESS:    msgError(msSinAccesoaArchivo + NT);
            DBIERR_NOMEMORY:        msgError(msSinMemoria + NT);
            DBIERR_OPENTBLLIMIT:    msgError(msMuchasTablasAbiertas + NT);
            DBIERR_NOSHAREDMEMORY:  msgError(msSinMemoriaCompartida + NT);
            DBIERR_INVALIDFILENAME: msgError(msNombreArchivoIncorrecto + NT);
            DBIERR_NOSUCHINDEX:     msgError(msNombreIndiceIncorrecto + NT);
            else                    msgError(msErrorDesconocido + E.Message);
         end;
         Result := False;
      end;
      end;


La franja horaria es GMT +2. Ahora son las 04:52:28.

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