Antecedentes :
Estamos tentando criar um equipamento de teste "básico" da AG para uma de nossas equipes de suporte. Não sabendo quais servidores, em um determinado momento, serão os principais instruídos para executar o TSQL em um grupo de servidores registrado. O grupo de servidores registrados consiste em todos os servidores no AG. O objetivo é executar apenas o TSQL no servidor principal atual:
Arnês de teste atual :
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 :
Se o primeiro servidor que responder à consulta de vários servidores não retornar nenhum resultado, o SSMS assumirá que o conjunto de resultados correto não é um conjunto de resultados, mesmo que outros servidores posteriormente retornem com um conjunto de resultados. Portanto, nesse cenário, nenhum resultado é retornado ... isso não está correto e não é a funcionalidade esperada.
Alguém pode pensar em uma maneira, com o SSMS (essa é a ferramenta mais familiar para a equipe de CS), forçar a execução apenas no servidor principal atual?
fonte
Respostas:
Eu já deparei com isso ** antes, e se bem me lembro, para garantir sempre a obtenção de resultados com consultas de vários servidores, você precisa forçar um conjunto de resultados vazio quando nenhuma linha seria retornada. Ou seja, você precisa de uma
ELSE
ramificação para issoIF
e, dentro doELSE
diretório, faria algo como o seguinte:Isso produz um conjunto de resultados vazio que possui os nomes e tipos de dados adequados.
OU, e eu não tentei isso no passado (pensei nisso enquanto estava digitando isso), mas você pode simplesmente fazer uma pausa nesse
ELSE
ramo, de modo que o servidor primário / pretendido sempre possa retornar seu primeiro conjunto de resultados (que é o problema real aqui: o primeiro servidor a responder define a estrutura que todas as outras respostas devem aderir). Portanto, o seguinte pode funcionar como a única coisa noELSE
:Mas não me lembro se outros servidores retornaram nenhum resultado, causando a exibição de uma mensagem de erro na guia "Mensagens". Se isso acontecer, o conjunto de resultados vazio é definitivamente o caminho a percorrer. Mas se isso funcionar, poderá funcionar melhor em um modelo geral (como parece o seu caso), pois não exigiria o ajuste do conjunto de resultados vazio e forçado toda vez que for usado.
ATUALIZAR:
O OP verificou que:
WAITFOR DELAY
realmente funcionou, e** A situação em que me deparei era semelhante, mas não tinha nada a ver com os Grupos de Disponibilidade ou com os resultados de apenas um servidor. Nossa situação era que tínhamos 18 servidores com o mesmo esquema de dados diferentes e precisávamos executar várias tarefas de manutenção, agregações em todos os 18 nós. Havia alguns procedimentos armazenados que, por qualquer motivo, ocasionalmente não retornavam nenhum conjunto de resultados e, por qualquer motivo, não era possível corrigi-lo no procedimento armazenado. Portanto, dependendo de qual nó retornou primeiro, na maioria das vezes tudo estava bem, mas de vez em quando o nó que às vezes retornava nenhum conjunto de resultados retornava primeiro. Então, eu tinha que fazer algo como despejar os resultados em uma tabela temporária e se
@@ROWCOUNT
issoINSERT...EXEC
foi de 0, então eu iria selecionar o forçado, conjunto de resultados vazio.fonte
WAITFOR DELAY
abordagem e que você confirmou que funcionou, então obrigado por isso!Eu sempre usei uma tabela temporária para retornar resultados e obter respostas consistentes de todos os servidores em um grupo. As consultas com vários servidores são uma das minhas coisas favoritas sobre o SSMS.
fonte