wake-up-neo.net

Wie kann ich Daten zwischen zwei Tabellen in verschiedenen Datenbanken mit SQL Server 2008 vergleichen?

Ich habe zwei Datenbanken, DB1 und DB2 in SQL Server 2008. Diese beiden Datenbanken haben dieselben Tabellen und dieselben Tabellendaten. Ich möchte jedoch prüfen, ob Unterschiede zwischen den Daten in diesen Tabellen bestehen. 

Könnte mir jemand mit einem Skript dafür helfen? 

38
Jagadis Sahu
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

Testcode:

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

Ergebnis:

ID
-----------
1
3
25
Mikael Eriksson

Ich würde wirklich vorschlagen, dass Leute, die dieses Problem haben, ein Datenbankvergleichstool von Drittanbietern suchen. 

Grund - diese Tools sparen viel Zeit und machen den Prozess weniger fehleranfällig. 

Ich habe Vergleichstools verwendet von ApexSQL (Diff und Data Diff), aber mit den anderen Tools, die bereits erwähnt wurden, können marc_s und Marina Nastenko nichts falsch machen.

Wenn Sie absolut sicher sind, dass Sie nur einmal Tabellen vergleichen, ist SQL in Ordnung, wenn Sie dies jedoch gelegentlich benötigen, sind Sie mit Drittanbieter-Tools besser beraten.

Wenn Sie kein Budget haben, um es zu kaufen, verwenden Sie es einfach im Testmodus, um die Arbeit zu erledigen.

Ich hoffe, dass neue Leser das nützlich finden werden, auch wenn es eine späte Antwort ist…

24
JdMR

Ich habe solche Dinge mit der Checksum (*) - Funktion gemacht

Im Wesentlichen erstellt es eine Prüfsumme auf Zeilenebene für alle Spaltendaten. Sie können dann die Prüfsumme jeder Zeile für jede Tabelle miteinander vergleichen, einen Link nach links verwenden, um nach anderen Zeilen zu suchen.

Hoffe das hat Sinn gemacht ...

Besser mit einem Beispiel ....

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 
7
Matt

Vergleichen der zwei Datenbanken in der SQL-Datenbank. Versuchen Sie diese Abfrage, es kann helfen.

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]
4
edward
select * from DB1.dbo.Table a inner join DB2.dbo.Table b on b.PrimKey = a.PrimKey 
where a.FirstColumn <> b.FirstColumn ...

Die von Matt empfohlene Prüfsumme ist wahrscheinlich eine bessere Methode zum Vergleich von Spalten als für jede Spalte

3
evpo

Wenn sich die Datenbank auf demselben Server befindet, verwenden Sie das Format [DatabaseName].[Owner].[TableName] beim Zugriff auf eine Tabelle, die sich in einer anderen Datenbank befindet.

ZB: [DB1].[dbo].[TableName]

Wenn Datenbanken auf verschiedenen Servern auf Verbindungsserver (SQL Server-Datenbankmodul) suchen - /

2
CharithJ

Eine andere Lösung (nicht T-SQL): Sie können das Dienstprogramm tablediff verwenden. Wenn Sie beispielsweise zwei Tabellen (Localitate) von zwei verschiedenen Servern (ROBUH01 und ROBUH02) vergleichen möchten, können Sie diesen Shell-Befehl verwenden:

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

Ergebnisse:

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.
------------------------------------------------------------------------
1
Bogdan Sahlean

Um zwei Datenbanken zu vergleichen, habe ich die Prozeduren unten geschrieben. Wenn Sie zwei Tabellen vergleichen möchten, können Sie die Prozedur 'CompareTables' verwenden. Beispiel:

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

Wenn Sie zwei Datenbanken vergleichen möchten, verwenden Sie die Prozedur 'CompareDatabases'. Beispiel:

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

Hinweis: - Ich habe versucht, die Prozeduren sicherer zu machen, aber diese Prozeduren sind sowieso nur zum Testen und Debuggen gedacht.

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 [email protected])
        return 0
    if not exists(SELECT name FROM sys.databases WHERE [email protected])
        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 [email protected]_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 [email protected]_SCHEMA AND [email protected]_NAME)
        RETURN 1

    RETURN 0
END

GO
0
MOULOU

Wenn beide Datenbanken auf demselben Server liegen. Sie können ähnliche Tabellen mithilfe der folgenden Abfrage prüfen:

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     

Durch Auflisten einer ähnlichen Tabelle können Sie das Spaltenschema mithilfe der sys.columns-Ansicht vergleichen.

Hoffe das hilft dir.

0
user3209145