none
Obtener el Query, Comando, instrucción que se está ejecutando en una tabla como el profiler

    Question

  • Hola, buenos días a todos,

    mi pregunta de hoy es, 

    como capturar el comando que se está ejecutando en una tabla,

    necesito esa instrucción, algo parecido a lo que hace el monitoreo Profiler

    pero, quisiera meterlo en una tabla dentro de un trigger. 

    actualmente he bajado dos queries que he visto por aquí en la red, pero no son exactamente lo que ando buscando,  de todas maneras se los dejos, para ver si pueder revisarlos pls

    si los ejecuto en un Analyzer, pues si me entregan el query que estoy ejecutando

    pero cuando los meto a un trigger, ya no lo hace

    me manda el commad que crea el trigger (create trigger.....)  porqué?

    muchas gracias por todas esas ideas

    SELECT  requests.session_id, 
            requests.status, 
            requests.command, 
            requests.statement_start_offset,
            requests.statement_end_offset,
            requests.total_elapsed_time,
            details.text
    FROM    sys.dm_exec_requests requests
    CROSS APPLY sys.dm_exec_sql_text (requests.plan_handle) details
    WHERE   requests.session_id > 50
    ORDER BY total_elapsed_time DESC

    SELECT
    DMExQryStats.last_execution_time AS [Executed At],
    DMExSQLTxt.text AS [Query]
    FROM
    sys.dm_exec_query_stats AS DMExQryStats 
    CROSS APPLY
    sys.dm_exec_sql_text(DMExQryStats.sql_handle) AS DMExSQLTxt
    ORDER BY
    DMExQryStats.last_execution_time DESC

    TENGO SQL2000 Y SQL2005 donde me gustaría ejecutarlo  muchas gracias


    saludos



    Wednesday, August 15, 2012 12:18 PM

Answers

  • Hola.

    Lo que comentas plantea algunas cuestiones impensables.

    1.- No es posible que una empresa que no puede permitirse adquirir un cluster pretenda una sincronización con una instancia de respaldo en la que un retardo de 10 segundos suponga un problema. De hecho, si se te rompe un disco, si tienes un bloqueo medianamente largo, con el propio proceso de undo, pierdes más de 10 segundos de información.

    2.- Aunque a mí eso me parece algo muy positivo porque te permite no perder ninguna transacción, puedes parametrizar la replicación para que se salte algunos tipos de errores (parámetro -SkipErrors).

    3.- La transmisión de objetos también es posible implementarla con replicación. De hecho, su automatización plantea cuestiones bastante peliagudas. Sin embargo, un entorno con frecuentes cambios no es el escenario apropiado para una replicación transaccional.

    4.- No puede ser que sea un problema perder 10 segundos de datos y que puedan alcanzarse las 72 horas sin pasar datos, dando lugar a que la suscripción caduque (otro parámetro que es configurable, ese es el valor por defecto). El alta disponibilidad empieza por las personas o al menos por sistemas de alertas que avisen en caso de error.

    Por lo que cuentas, tu escenario se adaptaría bastante mejor a log shipping que a una replicación transaccional, plantéatelo también como sistema de respaldo.

    Otra cosa es que estés realizando una aplicación que te permita realizar todas esas cosas con fines de comercializarla, esto es, que tu negocio fuera realizar esa aplicación. Si es así, pues nada, adelante, tienes un reto tan grande como bonito por delante, aunque te aviso que la competencia es monstruosa. En otro caso, y lo digo, insisto, con el debido respeto, estás intentando inventar la rueda e invirtiendo una cantidad de tiempo muy grande, y el que tendrás que invertir para mantenerlo será mucho mayor.

    Volviendo a tu cuestión, veo que lo que te falta sería capturar las modificaciones de datos para transmitirlos. Decirte que te queda lo más complicado, ya que no es nada fácil saber cuándo hay que anotar el cambio para transmitirlo. Por ejemplo, puedes capturar una inserción, pero puede que luego se haga un rollback de la misma, y eso ya complica mucho más la cuestión.

    En esa línea, lo más simple es que implementes triggers que vuelquen los datos a tablas intermedias y que otro proceso lea de esas tablas intermedias y las mande al suscriptor. Son datos, no comandos. Otra alternativa es que aprendas a leer el log de transacciones, algo que no es trivial y que además tiene otros peligros. Comento estas vías porque son las que usan otros productos comerciales para estos fines.


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

    Monday, August 27, 2012 6:22 PM

All replies

  • No uses triggers, son lentos, difíciles de mantener.

    Tienes SQL Server 2008 ?

    Si es así usa el SQL Server Audit:

    http://www.mssqltips.com/sqlservertip/1954/sql-server-2008-auditing-feature/


    MVP MCT MCTS Daniel Calbimonte

    http://elpaladintecnologico.blogspot.com

    Wednesday, August 15, 2012 8:18 PM
  • El consejo de Dani es lo mejor para tu caso, ademas a diferencia de otros motores SQL Server no tiene triggers por SELECT..
    Thursday, August 16, 2012 4:05 AM
  • Es que aquí en el trabajo cuentan con SQL 2000

    no puedo llegar así nada mas y cambiarlo, 

    a parte de la migración, pues está la licencia, 

    la idea es no tocar nada


    saludos

    Tuesday, August 21, 2012 12:50 PM
  • La verdad que nunca he visto la ejecucion de trazas en TSQL 2000, pero puedes fijarte en estos 2 enlaces a ver si te sirven

    http://support.microsoft.com/kb/283790/es

    http://consejosdelguru.blogspot.com/2007/10/monitoreo-de-sql-server-2000.html
    Tuesday, August 21, 2012 12:55 PM
  • Hola.

    ¿Y por qué no usas profiler? ¿Por qué no te sirve? Desde luego es lo más fácil de implementar y de explotar, mucho más que cazar mediante un trigger la sentencia que se ejecuta sobre una tabla.


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

    Monday, August 27, 2012 2:45 PM
  • Porqué aquí la empresa no tiene los recursos para implementar un cluster en nuestros servidores de bases de datos por lo que estamos haciendo una aplicación que copie  la información  en tiempo real de un servidor a otro como respaldo, 

    Es por lo pronto una forma de tener respaldo, redundancia y "alta disponibilidad"

    Al menos así, si llegase a caer un servidor, tendríamos el 99.9% de la información disponible en otro servidor.

    la capa de datos está preparada para 'switchearse' al otro servidor en un escenario como estos.

    Entonces, lo que busco es, ejecutar el query(ó comando) obtenido de nuestro servidor primario al secundario

    Mi primera solución fue, detectar los cambios por registro mediante un trigger, y así pasarlos al otro servidor

    asincronamente mediante la aplicación.

    pero supongo que es mas óptimo sacar el query y ejecutarlo al otro servidor, por ejemplo

    si se hace un update al una tabla para 100 registros,

    ejecutando una sola vez ese query del otro lado es mas eficiente que

    barrer 100 registros y actualizarlos uno a uno, que es como lo tengo actualmente.

    como ves?



    saludos

    Monday, August 27, 2012 2:58 PM
  • Hola.

    Con el debido respeto, estás intentando desarrollar un mecanismo de replicación casero. Implementa replicación transaccional, hace lo que pretendes y ya está hecho, está incluido en el producto, documentado, es sólido y eficaz.

    http://technet.microsoft.com/en-us/library/cc917706.aspx

    No te diré que es algo fácil de aprender, pero comparado con lo que pretendes hacer es infinitamente más sencillo.


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

    Monday, August 27, 2012 3:04 PM
  • yo sé. de hecho, la tenemos configurada actualmente, pero tiene algunas deficiencias:

    1.- Copia los registros como máximo cada 10 segundos, es decir, no podemos acelerarla mas de eso, y 10 segundos es demasiado para nosotros, ya no se puede bajar mas el tiempo.

    2.- Cuando falla la actualización de un registro de primario a secundario, la replica se cae, truena, y ya no continua, y esto está fatal,

    3.- No hace la replicación de tablas, vistas, procedures, triggers etc....  Resulta que la aplicación que estoy haciendo, detecta los nuevos objetos o los cambios que se hagan en éstos y los replica  =)  ya no es sólo información, jeje, 

    4.- La replicación deja de trabajar si no caen registros en el servidor primario después de 72 horas,  

    hemos visto ya varios tipos de replicas y pues nada bueno jiji

    existe otro pequeño inconveniente, se tienen servidores con SQL 2000 para replicarlos en 2000

    y sql 2005 a sql 2005, 

    por si querías darme ideas de replicas mejoradas en 2008, pues no podemos pagar mas licenciamiento =(


    así que como verás, si pudiera obtener esos comandos, ya estaría de 100 la aplicación =)

      


    saludos

    Monday, August 27, 2012 3:17 PM
  • Hola.

    Lo que comentas plantea algunas cuestiones impensables.

    1.- No es posible que una empresa que no puede permitirse adquirir un cluster pretenda una sincronización con una instancia de respaldo en la que un retardo de 10 segundos suponga un problema. De hecho, si se te rompe un disco, si tienes un bloqueo medianamente largo, con el propio proceso de undo, pierdes más de 10 segundos de información.

    2.- Aunque a mí eso me parece algo muy positivo porque te permite no perder ninguna transacción, puedes parametrizar la replicación para que se salte algunos tipos de errores (parámetro -SkipErrors).

    3.- La transmisión de objetos también es posible implementarla con replicación. De hecho, su automatización plantea cuestiones bastante peliagudas. Sin embargo, un entorno con frecuentes cambios no es el escenario apropiado para una replicación transaccional.

    4.- No puede ser que sea un problema perder 10 segundos de datos y que puedan alcanzarse las 72 horas sin pasar datos, dando lugar a que la suscripción caduque (otro parámetro que es configurable, ese es el valor por defecto). El alta disponibilidad empieza por las personas o al menos por sistemas de alertas que avisen en caso de error.

    Por lo que cuentas, tu escenario se adaptaría bastante mejor a log shipping que a una replicación transaccional, plantéatelo también como sistema de respaldo.

    Otra cosa es que estés realizando una aplicación que te permita realizar todas esas cosas con fines de comercializarla, esto es, que tu negocio fuera realizar esa aplicación. Si es así, pues nada, adelante, tienes un reto tan grande como bonito por delante, aunque te aviso que la competencia es monstruosa. En otro caso, y lo digo, insisto, con el debido respeto, estás intentando inventar la rueda e invirtiendo una cantidad de tiempo muy grande, y el que tendrás que invertir para mantenerlo será mucho mayor.

    Volviendo a tu cuestión, veo que lo que te falta sería capturar las modificaciones de datos para transmitirlos. Decirte que te queda lo más complicado, ya que no es nada fácil saber cuándo hay que anotar el cambio para transmitirlo. Por ejemplo, puedes capturar una inserción, pero puede que luego se haga un rollback de la misma, y eso ya complica mucho más la cuestión.

    En esa línea, lo más simple es que implementes triggers que vuelquen los datos a tablas intermedias y que otro proceso lea de esas tablas intermedias y las mande al suscriptor. Son datos, no comandos. Otra alternativa es que aprendas a leer el log de transacciones, algo que no es trivial y que además tiene otros peligros. Comento estas vías porque son las que usan otros productos comerciales para estos fines.


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

    Monday, August 27, 2012 6:22 PM
  • Parece ser que log shipping es justamente lo que necesito,   =0

    dejame leer mas acerca de esto y hacer unas pruebas,

    espero que el tiempo en enviar los datos sea rápido

    ...

    te aviso tks!


    saludos

    Monday, August 27, 2012 8:21 PM
  • Estoy viendo que existe una función llamada  EVENTDATA() que efectivamente entrega el TSQL COMMAND

    al actualizar un objeto de la base de datos, es decir, solo funciona para triggers de tipo DDL

    Data Definition Language

    al modificar la estructura de la tabla, me entrega bien bonito el query que lo quiere hacer,

    SELECT EVENTDATA().value ('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')

    pero EventData() es para DDL,

    Existirá algo parecido para  DML TRIGGERS? hay algo como sys.trigger_events 

    pero no es exactamente lo que necesito, 

    estoy seguro, debe de poderse...


    saludos

    Tuesday, August 28, 2012 5:39 PM
  • Hola.

    Insisto en la que ya te comenté, si desestimas la utilización de log shipping para lograr tu servidor de respaldo (que es lo más fácil, barato y lo que puedo recomendarte), puedes o bien leer del log de transacciones (no está documentado, pero hay herramientas comerciales que permiten hacerlo) o bien preparas triggers de inserción, actualización y borrado en cada tabla que te permitan capturar lo que se modifica. Otra opción pasaría por capturar trazas y luego emplearlas para ejecutarlas en el otro servidor.

    Ninguno de los tres últimos métodos son fáciles y no te los recomiendo. Existen tecnologías de SQL Server que permiten hacer lo que te propones, no todas en las versiones que empleas, y que estás descartando por tener puntos de fallo que no son, ni de lejos, nada comparable con lo que te propones realizar.

    En cualquier caso, mucha suerte.


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

    Tuesday, August 28, 2012 6:10 PM
  • estuve viendo que lo más rápido que log shipping envía los datos es cada minuto

    y puf, es mucho 

    =(

    buscándole, me he encontrado con los comandos ejecutados ó por ejecutar

    el procesado y el solicitado jeje

    SELECT  t.*

    FROM sys.sysprocesses r

    Cross apply sys.dm_exec_sql_text([sql_handle]) t

    where spid = @@spid

    select t.*

    from sys.dm_exec_requests r

    Cross apply sys.dm_exec_sql_text([sql_handle]) t

    where session_id = @@spid

    aún así, ya me rindo, seguirá siendo por trigger en cada tabla  =( como bien lo dices

    y como así lo tengo hoy por hoy.

    porque veo que con los TSQLCOMMANDS obtengo la definición del trigger en el processes

    ya que el trigger se dispara despues de... (AFTER)

    y obviamente también es el mismo en el request porqué fue lo último que se solicitó

    =(

    en fin, no iba tan mal jajaja

    renuncio!


    saludos

    Tuesday, August 28, 2012 6:26 PM