Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用SQLServer2008比较不同数据库中两个表之间的数据?_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

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

如何使用SQLServer2008比较不同数据库中两个表之间的数据?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,在SQLServer2008中,我有两个数据库,分别命名为DB1和DB2。这两个数据库具有相同的表和相同的表数据。但是,我想检查这些表中的数据之间是否存在任何差异 有人能帮我写一个剧本吗 我用Checksum*函数做了类似的事情 在essance中,它对所有列数据创建一个行级校验和,然后您可以将每个表的每一行的校验和相互比较,使用左联接来查找不同的行 希望这是有意义的 最好举个例子 select * from ( select checksum(*) as chk, userid as k f

在SQLServer2008中,我有两个数据库,分别命名为DB1和DB2。这两个数据库具有相同的表和相同的表数据。但是,我想检查这些表中的数据之间是否存在任何差异


有人能帮我写一个剧本吗

我用Checksum*函数做了类似的事情

在essance中,它对所有列数据创建一个行级校验和,然后您可以将每个表的每一行的校验和相互比较,使用左联接来查找不同的行

希望这是有意义的

最好举个例子

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 

Matt建议的校验和可能是比较列的更好方法,而不是比较每一列。如果数据库位于同一服务器中,请在访问位于不同数据库中的表时使用[DatabaseName].[Owner].[TableName]格式

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

如果数据库位于不同的服务器上,请查看

测试代码:

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
注意:在开发优化的解决方案或重构时,比较大的表可能需要很长时间,这将给出与REFERERCE相同的结果-最好先检查kc简单参数:如

select count(t.*) from (
   select count(*) c0, SUM(BINARY_CHECKSUM(*)%1000000) c1 FROM T_REF_TABLE 
   -- select 12345 c0, -214365454 c1 -- constant values FROM T_REF_TABLE 
   except 
   select count(*) , SUM(BINARY_CHECKSUM(*)%1000000) FROM T_WORK_COPY 
) t
当这个值为空时,您可能可以控制事情,并且可能您可以在失败时进行修改。您将看到从T_REF到isert的常量值,以便为下次检查节省更多时间

非T-SQL的另一个解决方案:您可以使用实用程序。 例如,如果要比较来自两个不同服务器ROBUH01和ROBUH02的两个本地化表,可以使用以下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.
------------------------------------------------------------------------

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

原因–这些工具节省了大量时间,并使流程不那么容易出错

我使用了ApexSQL Diff和Data Diff,但marc_和Marina Nastenko已经指出,使用其他工具不会出错

如果您完全确定只需要比较一次表,那么SQL是可以的,但是如果您需要不时地使用它,那么最好使用一些第三方工具

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

我希望新读者会发现这很有用,尽管这是一个很晚的答案…

比较SQL数据库中的两个数据库。尝试此查询,它可能会有所帮助


如果两个数据库位于同一服务器上。您可以使用以下查询来检查类似的表:

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'
EXEC master.dbo.CompareDatabases 'DB1', 'DB2'
如果要比较两个数据库,请使用“CompareDatabases”过程。例如:

EXEC master.dbo.CompareTables 'DB1', 'dbo', 'table1', 'DB2', 'dbo', 'table2'
EXEC master.dbo.CompareDatabases 'DB1', 'DB2'
注意:-我试图使程序安全,但无论如何,这些程序仅用于测试和调试。 -如果您想要一个完整的比较解决方案,请使用第三方,如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


找个好工具帮你做那件事!对于结构比较,比较表的数据/内容。是比较数据库数据和模式的另一个非常有用的工具。plz让我明白,除了关键字和union all是什么?@JagadisSahu except从左查询返回右查询中找不到的任何不同值@JagadisSahu UNION指定将多个结果集合并并作为单个结果集返回。。当您处于无法安装redgate但可以访问这两个数据库的环境中时,这是一种非常好的模式!谢谢!您可以编写一个t-sql脚本,以编程方式创建所有这些查询。所有元数据都在系统表和视图中查看此问题以获取主键这不起作用,因为没有定义UserAccounts。这与@Mikael Eriksson接受的答案有什么不同?看起来您重新使用了接受的答案,并将其放在CREATE PROC语句中。您的评论与此无关。有时,您需要以编程方式运行比较。
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