比较表列并在SQL Server 2014中显示错误消息中的差异

时间:2019-06-19 12:22:58

标签: sql sql-server

我正在尝试编写一些SQL,它将比较两个SQL Server表并在错误消息中显示列中的任何差异。可能存在多个差异,因此我需要错误消息中提到的每个差异。我已经开始了这一工作,但是希望获得一些有关如何捕获确切差异的指导。

谢谢

SELECT      name, 
        object_id   
INTO        #sysTbl
FROM        sys.tables
ORDER BY    name

SELECT      t.name AS 't_name', 
            cols.name AS 'c_name', 
            cols.user_type_id,
            typ.name as user_type_name,
            cols.max_length,
            cols.is_nullable
INTO        #sysCols
FROM        #sysTbl t
INNER JOIN  sys.all_columns AS cols ON t.object_id = cols.object_id
INNER JOIN  sys.types AS typ ON cols.user_type_id = typ.user_type_id

    SELECT  *
    INTO #errorTbl
    FROM 
    (
        SELECT  *
        FROM    dbo.[metaDataFile] 
        EXCEPT
        SELECT  *
        FROM    #sysCols
        UNION 
        SELECT  *
        FROM    #sysCols
        EXCEPT
        SELECT *
        FROM    dbo.[metaDataFile] 
    ) err

    DECLARE @errStr VARCHAR(MAX) 
    --build Error Message
    select @errStr = 'There is a mismatch on' + stuff((select ',' + ' table ' + t_name +' on column ' + c_name 
                FROM #errorTbl t2
                FOR XML PATH('')),1,1,'')

        IF EXISTS 
        (
            SELECT *
            FROM #errorTbl
        )
                RAISERROR (@errStr, 
                   16, -- Severity,  
                   1, -- State,  
                   N'Failure due to data mismatch'); 
        ELSE
            BEGIN
                PRINT 'Success - Data Matches'
            END

1 个答案:

答案 0 :(得分:0)

这可能被过度简化,但是这是使用信息模式的努力:

select *
from INFORMATION_SCHEMA.COLUMNS
where TABLE_CATALOG='DB NAME'
    and TABLE_NAME='TABLE NAME'

这将提供有关表的所有列信息和元数据。

现在为这两者尝试一下:

select 
    t1.COLUMN_NAME
    ,DataType_NoMatch = case when t1.DATA_TYPE <> t2.DATA_TYPE then 1 else 0 end
from
    (
    select *
    from INFORMATION_SCHEMA.COLUMNS
    where TABLE_CATALOG='DB NAME'
        and TABLE_SCHEMA = 'SCHEMA'
        and TABLE_NAME='TABLE'
        ) t1
    join
    (
    select *
    from INFORMATION_SCHEMA.COLUMNS
    where TABLE_CATALOG='DBANME'
        and TABLE_SCHEMA = 'SCHEMA'
        and TABLE_NAME='TABLE2'
    ) t2 on t1.COLUMN_NAME=t2.COLUMN_NAME

,然后逐步处理要比较的属性。我给你举了一个数据类型的例子。

根据交叉应用评论添加:

select 
    t1.COLUMN_NAME
    ,ca.*
from
    (
    select *
    from INFORMATION_SCHEMA.COLUMNS
    where TABLE_CATALOG='DB NAME'
        and TABLE_SCHEMA = 'dbo'
        and TABLE_NAME='DimOrganization'
        ) t1
    join
    (
    select *
    from INFORMATION_SCHEMA.COLUMNS
    where TABLE_CATALOG='DB NAME'
        and TABLE_SCHEMA = 'bak'
        and TABLE_NAME='DimOrganization'
    ) t2 on t1.COLUMN_NAME=t2.COLUMN_NAME
cross apply
    (select Metadata = 'DataType' ,TestPassFail = case when t1.DATA_TYPE <> t2.DATA_TYPE then 1 else 0 end 
     union all
     select [Column] = 'CharMaxLen' ,TestPassFail = case when t1.CHARACTER_MAXIMUM_LENGTH <> t2.CHARACTER_MAXIMUM_LENGTH then 1 else 0 end
     ) ca

where ca.TestPassFail=1