【问题标题】:Calling one sp from another从另一个调用一个 sp
【发布时间】:2013-06-01 21:52:16
【问题描述】:

在这个链接上

http://gallery.technet.microsoft.com/Compare-Data-0c5bfc87#content

我们可以找到一个可以比较两个表数据的存储过程示例。我想为数据库中的每个表调用这个 sp。我找到了下一个将枚举所有表的 sp

http://weblogs.sqlteam.com/joew/archive/2007/10/23/60383.aspx

问题是我无法正确传递参数。这是我尝试过的(我已将两个数据库都放在本地服务器上):

Exec sp_MSforeachtable "EXEC sp_CompareTable dbName1, dbName2, NULL, PARSENAME('?', 1)"

失败了

消息 102,级别 15,状态 1,第 1 行 '[dbo].[Activities]' 附近的语法不正确。

每张桌子都有相同的信息。谁能帮我解决我在这里做错的事情?

【问题讨论】:

  • 来自您的链接:“当然,我们可以创建一个脚本,该脚本使用游标循环遍历数据库中的所有表,以通过动态 SQL 进行竞标。糟糕!” - 那将是我的建议:使用光标并省略这个魔法未记录的东西。最好的问候

标签: tsql stored-procedures sql-server-2012-express


【解决方案1】:

我会伸出脖子并将其发布为答案,因为它没有很好地格式化为评论。 你有没有试过这个:

sp_MSforeachtable "EXEC sp_CompareTable dbName1, dbName2, NULL, PARSENAME('[?]', 1)"

更新:

它看起来不喜欢 PARSENAME。你可以试试这个(我在一个版本的 sp_CompareTable 上试过这个,EXEC 改为 PRINT)。

  1. 将此行添加到 sp_CompareTable(在 EXEC 之前):

    SET @TableName = PARSENAME(@TableName,1)
    
  2. 这样称呼它:

    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, '?'"

【讨论】:

  • '[[dbo]].[Activities]]]' 附近的语法不正确。结果只是更多的括号
  • 如果你只有“dbo”,你可以试试我的快速修复(上面更新)。
  • 与问题无关,但也许值得一提。您不应该在存储过程中真正使用前缀“sp_”。我怀疑对此的适当修复将涉及重写 sp_CompareTable(我可能会稍后再看),在这种情况下,它也应该重命名。
猜你喜欢
  • 1970-01-01
  • 2011-01-18
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
  • 2012-02-24
相关资源
最近更新 更多