FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
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. |
#2
|
||||
|
||||
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. |
#3
|
|||
|
|||
¿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á :) |
#4
|
||||
|
||||
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; Última edición por kinobi fecha: 21-06-2003 a las 02:05:53. |
#5
|
|||
|
|||
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; |
#6
|
||||
|
||||
Hola,
Cita:
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; 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; Última edición por kinobi fecha: 21-06-2003 a las 02:07:13. |
|
|
|