我想创建一个可以清理 master 和 msdb 的维护数据库,我正在尝试从 master 和 msdb 收集所有不是 Microsoft 表的表信息,请记住,由于不同的要求,某些实例可能具有不同的结构。我收到代码错误
消息 102,级别 15,状态 1,第 27 行“@ServerName”附近的语法不正确
有没有更简单的方法来做到这一点?
DECLARE servers_cursor CURSOR
FOR
-- select * from environment
-- select * from DatabaseInfo
select distinct LinkedserverName,Environment,ServerUse
from SQLMonitor.dbo.Environment
join master..sysservers on srvname COLLATE DATABASE_DEFAULT = LinkedserverName COLLATE DATABASE_DEFAULT
where ServerUse = 'DEV'
--and IncludeBackupsStats = 1
order by LinkedServerName
OPEN servers_cursor
DECLARE @Servername varchar(255)
DECLARE @sql varchar(8000)
DECLARE @Environment char(4)
DECLARE @ServerUse varchar(15)
FETCH NEXT FROM servers_cursor INTO @ServerName,@Environment,@ServerUse
WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT @ServerName
CREATE TABLE [_TempDetails_]
(DatabaseName sysname
,TableName sysname
,ActualCommand nvarchar(max))
INSERT INTO [TempTableScripts].dbo._TempDetails_
SELECT * FROM OPENQUERY(@ServerName, '
declare @TableNames table
(
DatabaseName sysname
, TableName sysname
)
insert @TableNames
EXEC sp_msforeachdb @command1 = ''use ?;
IF ''''?'''' IN (''''master'''',''''msdb'''')
BEGIN
SELECT ''''?'''', name from sys.tables T WHERE is_ms_shipped = 0
END'+'
select *, ''''SELECT TOP 1 * INTO ['''' + @ServerName + ''''_-_'''' + Databasename +''''_-_'''' + TableName +''''] FROM ['''' + @ServerName+''''].[''''+ Databasename + ''''].dbo.['''' + TableName + '''']''''
from @TableNames
')
--exec (@sql)
FETCH NEXT FROM servers_cursor INTO @ServerName,@Environment,@ServerUse
--PRINT @ServerName
END
CLOSE servers_cursor
DEALLOCATE servers_cursor
以下代码将检查当前实例上所有链接服务器的 master 和 msdb 数据库,报告非 Microsoft 提供的表:
您的代码有两个问题;
您不能
OPENQUERY
像这样使用变量:那需要是:
显然,这对您的情况不起作用,因为您正在尝试动态执行此操作。要实现这一点,您需要在动态 SQL 中执行动态 SQL。
此行包含对变量的嵌入式引用
@ServerName
,但该变量在动态 T-SQL 中不可见......该行需要是: