none
trigger en sql 2008 RRS feed

  • Pregunta

  • Buenas tardes, estoy haciendo un trigger que me mande un correo cuando se actualiza un campo de una tabla.. los valores que puede tomar son S de si y N de no... me ejecuta todo muy bien... solo que no me manda dos correos, cuando es S o N...y se supone que ya le puse que la condicion de que solo cuando sea N...

    Pudieran ayudarme ..?... hay alguna manera de en el siguiente codigo ponerle IF UPDATE(cb_activo)='N' para que luego me haga el insert de la tabla?.. gracias

    create TRIGGER [dbo].[Bajas_Trg] ON [dbo].[COLABORA]
    AFTER UPDATE
    AS 
    BEGIN
     SET NOCOUNT ON;
       IF UPDATE(cb_activo) 
      BEGIN
        INSERT INTO TMPBAJAS
        SELECT I.cb_codigo
        FROM inserted I INNER JOIN COLABORA C ON I.CB_CODIGO = C.CB_CODIGO WHERE I.cb_activo = 'N'
       EXEC msdb.dbo.sp_start_job @job_name='BajasTress'   
      END 
    END


    Muchas Gracias

    lunes, 30 de abril de 2012 18:20

Respuestas

  • Hola.

    Mucho me temo que, como en tantas otras ocasiones, el que pide estas cosas no conoce la tecnología, pero para eso estamos los técnicos, para tratar de llevar acabo aquello que nos solicitan de la forma lo más aproximada que sea posible.

    El error es conceptual: El correo es un servicio offline, no online. Por mucho que tú lo quieras enviar, lo que haces en encolarlo en una lista de salida, que lo tratará cuando toque, y luego queda la parte cliente. Además, lo de "en cuanto se produzca" entra perfectamente en la categoría de un un job que se ejecute cada minuto. Si me apuras, creas 4 programaciones solapadas que se lancen cada 15 segundos, pero con una revisión por minuto, suficiente.

    Aparte, nada te impide verificar el valor que tiene el campo en la tabla INSERTED. De hecho lo haces, así que el problema quizá es otro, a lo mejor relacionado con ese truncado de la tabla que haces en el job. Yo eso tampoco lo haría, sino que marcaría los registros sin más o borraría los registros tratados, pero no todos porque puede que pierdas control en ejecuciones sucesivas.


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

    • Marcado como respuesta Eder Costa martes, 8 de mayo de 2012 17:29
    lunes, 30 de abril de 2012 21:06
    Moderador
  • Aparte de lo que acertadamente comenta Alberto, en la forma que tienes estructurado el trigger desde el momento en que se actualizo el campo tu envias a ejecutar el EXEC msdb.dbo.sp_start_job @job_name='BajasTress'  , podrías perfectamente evaluar antes el valor de la columna I.cb_activo y en caso de ser 'N' entonces ejecutar todas las sentencias.

    Aunque me sumo a Alberto, mejor realiza como él te indica 4 programaciones solapadas que se lancen cada 15 segundos, además no creo que ese diferencial en segundos te cause inconvenientes, tampoco creeria que va a notificar a un comando SWAT para que lleguen a sacar al empleado :-) .


    "How many years can some people exist before they're allowed to be free" Bob Dylan Email: info@geohernandez.com Blog: geeks.ms/blogs/ghernandez

    • Marcado como respuesta Eder Costa martes, 8 de mayo de 2012 17:29
    lunes, 30 de abril de 2012 21:20

Todas las respuestas

  • Hola.

    Te recomiendo que, en lugar de querer arrancar un job o enviar un mial con un trigger (algo que por cuestiones de permisos es difícilmente asumible y por cuestiones de lo que es un trigger es complicado de manejar), guardes un registro en una tabla que crees para este fin. Luego, con un job, revisas la tabla y envías el correo.

    El resultado es exactamente el mismo, sólo que en el job has de hacer el chequeo para ver si hay que enviar mails o no, y ejecutarlo cada pocos minutos.

    Inténtalo con esa variante, y si no lo consigues, nos dices.


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

    lunes, 30 de abril de 2012 19:10
    Moderador
  • Estoy de acuerdo con el planteamiento de Alberto, además de evitarte todas las complicaciones que te mencionaban, estoy casi seguro que no requieres esa inmediatez que esperas te brinde el trigger, igual programas el JOB para su ejecución en un intervalo muy corto y asi solventaras lo que necesitas.


    "How many years can some people exist before they're allowed to be free" Bob Dylan Email: info@geohernandez.com Blog: geeks.ms/blogs/ghernandez

    lunes, 30 de abril de 2012 19:22
  • muchas gracias a ambos.. lo que me estan solicitando en la empresa es un trigger... tengo una tabla de empleados, me piden que en cuanto un empleado sea dado de baja, se notifique en ese instante a cierto grupo de personas... ya pude hacer que eso pase... pero en el trigger tengo que cuando se actualice la tabla y necesito ponerle que cuando se actualice la tabla solamente a N (activo=No)

    Primero cree el trigger

    ALTER TRIGGER [dbo].[Bajas_Trg] ON [dbo].[COLABORA]
    AFTER UPDATE
    AS 
    BEGIN
    SET NOCOUNT ON;
       IF UPDATE(cb_activo) 
      BEGIN
        INSERT INTO TMPBAJAS
        SELECT I.cb_codigo
        FROM inserted I INNER JOIN COLABORA C ON I.CB_CODIGO = C.CB_CODIGO WHERE I.cb_activo = 'N'
       EXEC msdb.dbo.sp_start_job @job_name='BajasTress'   
      END 
    END
    

    Luego cree el job

    EXEC msdb.dbo.sp_send_dbmail 
         @profile_name = 'EPOEmailAlertProfile',
         @recipients = 'l.d@e.com',
         @query = 'select c.CB_CODIGO, prettyname NOMBRE, CB_FEC_BAJ, mb.tb_element MOTIVO, CB_NOMNUME ULTNOM, N3.TB_ELEMENT, CB_NIVEL0 
                   from etac.dbo.COLABORA C
                   inner join etac.dbo.TMPBAJAS B on C.CB_CODIGO = b.CB_CODIGO
                   inner join etac.dbo.MOT_BAJA mb on mb.TB_CODIGO=C.cb_mot_baj
                   INNER JOIN etac.dbo.NIVEL3 N3 ON C.CB_NIVEL3=N3.TB_CODIGO where c.cb_activo=''N'' ',
         @subject = 'Bajas de TRESS',
         @attach_query_result_as_file = 1;
    TRUNCATE TABLE Tmpbajas;

    Funciona bien, pero cuando hay un reingreso cambia el estatus de N a S y me manda el correo, ya que se actualizo la tabla que esta definido en el trigger  IF UPDATE(cb_activo) quisiera saber si en el trigger pudiera condicionar este funcionamiento a IF UPDATE(cb_activo)='N', es decir cuando actualice el campo cb_activo a n que se dispare el trigger y que active la tarea...

    les agradezco a todos el tiempo...


    Muchas Gracias

    lunes, 30 de abril de 2012 20:39
  • Hola.

    Mucho me temo que, como en tantas otras ocasiones, el que pide estas cosas no conoce la tecnología, pero para eso estamos los técnicos, para tratar de llevar acabo aquello que nos solicitan de la forma lo más aproximada que sea posible.

    El error es conceptual: El correo es un servicio offline, no online. Por mucho que tú lo quieras enviar, lo que haces en encolarlo en una lista de salida, que lo tratará cuando toque, y luego queda la parte cliente. Además, lo de "en cuanto se produzca" entra perfectamente en la categoría de un un job que se ejecute cada minuto. Si me apuras, creas 4 programaciones solapadas que se lancen cada 15 segundos, pero con una revisión por minuto, suficiente.

    Aparte, nada te impide verificar el valor que tiene el campo en la tabla INSERTED. De hecho lo haces, así que el problema quizá es otro, a lo mejor relacionado con ese truncado de la tabla que haces en el job. Yo eso tampoco lo haría, sino que marcaría los registros sin más o borraría los registros tratados, pero no todos porque puede que pierdas control en ejecuciones sucesivas.


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

    • Marcado como respuesta Eder Costa martes, 8 de mayo de 2012 17:29
    lunes, 30 de abril de 2012 21:06
    Moderador
  • Aparte de lo que acertadamente comenta Alberto, en la forma que tienes estructurado el trigger desde el momento en que se actualizo el campo tu envias a ejecutar el EXEC msdb.dbo.sp_start_job @job_name='BajasTress'  , podrías perfectamente evaluar antes el valor de la columna I.cb_activo y en caso de ser 'N' entonces ejecutar todas las sentencias.

    Aunque me sumo a Alberto, mejor realiza como él te indica 4 programaciones solapadas que se lancen cada 15 segundos, además no creo que ese diferencial en segundos te cause inconvenientes, tampoco creeria que va a notificar a un comando SWAT para que lleguen a sacar al empleado :-) .


    "How many years can some people exist before they're allowed to be free" Bob Dylan Email: info@geohernandez.com Blog: geeks.ms/blogs/ghernandez

    • Marcado como respuesta Eder Costa martes, 8 de mayo de 2012 17:29
    lunes, 30 de abril de 2012 21:20