Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   MS SQL Server (https://www.clubdelphi.com/foros/forumdisplay.php?f=23)
-   -   Como capturar mensaje cuando se intenta duplicar una clave primaria de una BD (https://www.clubdelphi.com/foros/showthread.php?t=73903)

RedVenom 24-05-2011 01:13:53

Como capturar mensaje cuando se intenta duplicar una clave primaria de una BD
 
Quisiera saber si hay alguna forma de capturar el mensaje de error que manda la base de datos cuando se intenta duplicar el valor de una llave primaria, esto es para mostrarle un mensaje personalizado al usuario de la aplicacion en lugar del que mande el sistema.
Les agradezco su ayuda de antemano.

Casimiro Notevi 24-05-2011 01:41:42

¿Qué base de datos?

RedVenom 24-05-2011 01:58:03

Es SQL Server 2008

olbeup 24-05-2011 08:02:58

Porque no creas una función para saber si existe tal dato en la tabla, no creo que sea buena idea que la base de datos te devuelva un error de la existencia de dicho dato.

un saludo.

Neftali [Germán.Estévez] 24-05-2011 11:38:45

¿Cómo estás accediendo? ¿ADO, DBExpress?

Utiliza un Try..Except y captura el mensaje de vuelta. Segun la clase podrás acceder al código o en su defecto al mensaje; A partir de ahí podrás personalizar el mensaje:

Código Delphi [-]
try
  ADOQuery1.Update;
except
  on E:EOLEException do begin
    ==> E.ErrorCode    Codigo de error.
    ==> E.Message      Mensaje de error
  end;
end;

Esto es más o menos lo que puedes utilizar para ADO; Para DbExpress algo similar.

RedVenom 24-05-2011 22:03:24

Es que la base de datos sola me devuelve ese error cuando intento duplicar una llave primaria lo que deseo es interceptarlo para que yo muestre mi propio mensaje, no me convence lo de crear una funcion tendria que estar llamando a la funcion cada vez que agrego un registro cuando la base de datos ya te da el mensaje.

BlueSteel 25-05-2011 01:18:22

Cita:

Empezado por RedVenom (Mensaje 401190)
Es que la base de datos sola me devuelve ese error cuando intento duplicar una llave primaria lo que deseo es interceptarlo para que yo muestre mi propio mensaje, no me convence lo de crear una funcion tendria que estar llamando a la funcion cada vez que agrego un registro cuando la base de datos ya te da el mensaje.


Creo que deberias pensar mejor lo de la funcion...

Si bien la base te envia un mensaje cuando el codigo de registro esta duplicado, para un sistema en donde se ingresa un registro con grandes cantidades de información... (por unos 30 0 50 campos por lo minimo)... haras que el usuario digite todos los campos.... y cuando presiones guardar se de cuenta que ya existe?:confused::confused::confused:

Creo que lo mejor es ingresar el campo clave (codigo, campo clave o como lo llames) y preguntar si en la base existe algun registro con dicho codigo.. si existe lanzas el mensaje que existe un registro... en caso contrario sigues ingresando....:p:p


Salu2:p

Al González 25-05-2011 04:10:36

Cita:

Empezado por olbeup (Mensaje 401083)
Porque no creas una función para saber si existe tal dato en la tabla, no creo que sea buena idea que la base de datos te devuelva un error de la existencia de dicho dato.

Para mí, de hecho, es mejor que sea el motor de base de datos quien valide ese tipo de cuestiones y capturar desde la aplicación el mensaje de excepción, convirtiéndolo en algo amigable y entendible por el usuario.

Con una función de verificación no hay garantía de que, entre la llamada a la función y el envío de los datos, otro programa o usuario ocupe el valor que no se quiere duplicar.

Una solución como la de Neftali me parece la más adecuada (o usar el evento OnReconcileError en caso de que RedVenom esté utilizando objetos TClientDataSet). Esperemos a ver qué nos dice.

Saludos. :)

Neftali [Germán.Estévez] 25-05-2011 09:59:06

Cita:

Empezado por Al González (Mensaje 401230)
Para mí, de hecho, es mejor que sea el motor de base de datos quien valide ese tipo de cuestiones y capturar desde la aplicación el mensaje de excepción, convirtiéndolo en algo amigable y entendible por el usuario.

+1

Correcto. Muy correcto.

Primero porque estaremos haciendo trabajo doble.
Segundo porque si ya hay alguien que saber hacer ese trabajo, mejor que lo haga él (SGBD).
Tercero, porque los métodos de hacerlo del SGDB son mucho más eficientes que hacerlo desde el cliente (delphi).
Cuarto, porque hacerlo nosotros no es tan sencillo como parece, por los temas de concurrencia que comenta Al.

Casimiro Notevi 25-05-2011 11:42:41

+1 Al González
+1 Neftalí

roman 25-05-2011 16:35:07

Cita:

Empezado por BlueSteel (Mensaje 401220)
Creo que lo mejor es ingresar el campo clave (codigo, campo clave o como lo llames) y preguntar si en la base existe algun registro con dicho codigo.. si existe lanzas el mensaje que existe un registro... en caso contrario sigues ingresando....:p:p

Esto tiene el problema de concurrencia que ya han mencionado. Lo que he hecho a veces, para evitar la captura innecesaria es:

1. Preguntar la clave.
2. Insertar un nuevo registro con esa clave.
3. Esperar... (a ver qué dice el servidor :D)
4. Presentar un formulario para llenar los datos restantes.
5. Hacer el UPDATE a la base.

Por cierto, además del try-except también puede usarse el evento OnPostError del DataSet.

// Saludos

Al González 25-05-2011 16:35:10

Y uno más para Casimiro +1. Por darme su voto. :p

RedVenom 26-05-2011 03:09:29

Estoy usando ADODataset no entendi muy bien el codigo que me dio neftali en donde lo debo colocar para capturar y como lo paso al mensaje que yo deseo presentar.
Les agradezco mucho suayu da y opinion, ah y si yo tambien soy de la opinion de usar lo que ya hace la base de datos en lugar de volvr a programar lo que ya esta programado y verificado.

RedVenom 26-05-2011 04:14:52

Ya logre poner mi mensaje cuando da el error la Base de Datos puse el siguiente codigo en el evento OnPostError y si aparece mi mensaje pero despues de que le doy aceptar aparece enseguida el mensaje de error de la base de datos, ahora mi pregunta es como le hago para que solo aparezca mi mensaje??, y otra cuestion y si solo quisiera interceptar ciertos errores de la base de datos se podria hacer??

Código Delphi [-]
procedure TForm1.ADODataSet1PostError(DataSet: TDataSet; E: EDatabaseError;
  var Action: TDataAction);
begin
   MessageDlg('MENSAJE DE ERROR: '+E.Message, mtWarning, [mbOK], 0);
end;

Casimiro Notevi 26-05-2011 09:33:22

Eso es porque lo has ejecutado desde delphi, pruébalo desde fuera, verás :)

Neftali [Germán.Estévez] 26-05-2011 10:09:04

Cita:

Empezado por Casimiro Notevi (Mensaje 401412)
Eso es porque lo has ejecutado desde delphi, pruébalo desde fuera, verás :)

O desactiva los mensajes de error en el IDE;
Tool / Debugger Options / Languages Exceptions / Stop on Delphi Exceptions

Casimiro Notevi 26-05-2011 11:44:22

Cita:

Empezado por Neftali (Mensaje 401415)
O desactiva los mensajes de error en el IDE;
Tool / Debugger Options / Languages Exceptions / Stop on Delphi Exceptions

Y te acuerdas de activarlo después, ya que no volverás a ver un error, aunque exista.

RedVenom 26-05-2011 14:47:29

Y como seria desde fuera??

maeyanes 26-05-2011 15:30:54

Cita:

Empezado por RedVenom (Mensaje 401473)
Y como seria desde fuera??

Ejecutas directamente desde Windows el ejecutable generado por Delphi, no desde el IDE...


Saludos...

RedVenom 26-05-2011 18:34:33

Me sigue apareciendo lo mismo primero el mensaje y luego el que manda la base de datos. Alguna sugerencia??


La franja horaria es GMT +2. Ahora son las 02:00:53.

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