Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 17-06-2003
Giniromero Giniromero is offline
Miembro
 
Registrado: may 2003
Ubicación: Madrid
Posts: 296
Poder: 22
Giniromero Va por buen camino
para no dejar duplicar registros en InterBase

Hola a todos,

Con interbase7 y delphi 6.

Tengo una ventana en mi aplicación que me sirve para agregar registros a una tabla. Esta tabla de interbase, tiene dos campos que son NO NULL y que juntos, son mi manera de direfenciar los registros de esa tabla.

Tengo un TDBNavigator para insertar, editar y gestionar en general esta tabla tbMaterial1.

El caso es que necesito poner una condición para que, si intenta alguien insertar un registro que ya esté, me muestre un mensaje de error, y no me deje guardar, me cancele la inserción.

El código que tengo es el siguiente:

procedure TFrmChangeMaterial.DBNavigator1BeforeAction(Sender: TObject;
Button: TNavigateBtn);
begin

If (FrmMainCenta.TbMaterial1.State = dsEdit) Or (FrmMainCenta.TbMaterial1.State = dsInsert) Then Begin
//si ya hay un material en la tabla material con los datos que estamos insertando nuevo
IF FrmMainCenta.TbMaterial.Locate ('ISBN;Copia', VarArrayOf([FrmMainCenta.TbMaterial1ISBN.AsVariant, FrmMainCenta.TbMaterial1Copia.AsVariant]), [locaseInsensitive]) THEN BEGIN
//If (FrmMainCenta.TbMaterial1.State = dsEdit) Or (FrmMainCenta.TbMaterial1.State = dsInsert) Then Begin
//mostramos mensaje aviso
showmessage ('¡¡CUIDADO!! El ISBN y COPIA insertados están asignados a otro material de la biblioteca. Su Operación no se puede llevar a cabo');
FrmMainCenta.IBTransCenta.Rollback;

END;
End;


end;


Donde TbMaterial1 y Tbmaterial funcionan como tablas independientes.

Me funciona, aparentemente todo bien hasta que muestra el mensaje, pero si después del mensaje pongo :
FrmMainCenta.IBTransCenta.Rollback; me dice que la tabla tbMaterial1 no esta en "edit o insert mode"

Si pongo
DBNavigator1.BtnClick(nbCancel); directamente no hace nada, me da el mismo error que cuando no le pongo código para controlar esto.



¿puede ayudarme alguien?

gracias

Virginia
__________________
Sonrie al mundo, y el mundo te sonreirá :)

Última edición por Giniromero fecha: 17-06-2003 a las 12:43:00.
Responder Con Cita
  #2  
Antiguo 17-06-2003
Avatar de kinobi
kinobi kinobi is offline
Miembro
 
Registrado: may 2003
Posts: 2.621
Poder: 24
kinobi Va por buen camino
Hola,

¿y por qué no dejar que el servidor envíe el error de clave duplicada (si esos dos campos te sirven para diferenciar los registros de la tabla deben, o deberían ser clave principal de la misma), capturando la excepción en la aplicación Delphi?.

Creo que es mucho más sencillo y más rápido que tener un segundo DataSet para lanzar un Locate que busque una posible clave duplicada.

Saludos.
Responder Con Cita
  #3  
Antiguo 17-06-2003
Giniromero Giniromero is offline
Miembro
 
Registrado: may 2003
Ubicación: Madrid
Posts: 296
Poder: 22
Giniromero Va por buen camino
¿y como lo hago? porque, si dejo que salga el error este de, "duplicando registro", se me queda la aplicación colgadilla.

gracias por todo

Virginia
__________________
Sonrie al mundo, y el mundo te sonreirá :)
Responder Con Cita
  #4  
Antiguo 17-06-2003
Avatar de kinobi
kinobi kinobi is offline
Miembro
 
Registrado: may 2003
Posts: 2.621
Poder: 24
kinobi Va por buen camino
Hola,

con try ... except. Ejemplo ...

Código:
  try 
    ...
    // intento de envío de actualización al servidor
    MiDataset.Post;
    ...
  except
    on E:EIBError do // error InterBase
    begin
      if E.IBError.Code = <codigo_error_clave_duplicada> then 
// no recuerdo ahora cúal es, pero una
 de las units de IBX tienes una constante
        ...
        ShowMessage('Clave duplicada   ...');
        ...
    end;    
  Else Raise; // no es error InterBase
  end;
Saludos.

Última edición por kinobi fecha: 21-06-2003 a las 02:05:53.
Responder Con Cita
  #5  
Antiguo 20-06-2003
[digital] digital is offline
Miembro Premium
 
Registrado: jun 2003
Posts: 26
Poder: 0
digital Va por buen camino
hola Kinobi
una duda.
las exception declaradas en la Base de datos se puede utilizar en el Ejemplo. que pones.

un ejemplo declaro una exception en la base de datos llamada
ART_NO_CODIGO con un texto 'NO HA INDICADO EL CODIGO DEL ARTICULO'

y despues creo un Trigger tipo Before Insert en la tabla de Articulos llamada.ARTICULOS_BI0

begin
if (new.codigo = "") then exception art_no_codigo;
end

la exception art_no_codigo se puede usar en try ... except.
try
MiDataset.Post;
except
on E:EIBError do
begin
if E.IBError.Code =art_no_codigo then
...
ShowMessage('Clave duplicada ...');
...
end;
Else Raise; end;
Responder Con Cita
  #6  
Antiguo 21-06-2003
Avatar de kinobi
kinobi kinobi is offline
Miembro
 
Registrado: may 2003
Posts: 2.621
Poder: 24
kinobi Va por buen camino
Hola,

Cita:
Posteado originalmente por digital
una duda.
las exception declaradas en la Base de datos se puede utilizar en el Ejemplo. que pones.
no a través del código de error. Para el caso de excepciones InterBase (CREATE EXCEPTION ....) la clase de excepciones EIBError recibe un código de error común para todas ellas, el valor 335544517 (si utilizas IBX tienes una constante definida para ese valor en la unit "IBErrorCodes.pas"; la constante es: "isc_except"). Por tanto no podrás discriminar entre excepciones utilizando el código de error enviado por el servidor. Pero sí puedes hacerlo a través del mensaje que devuelve, ya que es el mensaje de la excepción InterBase.

Por cierto, el código que puse anteriormente tiene un error. El código correcto es ...

Código:
  try 
    ...
    // intento de envío de actualización al servidor
    MiDataset.Post;
    ...
  except
    on E:EIBError do // error InterBase
    begin
      if E.IBErrorCode = isc_unique_key_violation 
// la constante isc_unique_key_violation 
// está definida en la unit IBErrorCodes (IBX)
        ...
        ShowMessage('Clave duplicada   ...'); 
// sustituir ShowMessage por el procesamiento que se desee
        ...
    end;    
  else Raise; // no es error InterBase
  end;
Para el caso de utilizar las cadenas de los mensajes de error de las excepciones InterBase ...

Código:
  try 
    ...
    // intento de envío de actualización al servidor
    MiDataset.Post;
    ...
  except
    on E:EIBError do // error InterBase
    begin
      if E.Message = <mensaje_excepción_InterBase>
        ...
        ShowMessage(E.Message);
        ...
    end;    
  else Raise; // no es error InterBase
  end;
Saludos.

Última edición por kinobi fecha: 21-06-2003 a las 02:07:13.
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 06:46:24.


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