动态比较Linked Servers SQL上的表

时间:2017-04-17 18:55:58

标签: sql-server sql-server-2012

我必须比较表(SIB $)以获得两个相同的LINKED SERVERS(LATESTDUMP,OLDDUMP)上的不匹配记录。我已经尝试过创建动态查询。有人可以帮我跟进: 1)有没有办法我不必将列名称传递给代码,代码动态获取列名称并将其用作列表进行比较。
所以我要做的就是将两个表名称传递给存储过程

我编写的代码:

DECLARE @sql nvarchar(max) = ' ((SELECT  * FROM LATESTDUMP...SIB$) t1 FULL 
OUTER JOIN (SELECT * FROM OLDDUMP...SIB$) t2
ON t1.id = t2.id
WHERE
t1.id IS NULL OR
t2.id IS NULL)'

SELECT  @sql += ' or t1.' + quotename(column_name) + ' <> t2.' + 
quotename(column_name) from information_schema.columns where table_name = 
'SIB$'

2 个答案:

答案 0 :(得分:0)

您可能希望查看自SQL 2008以来可用的MERGE语句。 https://docs.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql

答案 1 :(得分:0)

这里有一些代码可以帮助您入门。它会拉出一个主键(假设一列主键,这可能是也可能不是你的有效假设),并抓取剩余列的逗号分隔字符串列表。

从这里你可以使用split-string来构建一个sql字符串,它连接主键上硬编码链接服务器中的两个同名表,比较每个列的差异,然后执行动态SQL 。我已经包含了一些测试脚手架,因此您可以通过以下方式完成:

   DECLARE @tableName sysname;
   SET @tableName = 'some table'

    -- Validate parameter
    IF @tableName IS NULL OR NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @tableName AND TABLE_TYPE = 'BASE TABLE')
    BEGIN
        RAISERROR ('Invalid table name specified', 16, 1);
        RETURN;
    END;

    -- Validate table has a primary key
    IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'PRIMARY KEY' AND TABLE_NAME = @tableName)
    BEGIN
        RAISERROR ('Specified table does not have a primary key', 16, 1);
        RETURN;
    END;

    -- Get info about the Primary Key columns
    DECLARE @pkcolName sysname;
    SELECT @pkcolName = c.COLUMN_NAME 
      FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
           INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
           INNER JOIN INFORMATION_SCHEMA.COLUMNS c ON kcu.TABLE_NAME = c.TABLE_NAME AND kcu.COLUMN_NAME = c.COLUMN_NAME
     WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY' AND tc.TABLE_NAME = @tableName AND kcu.ORDINAL_POSITION = 1

    -- Grab the names of all the remaining columns
    DECLARE @nonKeyColumns nvarchar(MAX);
    SELECT @nonKeyColumns = STUFF ( ( SELECT N'], [' + c.name
                FROM sys.columns c
               WHERE object_id = (select top 1 object_id FROM sys.objects where name = @tableName) 
                 AND c.name <> @pkcolName 
               ORDER BY c.column_id
                 FOR XML PATH('')), 1, 2, '') + ']';

SELECT @pkcolName 
SELECT @nonKeyColumns