Antecedentes :
Estamos tratando de crear un arnés de prueba "primario" para uno de nuestros equipos de soporte. Sin saber qué servidores en un momento dado serán los principales, se les ha indicado que ejecuten el TSQL contra un grupo de servidores registrados. El grupo de servidores registrados consta de todos los servidores de la AG. El objetivo es ejecutar solo TSQL en el servidor primario actual:
Arnés de prueba actual :
IF EXISTS (SELECT *
FROM sys.dm_hadr_availability_replica_states AS HARS
INNER JOIN sys.dm_hadr_availability_replica_cluster_states AS HACS ON HACS.replica_id = HARS.replica_id
WHERE (HARS.role_desc = 'PRIMARY') AND (HACS.replica_server_name LIKE @@SERVERNAME))
BEGIN
<<SOME CODE TO EXECUTE>>
END
Problema :
Si el primer servidor que responde a la consulta del servidor múltiple no devuelve ningún resultado, SSMS asumirá que el conjunto de resultados correcto no es un conjunto de resultados, incluso si otros servidores luego regresan con un conjunto de resultados. Entonces, en este escenario, no se devuelven resultados ... esto no es correcto y no es la funcionalidad esperada.
¿Alguien puede pensar en una forma, con SSMS (esta es la herramienta más familiar para el equipo de CS), para forzar la ejecución solo en el servidor primario actual?
fuente
Respuestas:
Me he encontrado con esto ** antes, y si recuerdo correctamente, para garantizar que siempre obtenga resultados con consultas de varios servidores, debe forzar un conjunto de resultados vacío cuando de lo contrario no se devolverían filas. Es decir, necesita una
ELSE
rama sobre esoIF
y dentro deELSE
esto haría algo como lo siguiente:Esto produce un conjunto de resultados vacío que tiene los nombres y tipos de datos adecuados.
O bien, y no lo he intentado en el pasado (solo pensé que estaba escribiendo esto), pero es posible que pueda salirse con la pausa simplemente en esa
ELSE
rama de modo que el servidor primario / previsto siempre pueda devolver su conjunto de resultados primero (que es el problema real aquí: el primer servidor que responde define la estructura a la que deben adherirse todas las demás respuestas). Por lo tanto, lo siguiente podría funcionar como lo único enELSE
:Pero no recuerdo si hacer que otros servidores no devuelvan ningún resultado provocó que se mostrara un mensaje de error en la pestaña "Mensajes". Si eso sucede, entonces el conjunto de resultados vacío es definitivamente el camino a seguir. Pero si esto funciona, entonces podría funcionar mejor en una plantilla general (como parece ser su caso) ya que no requeriría ajustar el conjunto de resultados forzado y vacío cada vez que se usa.
ACTUALIZAR:
El OP verificó que:
WAITFOR DELAY
hecho funcionó, y** La situación con la que me encontré fue similar, pero no tenía nada que ver con los Grupos de disponibilidad o con los resultados deseados de un solo servidor. Nuestra situación era que teníamos 18 servidores con el mismo esquema de datos diferentes y necesitábamos hacer varias tareas de mantenimiento, agregaciones en los 18 nodos. Hubo algunos procedimientos almacenados que, por el motivo que sea, ocasionalmente no devolvieron ningún conjunto de resultados, y cualquiera que sea el motivo, no se pudo solucionar dentro del procedimiento almacenado. Entonces, dependiendo de qué nodo regresó primero, la mayoría de las veces todo estuvo bien, pero de vez en cuando el nodo que a veces no devolvió ningún conjunto de resultados regresó primero. Entonces, tuve que hacer algo como volcar los resultados en una tabla temporal y si
@@ROWCOUNT
esoINSERT...EXEC
fuera 0, entonces seleccionaría el conjunto de resultados forzado y vacío.fuente
WAITFOR DELAY
enfoque y que usted confirmó que funcionó, ¡así que gracias por eso!Siempre he usado una tabla temporal para devolver resultados para obtener respuestas consistentes de todos los servidores de un grupo. Las consultas de varios servidores son una de mis cosas favoritas sobre SSMS.
fuente