【问题标题】:Run query for each element in array or list对数组或列表中的每个元素运行查询
【发布时间】:2021-06-10 20:59:47
【问题描述】:

我正在尝试监控访问我们数据库的所有连接。

为了做到这一点,我创建了这个查询:

SELECT @@ServerName AS [ServerName]
             ,NAME AS DatabaseName 
             ,COUNT(STATUS) AS [NumberOfConnections]
             ,GETDATE() AS [TimeStamp]
             ,hostname
             ,program_name
             ,loginame
FROM sys.databases sd
LEFT JOIN master.dbo.sysprocesses sp ON sd.database_id = sp.dbid
WHERE database_id NOT BETWEEN 1 AND 4
GROUP BY NAME,hostname ,program_name ,loginame
GO

在本地计算机上返回的正是我想要的:

很好,有ServerName,还有DatabaseName,还有NumberOfConnections,等等……

但是如果我想在远程服务器上运行它呢?实际上,在我的实验室中,我有一个名为[TESLABSQL02T] 的远程服务器,让我们看看我是否可以query it remotely

SELECT @@ServerName AS [ServerName]
             ,NAME AS DatabaseName 
             ,COUNT(STATUS) AS [NumberOfConnections]
             ,GETDATE() AS [TimeStamp]
             ,hostname
             ,program_name
             ,loginame
FROM [TESLABSQL02T].master.sys.databases sd
LEFT JOIN [TESLABSQL02T].master.sys.sysprocesses sp ON sd.database_id = sp.dbid
WHERE database_id NOT BETWEEN 1 AND 4
GROUP BY NAME,hostname ,program_name ,loginame

太酷了:现在我想监控我的所有网络!

这就是事情变得棘手的时候:我想在每 10 分钟运行一次并且可以查询大约 30 台服务器的作业中自动执行此操作。

让我们先尝试两台服务器[TESLABSQL01T][TESLABSQL02T]

DECLARE @myTableVariable TABLE (id INT, ServerName varchar(50))
insert into @myTableVariable values(1,'[TESLABSQL01T]'),(2,'[TESLABSQL02T]')
select * from @myTableVariable


SELECT @@ServerName AS [ServerName]
             ,NAME AS DatabaseName 
             ,COUNT(STATUS) AS [NumberOfConnections]
             ,GETDATE() AS [TimeStamp]
             ,hostname
             ,program_name
             ,loginame
FROM (select ServerName from @myTableVariable).master.sys.databases sd
LEFT JOIN (select ServerName from @myTableVariable).master.sys.sysprocesses sp ON sd.database_id = sp.dbid
WHERE database_id NOT BETWEEN 1 AND 4
GROUP BY NAME,hostname ,program_name ,loginame

不幸的是没有快乐:(

查询在FROMLEFT JOIN 附近给了我一个Incorrect syntax

如何让这个查询每 10 分钟在每台远程服务器上运行一次?

我应该使用列表、数组、临时表还是普通表?

我听说 FETCH NEXT FROM ObjectCursor ,可以选择吗?

动态查询?

...每个建议都是有效的。谢谢。

【问题讨论】:

  • 根据问题指南,请不要发布代码、数据、错误消息等的图像 - 将文本复制或输入到问题中。请保留将图像用于图表或演示渲染错误,无法通过文本准确描述的事情。
  • @DaleK,我删除了图像。问题是用 StackOverflow 中的代码创建一个表很痛苦。有没有简单的方法?
  • 有表格格式化语法(查看帮助),您可以从许多来源复制和粘贴数据,然后格式化为代码,完全可以接受。
  • 嗨@DaleK,我找到了一个可以帮助我格式化表格的网站:tablesgenerator.com/markdown_tables#。从现在开始我将使用它。我相信 StackOverflow 应该赞助这个或复制相同的工具并在编辑器中提供它
  • Stackoverflow 确实支持表 meta.stackoverflow.com/questions/302471/…

标签: sql-server tsql automation database-administration sql-server-agent


【解决方案1】:

要解决语法错误,您必须使用游标创建动态查询:

DECLARE @ServerName varchar(50), @DynamicSQL NVARCHAR(MAX)
DECLARE @myTableVariable TABLE (id INT, ServerName varchar(50))
insert into @myTableVariable values(1,'[TESLABSQL01T]'),(2,'[TESLABSQL02T]')
select * from @myTableVariable

Declare VarCursor cursor for
Select ServerName from @myTableVariable
Open VarCursor
FETCH NEXT FROM VarCursor INTO @ServerName
WHILE @@FETCH_STATUS = 0 
BEGIN
    SET @DynamicSQL='SELECT @@ServerName AS [ServerName]
                 ,NAME AS DatabaseName 
                 ,COUNT(STATUS) AS [NumberOfConnections]
                 ,GETDATE() AS [TimeStamp]
                 ,hostname
                 ,program_name
                 ,loginame
    FROM '+@ServerName+'.master.sys.databases sd
    LEFT JOIN '+@ServerName+'.master.sys.sysprocesses sp ON sd.database_id = sp.dbid
    WHERE database_id NOT BETWEEN 1 AND 4
    GROUP BY NAME,hostname ,program_name ,loginame'
    

    EXEC (@DynamicSQL)

    FETCH NEXT FROM VarCursor INTO @ServerName
END
CLOSE VarCursor
DEALLOCATE VarCursor

但是对于此查询,您必须确保您在所有服务器中都具有特权,或者您在主要 SQL Server 引擎中具有链接服务器

【讨论】:

  • 你教我FETCH NEXT,谢谢@Isaac
  • 如果我在远程服务器上运行sp_who2,我会看到我的用户以DORMANT 状态连接到SSMS。有没有办法断开我的用户?再次感谢您
  • 但上面写着Cannot use KILL to kill your own process.
猜你喜欢
  • 1970-01-01
  • 2020-05-29
  • 1970-01-01
  • 1970-01-01
  • 2020-12-10
  • 2017-12-06
  • 2020-03-26
  • 2018-01-11
  • 1970-01-01
相关资源
最近更新 更多