如何使用Sql Server 2008比较不同数据库中两个表之间的数据?

我有两个数据库,在Sql server 2008中命名为DB1和DB2。这两个数据库也有相同的表和相同的表数据。 但是,我想检查这些表中的数据是否有差异。

任何人都可以帮我一个脚本吗?

我真的build议遇到这个问题的人去找一个第三方的数据库比较工具。

理由 – 这些工具可以节省大量时间,并且减less错误的发生。

我已经使用了ApexSQL(Diff和Data Diff)的比较工具 ,但是你不能用其他工具marc_s和Marina Nastenko已经指出的错误。

如果你确定你只是要比较一次表,那么SQL是好的,但是如果你需要这个,你可以使用一些第三方工具更好。

如果你没有预算来购买它,那么只需在试用模式下使用它来完成工作。

我希望新读者会发现这个有用的,即使这是一个迟到的答案…

select * from ( select * from DB1.dbo.Table except select * from DB2.dbo.Table ) as T union all select * from ( select * from DB2.dbo.Table except select * from DB1.dbo.Table ) as T 

testing代码:

 declare @T1 table (ID int) declare @T2 table (ID int) insert into @T1 values(1),(2) insert into @T2 values(2),(3) select * from ( select * from @T1 except select * from @T2 ) as T union all select * from ( select * from @T2 except select * from @T1 ) as T 

结果:

 ID ----------- 1 3 

我用Checksum(*)函数做了这样的事情

在论文中,它将在所有列数据上创build一个行级校验和,然后可以将每个表的每一行的校验和相互比较,使用左连接来查找不同的行。

希望这是有道理的…

更好的例子….

 select * from ( select checksum(*) as chk, userid as k from UserAccounts) as t1 left join ( select checksum(*) as chk, userid as k from UserAccounts) as t2 on t1.k = t2.k where t1.chk <> t2.chk 

比较SQL数据库中的两个数据库。 试试这个查询可能有帮助。

 SELECT T.[name] AS [table_name], AC.[name] AS [column_name], TY.[name] AS system_data_type FROM [***Database Name 1***].sys.[tables] AS T INNER JOIN [***Database Name 1***].sys.[all_columns] AC ON T.[object_id] = AC.[object_id] INNER JOIN [***Database Name 1***].sys.[types] TY ON AC.[system_type_id] = TY.[system_type_id] EXCEPT SELECT T.[name] AS [table_name], AC.[name] AS [column_name], TY.[name] AS system_data_type FROM ***Database Name 2***.sys.[tables] AS T INNER JOIN ***Database Name 2***.sys.[all_columns] AC ON T.[object_id] = AC.[object_id] INNER JOIN ***Database Name 2***.sys.[types] TY ON AC.[system_type_id] = TY.[system_type_id] 
 select * from DB1.dbo.Table a inner join DB2.dbo.Table b on b.PrimKey = a.PrimKey where a.FirstColumn <> b.FirstColumn ... 

马特推荐的校验和可能是比较列而不是比较每列的更好方法

如果数据库在同一台服务器上,则在访问驻留在不同数据库中的表时使用[DatabaseName].[Owner].[TableName]格式。

例如: [DB1].[dbo].[TableName]

如果不同服务器上的数据库在创build链接服务器(SQL Server数据库引擎)

另一个解决scheme(非T-SQL ):你可以使用tablediff工具。 例如,如果要比较来自两个不同服务器(ROBUH01和ROBUH02)的两个表( Localitate ),可以使用以下shell命令:

 C:\Program Files\Microsoft SQL Server\100\COM>tablediff -sourceserver ROBUH01 -s ourcedatabase SIM01 -sourceschema dbo -sourcetable Localitate -destinationserver ROBUH02 -destinationschema dbo -destinationdatabase SIM02 -destinationtable Lo calitate 

结果:

 Microsoft (R) SQL Server Replication Diff Tool Copyright (c) 2008 Microsoft Corporation User-specified agent parameter values: -sourceserver ROBUH01 -sourcedatabase SIM01 -sourceschema dbo -sourcetable Localitate -destinationserver ROBUH02 -destinationschema dbo -destinationdatabase SIM02 -destinationtable Localitate Table [SIM01].[dbo].[Localitate] on ROBUH01 and Table [SIM02].[dbo].[Localitate ] on ROBUH02 have 10 differences. Err Id Dest. Only 21433 Dest. Only 21434 Dest. Only 21435 Dest. Only 21436 Dest. Only 21437 Dest. Only 21438 Dest. Only 21439 Dest. Only 21441 Dest. Only 21442 Dest. Only 21443 The requested operation took 9,9472657 seconds. ------------------------------------------------------------------------ 

如果两个数据库在同一台服务器 您可以使用以下查询来检查相似的表格:

 select fdb.name, sdb.name from FIRSTDBNAME.sys.tables fdb join SECONDDBNAME.sys.tables sdb on fdb.name = sdb.name -- compare same name tables order by 1 

通过列出类似的表,您可以使用sys.columns视图比较列架构。

希望这可以帮助你。

为了比较两个数据库,我写了下面的程序。 如果你想比较两个表,你可以使用程序'CompareTables'。 例如:

 EXEC master.dbo.CompareTables 'DB1', 'dbo', 'table1', 'DB2', 'dbo', 'table2' 

如果要比较两个数据库,请使用“CompareDatabases”过程。 例如:

 EXEC master.dbo.CompareDatabases 'DB1', 'DB2' 

注: – 我试图使程序安全,但无论如何,这些程序只用于testing和debugging。 – 如果你想要一个比较完整的解决scheme使用第三方(Visual Studio,…)

 USE [master] GO create proc [dbo].[CompareDatabases] @FirstDatabaseName nvarchar(50), @SecondDatabaseName nvarchar(50) as begin -- Check that databases exist if not exists(SELECT name FROM sys.databases WHERE name=@FirstDatabaseName) return 0 if not exists(SELECT name FROM sys.databases WHERE name=@SecondDatabaseName) return 0 declare @result table (TABLE_NAME nvarchar(256)) SET NOCOUNT ON insert into @result EXEC('(Select distinct TABLE_NAME from ' + @FirstDatabaseName + '.INFORMATION_SCHEMA.COLUMNS ' +'Where TABLE_SCHEMA=''dbo'')' + 'intersect' + '(Select distinct TABLE_NAME from ' + @SecondDatabaseName + '.INFORMATION_SCHEMA.COLUMNS ' +'Where TABLE_SCHEMA=''dbo'')') DECLARE @TABLE_NAME nvarchar(256) DECLARE curseur CURSOR FOR SELECT TABLE_NAME FROM @result OPEN curseur FETCH curseur INTO @TABLE_NAME WHILE @@FETCH_STATUS = 0 BEGIN print 'TABLE : ' + @TABLE_NAME EXEC master.dbo.CompareTables @FirstDatabaseName, 'dbo', @TABLE_NAME, @SecondDatabaseName, 'dbo', @TABLE_NAME FETCH curseur INTO @TABLE_NAME END CLOSE curseur DEALLOCATE curseur SET NOCOUNT OFF end GO 

 USE [master] GO CREATE PROC [dbo].[CompareTables] @FirstTABLE_CATALOG nvarchar(256), @FirstTABLE_SCHEMA nvarchar(256), @FirstTABLE_NAME nvarchar(256), @SecondTABLE_CATALOG nvarchar(256), @SecondTABLE_SCHEMA nvarchar(256), @SecondTABLE_NAME nvarchar(256) AS BEGIN -- Verify if first table exist DECLARE @table1 nvarchar(256) = @FirstTABLE_CATALOG + '.' + @FirstTABLE_SCHEMA + '.' + @FirstTABLE_NAME DECLARE @return_status int EXEC @return_status = master.dbo.TableExist @FirstTABLE_CATALOG, @FirstTABLE_SCHEMA, @FirstTABLE_NAME IF @return_status = 0 BEGIN PRINT @table1 + ' : Table Not FOUND' RETURN 0 END -- Verify if second table exist DECLARE @table2 nvarchar(256) = @SecondTABLE_CATALOG + '.' + @SecondTABLE_SCHEMA + '.' + @SecondTABLE_NAME EXEC @return_status = master.dbo.TableExist @SecondTABLE_CATALOG, @SecondTABLE_SCHEMA, @SecondTABLE_NAME IF @return_status = 0 BEGIN PRINT @table2 + ' : Table Not FOUND' RETURN 0 END -- Compare the two tables DECLARE @sql AS NVARCHAR(MAX) SELECT @sql = '(' + '(SELECT ''' + @table1 + ''' as _Table, * FROM ' + @FirstTABLE_CATALOG + '.' + @FirstTABLE_SCHEMA + '.' + @FirstTABLE_NAME + ')' + 'EXCEPT' + '(SELECT ''' + @table1 + ''' as _Table, * FROM ' + @SecondTABLE_CATALOG + '.' + @SecondTABLE_SCHEMA + '.' + @SecondTABLE_NAME + ')' + ')' + 'UNION' + '(' + '(SELECT ''' + @table2 + ''' as _Table, * FROM ' + @SecondTABLE_CATALOG + '.' + @SecondTABLE_SCHEMA + '.' + @SecondTABLE_NAME + ')' + 'EXCEPT' + '(SELECT ''' + @table2 + ''' as _Table, * FROM ' + @FirstTABLE_CATALOG + '.' + @FirstTABLE_SCHEMA + '.' + @FirstTABLE_NAME + ')' + ')' DECLARE @wrapper AS NVARCHAR(MAX) = 'if exists (' + @sql + ')' + char(10) + ' (' + @sql + ')ORDER BY 2' Exec(@wrapper) END GO 

 USE [master] GO CREATE PROC [dbo].[TableExist] @TABLE_CATALOG nvarchar(256), @TABLE_SCHEMA nvarchar(256), @TABLE_NAME nvarchar(256) AS BEGIN IF NOT EXISTS(SELECT name FROM sys.databases WHERE name=@TABLE_CATALOG) RETURN 0 declare @result table (TABLE_SCHEMA nvarchar(256), TABLE_NAME nvarchar(256)) SET NOCOUNT ON insert into @result EXEC('Select TABLE_SCHEMA, TABLE_NAME from ' + @TABLE_CATALOG + '.INFORMATION_SCHEMA.COLUMNS') SET NOCOUNT OFF IF EXISTS(SELECT TABLE_SCHEMA, TABLE_NAME FROM @result WHERE TABLE_SCHEMA=@TABLE_SCHEMA AND TABLE_NAME=@TABLE_NAME) RETURN 1 RETURN 0 END GO