Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   exceptions vs checks y FKs (https://www.clubdelphi.com/foros/showthread.php?t=25175)

micayael 14-09-2005 17:32:30

exceptions vs checks y FKs
 
Hola muchachos.-

Cuando yo creo un CHECK o una FK y trato de violarla aparece una mensaje de error mostrando el nombre del check o fk que no permite realizar el proceso mientras que si creo una excepcion puedo definir yo el mensaje que quiero que aparezca.

Entonces, no me conviene mas implmentar los CHECKs y FKs por medio de excepciones? o tengo que hacer ambos que me proponen ustedes los genios?
Lo mismo pasaria con los indices UNIQUE. Lo que no se es si se puede definir el mensaje para los CHECKs y UNIQUEs. Es decir, para sus propias restricciones

Neftali [Germán.Estévez] 14-09-2005 18:07:48

Lo normal sería crear índices, checks y FK's; Cuando realizas una operación (incorrecta) con cualquiera de ellos "saltará" una excepción; En ese punto la capturas y mustras tu mensaje de error (normalmente más claro de cara al usuario).

micayael 14-09-2005 20:42:39

aahh. Eso esta interesante. pero como capturo ese momento? Ahi deberia llamar a mi exepcion.

Neftali [Germán.Estévez] 15-09-2005 09:47:43

Bueno, sería algo así:

Código Delphi [-]
 
   ...
   // Comienza el bloque de proteccion
   try
     Tabla1.Post;  // Supongamos que ésto genera excepcion
   except
     on E:EDBEngineError do begin
       // Error de Base de Datos....
       // Para afinar más puedses intentar saber de qué tipo es el erorr...
       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);
       end
       else if....
          // puedes capturar el resto de la misma forma...
       end;
     end
     else begin
       raise;   // dejamos que siga....
     end;
   end;

Las constantes para los errores más comunes:
  • eKeyViol = 9729;
  • eRequiredFieldMissing = 9732;
  • eForeignKey = 9733;
  • eDetailsExist = 9734;
  • eSqlGralerror = 13059;
No lo he compilado, espero no haber cometido muchos errores; Pruébalo y si tienes problemas ya dirás...

micayael 15-09-2005 15:03:51

Guuuaaaauuuuu.,

La verdad que es bien complejo todavia para mi. Para empezar no se ni siquiera si es un trigger o alguna otra cosa.

Me podrias especificar eso (si es un trigger)

Sabes de donde puedo encontrar informacion sobre los tipos de exepciones y sobre las variables que usas ahi para crear tu mensaje? Es propio de firebird?

Es parecido al uso en visual basic. Yo estoy usando php

rastafarey 15-09-2005 15:17:03

Resp
 
Si uqieres personalizar aun mas tu errores lo puedes hacer el evento on exception ya que este captura todos lo errores.

Lee un poco sobre esto.

Espero te sirva

ContraVeneno 19-09-2005 16:22:26

O en todo caso coloca el cursor sobre la palabra que no entiendes y presionas F1 para que te muestre la ayuda sobre ese tema (esto sobre delphi claro esta).

HombreSigma 20-09-2005 17:03:01

Una sugerencia más
 
Saludos foro:

Sugiero aprovechar la tecnología de objetos de Delphi.

Como estas rutinas de captura de excepciones para validar la integridad de llave primaria y llave foránea son comunes a todas las tablas hace tiempo se me ocurrió crear un componente nuevo que llamé TTabla que hereda las características (métodos y propiedades) de TTable.

A este nuevo componente le modifique algunos de los métodos de los eventos tipicos de TTabla haciendo las validaciones estandar dentro de ellos.

Usando este componente, hasta ahora, me he olvidado por completo de tener que realizar validaciones de integridad tipicas como validacion de registros duplicados, mensajes de error en español, pues todo lo hace este componente, aprovechando los principios de la orientación a objetos de Delphi. De lo contrario estarían condenados para siempre a hacer copy paste del código de las validaciones mencionadas para cada TTable que ustedes crearan.

Envio un bosquejo del componente el cual se puede ampliar a conveniencia, luego pongase en una paleta de componentes personales y utilicese este componente en vez de TTable.

Código:


unit Tabla;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, DBCtrls, DBTables, ReglasValidacion, bdBaseDatos, ArchivoTexto,
  ComCtrls,Gauges, TiposComunes;

type
  TTabla = class(TTable)
  private
    { Private declarations }
    procedure MiDataSetPostError(DataSet: TDataSet;
                                  E: EDatabaseError;
                                  var Action: TDataAction);
    procedure MiUpdateError( DataSet: TDataSet;
                            E: EDatabaseError;
                            UpdateKind: TUpdateKind;
                            var UpdateAction: TUpdateAction);
    procedure MiDataSetDeleteError(DataSet: TDataSet;
                                  E: EDatabaseError;
                                  var Action: TDataAction);
    procedure MiBeforePost(DataSet:TDataSet);
    procedure MiBeforeDelete(DataSet:TDataSet);
    procedure MiBeforeInsert(DataSet:TDataSet);
    procedure MiBeforeEdit(DataSet:TDataSet);
   
  protected
    { Protected declarations }
  public
    { Public declarations }
  constructor Create (AOwner:Tcomponent);override;
    destructor Destroy;override;

  published
    { Published declarations }
  end;

implementation

constructor TTabla.Create (AOwner:TComponent);
var DataSetNo:Integer;
begin
  inherited Create(AOwner);
  Self.OnDeleteError  :=MiDataSetDeleteError;
  Self.OnPostError    :=MiDataSetPostError;
  Self.BeforePost      :=MiBeforePost;
  Self.BeforeDelete    :=MiBeforeDelete;
  Self.BeforeInsert    :=MiBeforeInsert;
  Self.BeforeEdit      :=MiBeforeEdit;
  Self.OnUpdateError  :=MiUpdateError;
end;

destructor TTabla.Destroy;
begin
  //Destroy previos al de TTabla
  inherited Destroy;
end;

procedure TTabla.MiDataSetDeleteError
 (DataSet: TDataSet;E: EDatabaseError; var Action: TDataAction);
begin
  //Hacer aqui las validaciones estandar en caso de error al borrar un registro
end;


procedure TTabla.MiDataSetPostError
  (DataSet: TDataSet; E:EDatabaseError; var Action:TDataAction);
var MensajeValidacionIntegridadDatos:AnsiString;
begin
  inherited;
  //Validaciones estandar en caso de error al hacer POST
end;

procedure TTabla.MiUpdateError( DataSet: TDataSet;
                            E: EDatabaseError;
                            UpdateKind: TUpdateKind;
                            var UpdateAction: TUpdateAction);
begin
  inherited;
  //Validaciones estandar en caso de error al actualizar
end;

procedure TTabla.MiBeforePost(DataSet: TDataSet);
begin
  //Hacer validaciones estándar before post
end;

procedure TTabla.MiBeforeDelete(DataSet: TDataSet);
begin
  if DataSet.IsEmpty
    then raise Exception.Create('No hay registros para borrar');
  //Otras validaciones estandar
end;

procedure TTabla.MiBeforeInsert(DataSet: TDataSet);
begin
  //Validaciones estandar BeforeInsert 
end;

procedure TTabla.MiBeforeEdit(DataSet: TDataSet);
begin
  //Validaciones estandar Before Edit
end;


end.


micayael 21-09-2005 19:33:09

eeeeeste. tomando en cuento que no uso Delfi. se puede hacer los mensajes de error en el firebird y que sean devueltos?

Es decir. Se que se pueden hacer con exeptions pero como capturo yo el mensaje de error de una FK por ejemplo y llamo a una excepcion? (en el firebird)

HombreSigma 21-09-2005 23:39:22

A mi parecer es mejor no alterar los mensajes estandar de la base de datos, simplemente se crean las restricciones de integridad y demas validaciones centralizadas en la misma; luego a traves del lenguaje de programacion, sea Delphi u otro, se capturan las excepciones generadas por la BD y los codigos de error programando los mensajes correspondientes.

Sin embargo, si insistes en hacer lo tuyo, primero bajate el manual de interbase desde el foro. De alli tome este ejemplo de como crear una excepcion en Firebird

Esta sentencia sql crea una excepcion llamada TuExcepcion:

Código:

CREATE EXCEPTION TuExcepcion ’Numero de empleado invalido';
Posteriormente, otra sentencia como la siguiente, ejecutada desde un procedimiento almacenado o un trigger debe generar la excepcion creada cuando el codigo de error de la base de datos SQLCODE es -530, que corresponde a una violacion de integridad referencial:

Código:

. . .
WHEN SQLCODE -530 DO
  EXCEPTION TuExcepcion;
....


micayael 22-09-2005 16:40:29

Me das una manito hombre sigma. cual es el manual?
Estoy buscando por la web y no encuentro ese manual.
Por lo menos si me dices el nombre del manual asi lo busco.
Eso que me dices es mas o menos lo que quiero. por ahi puedo crear una tabla con los tipos de errores y en todo caso los consulto desde el cliente.

Lepe 22-09-2005 16:55:35

De esta página, bajatelo todo, todo ;-)

http://www.firebirdsql.org/index.php?op=doc&id=userdoc

* As individual zipped PDF files:
* API Guide (1.69mb)
* Data Definition Guide (1.20mb)
* Developers Guide(1.46mb)
* Embedded SQL Guide (1.36mb)
* Operations Guide (1.45mb)
* Language Reference (1.28mb)
* Getting Started (0.43mb)
* Migration Guide


Data definition guide, Developers Guide, los he leido en vacaciones y no tienen desperdicio alguno. (no entiendo de libros de lectura ni literatura, así que pillé esos 2)

Language Reference, es para tenerlo a mano y consultar la sintaxis concreta de cada cosa, una vez que ya tienes los conocimientos.

Un saludo

micayael 22-09-2005 19:26:42

excelente maestro. Te debo una.

HombreSigma 24-09-2005 05:23:56

Mira en el foro:

http://www.clubdelphi.com/ib/documen...umentacion.php


La franja horaria es GMT +2. Ahora son las 13:11:51.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi