我会伸出脖子并将其发布为答案,因为它没有很好地格式化为评论。你有没有试过这个:
sp_MSforeachtable "EXEC sp_CompareTable dbName1, dbName2, NULL, PARSENAME('[?]', 1)"
更新:
看起来它不喜欢 PARSENAME。你可以试试这个(我在一个版本的 sp_CompareTable 上试过这个,将 EXEC 更改为 PRINT)。
将此行添加到 sp_CompareTable(在 EXEC 之前):
SET @TableName = PARSENAME(@TableName,1)
像这样称呼它:
sp_MSforeachtable "EXEC sp_CompareTable dbName1, dbName2, dbo, '?'"
注意:对于只有“dbo”模式的情况,这将是一个快速解决方案。它并没有真正回答原始语法为什么不起作用的问题。
再次更新:
这是一个比较表存储过程的版本,它被定制为与 sp_MSforeachtable 一起运行
CREATE PROC [dbo].[uspCompareTable](@db1 varchar(250), @db2 sysname, @TableName sysname)
AS
declare @reason varchar(7)='Missing';
IF @TableName = '[dbo].[sysdiagrams]'
RETURN
IF CHARINDEX('.',@db1,1) <> 0
SET @db1=QUOTENAME(SUBSTRING(@db1,1, CHARINDEX('.',@db1,1)-1))+'.'+QUOTENAME(SUBSTRING(@db1, CHARINDEX('.',@db1,1)+1,DATALENGTH(@db1)-CHARINDEX('.',@db1,1)))
IF CHARINDEX('.',@db2,1) <> 0
SET @db2=QUOTENAME(SUBSTRING(@db2,1, CHARINDEX('.',@db2,1)-1))+'.'+QUOTENAME(SUBSTRING(@db2, CHARINDEX('.',@db2,1)+1,DATALENGTH(@db2)-CHARINDEX('.',@db2,1)))
EXEC ('
SELECT * FROM
(SELECT * FROM '+ @db1 + '.' + @TableName +'
EXCEPT
SELECT * FROM '+ @db2 + '.' + @TableName +') T
CROSS JOIN (SELECT '''+@reason +' in '+@db2 +'.' + @TableName+''' Reason) T2
UNION ALL
SELECT * FROM
(SELECT * FROM '+ @db2 + '.' + @TableName +'
EXCEPT
SELECT * FROM '+ @db1 + '.' + @TableName +' ) T
CROSS JOIN (SELECT ''' + @reason + ' in ' + @db1 + '.' + @TableName + ''' Reason) T2')
在这里,我假设架构将成为 TableName 的一部分(如果您从 sp_MSforeachtable 调用它应该是)。还有一个调整以跳过在我的系统(SQL Server 2008 Express)上获取的系统图表。
用法是
sp_MSforeachtable "EXEC uspCompareTable dbname1, dbname2, '?'"