2009-09-24 182 views
2

我有兩個相同數據庫的實例。第一個數據庫表示今天的數據,即6個月前的第二個數據。我需要爲特定表中的條目子集找出差異。比較兩個T-SQL表的差異

對於具有兩個表中的id的條目,我想找到一種方法來查看只有不相同的行。

任何想法?

謝謝

+0

什麼是關閉請求? –

回答

3
SELECT t1.id 
FROM table1 t1 
INNER JOIN table2 t2 ON t1.id = t2.id 
WHERE ISNULL(t1.field1,'') <> ISNULL(t2.field1,'') 
     OR ISNULL(t1.field2,'') <> ISNULL(t2.field2,'') 
     OR ... 

以生產長WHERE部分你可以使用這個功能:

CREATE PROCEDURE compareTables 
    @db1 NVARCHAR(100), 
    @table1 NVARCHAR(100), 
    @db2 NVARCHAR(100), 
    @table2 NVARCHAR(100) 
AS 
BEGIN 
    SET NOCOUNT ON; 
    DECLARE @where NVARCHAR(MAX) 
    DECLARE @cmd NVARCHAR(MAX) 

    SET @where = '' 

    SELECT @where = @where + 'ISNULL(t1.' + name + ','''') <> ISNULL(t2.' + name + ','''') OR ' 
    FROM sys.columns WHERE object_id = OBJECT_ID(@table1) 

    SET @where = SUBSTRING(@where,1,LEN(@where)-3) 

    SET @cmd = 'SELECT t1.id FROM ' + @db1 + '.' + @table1 + ' t1 ' 
    SET @cmd = @cmd + 'INNER JOIN ' + @db2 + '.' + @table2 + ' t2 ON t1.id = t2.id ' 
    SET @cmd = @cmd + 'WHERE ' + @where 

    EXEC sp_executesql @cmd 
END 
GO 

用法示例:

EXEC compareTables 'db1_name','dbo.table1','db2_name','dbo.table1' 

記得把架構的表名。

+0

是的,我擔心你會這麼說。 –

+0

不要忘記測試NULL – cortijon

+0

不好?更多要求?只要說,任何事情都可以在這裏完成;-) –

2

您可以使用SQL Server 2005及更高版本附帶的TableDiff.exe實用程序。

您可以read more here

+0

這是一個令人印象深刻的工具。然而,我希望能夠在T-SQL代碼中完成某些工作。 –

2

爲SQL Server 2005和最多嘗試是這樣的:

declare @CurrentTable table (pk int, valuedata varchar(5)) 
declare @oldtable table (pk int, valuedata varchar(5)) 

insert into @CurrentTable values (1,'aa') 
insert into @CurrentTable values(2,'bb') 
insert into @CurrentTable values(3,'cc') 
insert into @CurrentTable values(4,'dd') 
insert into @CurrentTable values(5,'ee') 

insert into @oldtable values(1,'aa') 
insert into @oldtable values(1,'bb') 
insert into @oldtable values(3,'zz') 
insert into @oldtable values(7,'aa') 
insert into @oldtable values(8,'qq') 

select pk,valuedata from @CurrentTable 
except 
select pk,valuedata from @oldtable 

輸出

pk   valuedata 
----------- --------- 
2   bb 
3   cc 
4   dd 
5   ee 

(4 row(s) affected) 

如果SQL Server 2000或以上的嘗試是這樣的:

SELECT 
    c.* 
    FROM YourTableCurrent    c 
     LEFT OUTER JOIN YourTableOld o ON c.id=o.id 
    WHERE ISNULL(c.IntCol,-2147483648)!=ISNULL(o.IntCol,-2147483648) 
     OR ISNULL(c.varcharCol,'||null||')!=ISNULL(o.varcharCol,'||null||') 
     OR ISNULL(c.DatetimeCol,'01/01/1753')!=ISNULL(o.DatetimeCol,'01/01/1753') 
     .... 
UNION 
SELECT 
    o.* 
    FROM YourTableOld      o 
     LEFT OUTER JOIN YourTableCurrent c ON c.id=o.id 
    WHERE c.id IS NULL 
     .... 
3

從你文本,我想你說有一個ID可以用於匹配行。

SELECT t1.*, t2.* 
FROM table1 t1 JOIN table2 t2 ON t1.id=t2.id 
WHERE BINARY_CHECKSUM(t1.*) <> BINARY_CHECKSUM(t2.*) 

未經測試,但應該有效。

+0

BINARY_CHECKSUM不允許所有字段使用星號「*」符號。在2008R2中,我收到「*'附近的語法錯誤'*'」[星號]。如果它有效的話,這將是一個非常好的比較。 –

+0

http://technet.microsoft.com/en-us/library/ms173784(v=sql.105).aspx表示它在2008R2中受支持。查詢可能還有其他問題嗎? –

+0

你是對的:允許使用星號_is_,但表名顯然不允許。我猜測帶有(星號)的BINARY_CHECKSUM會爲所有的字段生成一個校驗和,即對於已經組合的連接表。看到http://stackoverflow.com/questions/9038338/using-binary-checksum-with-multiple-tables –

0

只要你知道,有一個了不起的第三方工具,你可以買到這樣的事情做SQL Server數據庫稱爲SQL數據比較這種事情。它由紅門出售。 http://www.red-gate.com/products/SQL_Data_Compare/index.htm?gclid=CKPp-6-Bi50CFQRM5QodtWGl8g

有免費試用。但值得花這筆錢是值得的。

+1

這是公平的補充說,有一些數據比較工具在那裏...(紅門的不是我的選擇)。這是幾年前更新的列表:http://www.mssqltips.com/sqlservertip/1069/sql-server-comparison-tools/ –

1

晚了一點,但:

SELECT * 
from Table1 
except select * 
from Table2 

將列出在表1中不存在表2中的所有行,

SELECT * 
from Table2 
except select * 
from Table1 

將顯示所有在表2中沒有的表1和

SELECT * 
from Table1 
intersect select * 
from Table2 

將顯示兩個表中相同的所有行。如果已知任何列在不同表之間有所不同,請僅指定需要比較的那些列。