我正在尝试编写一些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
答案 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