Har*_*rry 9 sql-server ssms t-sql
背景:
我们正在尝试为我们的一个支持团队创建一个 AG“是主要的”测试工具。不知道在任何给定时间哪些服务器将是主服务器,它们被指示对注册的服务器组执行 TSQL。注册服务器组由AG中的所有服务器组成。目标是只在当前主服务器上执行 TSQL:
当前测试线束:
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
Run Code Online (Sandbox Code Playgroud)
问题:
如果响应多服务器查询的第一台服务器没有返回任何结果,SSMS 将假定正确的结果集没有结果集,即使其他服务器稍后返回结果集也是如此。因此,在这种情况下,不会返回任何结果……这是不正确的,也不是预期的功能。
谁能想出一种方法,使用 SSMS(这是 CS 团队最熟悉的工具),仅在当前主服务器上强制执行?
Sol*_*zky 10
我之前遇到过这个**,如果我没记错的话,为了确保始终通过多服务器查询获得结果,您需要在不返回任何行时强制使用空结果集。意思是,你需要一个ELSE分支,IF在里面ELSE你会做如下的事情:
SELECT CONVERT(DATETIME, NULL) AS [Col1name],
CONVERT(DECIMAL(12, 5), NULL) AS [Col2name],
...{additional fields}...
WHERE 1 = 0;
Run Code Online (Sandbox Code Playgroud)
这将产生一个具有正确名称和数据类型的空结果集。
或者,我过去没有尝试过(只是在我输入时想到它),但是您可能可以通过简单地在该ELSE分支中暂停而逃脱,以便允许主/预期服务器始终返回其结果集优先(这是这里的真正问题:第一个响应的服务器定义了所有其他响应必须遵守的结构)。因此,以下内容可能是 中唯一的内容ELSE:
WAITFOR DELAY '00:00:10'; -- 10 seconds (just needs to be longer than the real query takes)
Run Code Online (Sandbox Code Playgroud)
但我不记得是否让其他服务器根本不返回任何结果导致在“消息”选项卡中显示错误消息。如果确实发生了,那么空结果集肯定是要走的路。但是,如果这确实有效,那么这在通用模板中可能会更好(就像您的情况一样),因为它不需要在每次使用时调整强制的空结果集。
更新:
OP 证实:
WAITFOR DELAY确实工作,**我遇到的情况类似,但与可用性组或仅从一台服务器获得结果无关。我们的情况是,我们有 18 个具有相同模式不同数据的服务器,并且需要执行各种维护任务,跨所有 18 个节点进行聚合。有一些存储过程,无论出于何种原因,偶尔不返回任何结果集,无论是什么原因,都无法在存储过程中修复。因此,取决于哪个节点首先返回,大多数情况下一切都很好,但每隔一段时间,有时不返回结果集的节点首先返回。所以,我必须做一些事情,比如将结果转储到一个临时表中,如果@@ROWCOUNT它INSERT...EXEC是 0,那么我会选择强制的空结果集。