none
CAPTURAR ERRORES SQL SERVER

    Question

  • Hola, estoy haciendo una aplicacion en C# la cual se conecta con SQL SERVER 2005.

     

    El problema que tengo es el siguiente:

    Cree un trigger dentro del servidor para limitar el numero de conexiones desde la aplicacion. El codigo es el siguiente:

     

    USE master;

    GO

    ALTER TRIGGER connection_limit_trigger

    ON ALL SERVER

    FOR LOGON

    AS

    BEGIN

        IF ORIGINAL_LOGIN()= 'asdf' AND PROGRAM_NAME()='.Net SqlClient Data Provider' AND

            (SELECT COUNT(*) FROM sys.dm_exec_sessions

             WHERE is_user_process = 1 AND  PROGRAM_NAME='.Net SqlClient Data Provider' AND

             original_login_name = 'asdf') > 2

        BEGIN

    ROLLBACK TRANSACTION;        

    PRINT 'Lo siento solo se permiten 2 conexiones para ''asdf'''

        END

    END; 

     

     

     

    El trigger funciona bien, ya que si tengo la aplicacion abierta en 2 pc distintas, cuando quiero iniciar desde una tercer pc tira el siguiente error:

    "ERROR  DEL INICIO DE SESION 'asdf' DEBIDO A LA EJECUCION DEL DESENCADENADOR. SE CAMBIO EL CONTEXTO DE LA BASE DE DATOS A 'mibase'. SE CAMBIO LA CONFIGURACION DE IDIOMA A ESPAÑOL."

     

    Pero lo que necesito es que se imprima el texto que yo escribí en el print del trigger.

     

    En la aplicacion realizo lo siguiente para capturar el error cuando quiero conectarme al servidor

     

    try

                {

                    --trato de conectar al servidor

                }

                catch (SqlException ex)

                {

                    MessageBox.Show(ex.Message);

                    salir();

                }

     

    Pero sin embargo no muestra el texto del print. Vale aclarar que tambien probe usar, en lugar de print, lo siguiente

    RAISERROR('mensaje',10,1). Pero obtuve el mismo resultado

     

    Sunday, May 01, 2011 9:22 PM

Answers

All replies

  • Mira este par de enlaces que te paso, te haras una idea de como tienes que hacerlo:

    http://social.msdn.microsoft.com/Forums/es-ES/vcses/thread/8687e862-4c5c-42d7-82de-7ed391c84e9a/

    http://social.msdn.microsoft.com/Forums/es-ES/vcses/thread/b32d8c1e-8d10-4c2c-b535-21d6ea11444e/

    Nos comentas si tiens dudas.


     Norman M. Pardell 

    ||Microsoft Certified IT Professional|| Database Administrator. Database Developer. SQL Server 2008

    Sunday, May 01, 2011 10:11 PM
  • Lo que en el servidor escribes con PRINT no te llega al cliente en forma de excepción, sino que se recibe mediante el evento InfoMessage del objeto SqlConnection. En tu caso concreto, resultará más sencillo que cambies el PRINT por RAISERROR, y que dentro del catch enumeres la colección Errors del SqlException hasta encontrar el mensaje correspondiente (fíjate en los links que te ha indicado Normannp).
    Monday, May 02, 2011 6:12 AM
  • Hola, gracias por la ayuda. Cuando enumero los errores me indica que el error es el numero: 17892

    Me fije en sql y ese error es:

    Error del inicio de sesión '%1!' debido a la ejecución del desencadenador.%2!

     

    Si yo hago el case para ese numero funciona bien, puedo identificar el error y personalizar el mensaje.

    Pero yo queria saber si podia evitar eso, y podia directamente mostrar el mensaje que escribo en el trigger.

    En el trigger cambie la linea del print por

    RAISERROR('mensaje',10,1).

     

    Y en la aplicacion hago lo siguiente dentro de bloque catch

     

    SqlError err = ex.Errors[0];

    string mensaje = string.Empty;

    switch (err.Number)

    {

    case 17892:

    mensaje = "mensaje"; break;

    .......... }

     

    Hay forma de obtener el mensaje que yo escribi en el trigger ????

    Monday, May 02, 2011 1:17 PM
  • Hola.

    Depende de la severidad del mensaje, ya que hay errores que SQL Server no te permite gestionar, no devuelve el control al llamante. Pero si se trata de un error que tú has colocado por el motivo que sea y lo encapsulas en un bloque try...catch dentro de tu trigger, puedes puedes capturarlo desde el código, de la forma en la que se describe aquí (es un link que ya podías llegar desde los que te han puesto), con los métodos de la clase SqlException, que no SqlError, Message, LineNumber, etc., que son los mismos que puedes obtener desde T-SQL con las funciones Error_Message(), Error_LineNumber(), etc.

    http://msdn.microsoft.com/es-es/library/system.data.sqlclient.sqlexception(v=vs.80).aspx#Y352

    Si no lo logras, nos dices.


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.blogspot.es/ Sígueme en twitter en http://twitter.com/qwalgrande

    Monday, May 02, 2011 1:42 PM
  • Que severidad debo poner en el raiserror del trigger para poder mostrar el mensaje?
    Monday, May 02, 2011 1:55 PM
  • Hola.

    En los que tú pongas, el que quieras mientras sea inferior a 17 (porque si lo pones de ese calibre, ya no lo podrás capturar). Si son arrojados por el motor, entonces ya es otra cosa, ya que no dependerá de ti ese nivel. De todos modos, usa bloques try.catch. Te dejo aquí la referencia de las diferentes severidades:

    http://msdn.microsoft.com/es-es/library/ms164086.aspx


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.blogspot.es/ Sígueme en twitter en http://twitter.com/qwalgrande

    Monday, May 02, 2011 2:07 PM
  • No he podido hacerlo.

    Tu dices que use un bloque try catch dentro del mismo trigger ???

    Probe esto con el siguiente codigo en el trigger que limita las conexiones:

     

    ...

    begin try

    select * from empleado

    end try

    begin catch

    RAISERROR('mi mensaje',16,1)

    end catch

     

    Pero cuando ejecuto la aplicacion y me rechaza la conexion, en lugar de mostrar mi mensaje muestra los mismos 3errores que venia mostrando

    "Error del inicio de sesión '%1!' debido a la ejecución del desencadenador.%2!"

    SE CAMBIO EL CONTEXTO DE LA BASE DE DATOS A 'mibase'.

    SE CAMBIO LA CONFIGURACION DE IDIOMA A ESPAÑOL."

    Monday, May 02, 2011 4:45 PM
  • Hola.

    Discúlpame, me enganché tarde al hilo y no caí en la cuenta de que era un trigger de logon. No puedes capturar errores en un trigger de logon porque dichos mensajes se redirigen al log de errores de SQL Server. Sólo te queda la opción de capturar el número del error (17892) o el texto (el que ya conoces) desde tu aplicación cliente y personalizar dicho mensaje cuando ocurra.

    Te dejo un link, por si te sirve de alguna ayuda en la elaboración de logon triggers:

    http://www.simple-talk.com/sql/t-sql-programming/logon-triggers/


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.blogspot.es/ Sígueme en twitter en http://twitter.com/qwalgrande

    Tuesday, May 03, 2011 9:54 PM