【问题标题】:Implement symmetric difference in SQL Server?在 SQL Server 中实现对称差异?
【发布时间】:2010-09-09 06:16:12
【问题描述】:

这是我在工作中一直试图解决的一个问题。我不是数据库专家,所以这可能有点幼稚。所有的道歉。

我有一个给定的数据库 D,它已在另一台机器上复制(以一种可能可疑的方式),导致数据库 D'。我的任务是检查数据库 D 和 D' 实际上是否完全相同。

当然,问题在于如果它们不是,该怎么做。为此,我的想法是在每个对应的表上运行对称差异并查看差异。

有一个“大量”的表,所以我不希望手动运行每个对称差异。然后我如何实现一个可以在任意表上运行而无需显式枚举列的对称差异“函数”(或存储过程,或任何你想要的)?

这是在 Windows 上运行的,如果你不遵守,你的对冲基金就会爆炸。祝你好运。

【问题讨论】:

  • 好的,Red Gate 确实是一个解决方案。但这不应该是一个非常普遍的问题吗?不应该有一个简单的程序化解决方案吗?

标签: sql sql-server


【解决方案1】:

我的第一反应是建议以毫不怀疑的方式再次复制到另一台机器。

如果这不是一个选项,也许Red Gate 提供的一些工具可以满足您的需求。

(我与 Red Gate 没有任何关系,只记得 Joel 在播客中提到他们的工具有多好。)

【讨论】:

  • 啊。你打败了我!
【解决方案2】:

使用Red Gate 的 SQL 比较工具。它比较模式,SQL 数据比较工具比较数据。我认为您可以免费试用它们,但如果这是一个反复出现的问题,您不妨购买它们。可能有像这样的开源或免费工具,但你最好只买这个。

【讨论】:

    【解决方案3】:

    这里是解决方案。示例数据来自 SSRS 2008 R2 附带的 ReportServer 数据库,但您可以在任何数据集上使用它:

    SELECT s.name, s.type 
    FROM 
    (
        SELECT s1.name, s1.type
        FROM syscolumns s1
        WHERE object_name(s1.id) = 'executionlog2'
        UNION ALL 
        SELECT s2.name, s2.type
        FROM syscolumns s2 
        WHERE object_name(s2.id) = 'executionlog3'
    ) AS s 
    GROUP BY s.name, s.type   
    HAVING COUNT(s.name) = 1
    

    【讨论】:

      【解决方案4】:

      SQL Server 2000 增加了“EXCEPT”关键字,与Oracle的“减号”几乎一模一样

      SELECT * FROM TBL_A WHERE ...
      EXCEPT
      SELECT * FROM TBL_B WHERE ...
      

      【讨论】:

        【解决方案5】:

        你可以通过这样做来实现这一点。

        我使用了一个函数将逗号分隔的值拆分为表格进行演示。

        CREATE FUNCTION [dbo].[Split]
        (
            @RowData nvarchar(2000),
            @SplitOn nvarchar(5)
        )  
        RETURNS @RtnValue table 
        (
            Id int identity(1,1),
            Data nvarchar(100)
        ) 
        AS  
        BEGIN 
            Declare @Cnt int
            Set @Cnt = 1
        
            While (Charindex(@SplitOn,@RowData)>0)
            Begin
                Insert Into @RtnValue (data)
                Select 
                    Data = ltrim(rtrim(Substring(@RowData,1,Charindex(@SplitOn,@RowData)-1)))
        
                Set @RowData = Substring(@RowData,Charindex(@SplitOn,@RowData)+1,len(@RowData))
                Set @Cnt = @Cnt + 1
            End
        
            Insert Into @RtnValue (data)
            Select Data = ltrim(rtrim(@RowData))
        
            Return
        END
        GO
        
        
        DECLARE @WB_LIST varchar(1024) = '123,125,764,256,157';
        DECLARE @WB_LIST_IN_DB varchar(1024) = '123,125,795,256,157,789';
        
        DECLARE @TABLE_UPDATE_LIST_IN_DB TABLE ( id varchar(20));
        DECLARE @TABLE_UPDATE_LIST TABLE ( id varchar(20));
        
        INSERT INTO @TABLE_UPDATE_LIST
        SELECT data FROM dbo.Split(@WB_LIST,',');
        
        INSERT INTO @TABLE_UPDATE_LIST_IN_DB
        SELECT data FROM dbo.Split(@LIST_IN_DB,',');
        
        
        SELECT * FROM @TABLE_UPDATE_LIST
        EXCEPT
        SELECT * FROM @TABLE_UPDATE_LIST_IN_DB
        UNION
        SELECT * FROM @TABLE_UPDATE_LIST_IN_DB
        EXCEPT
        SELECT * FROM @TABLE_UPDATE_LIST;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-05-09
          • 1970-01-01
          • 2017-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多