2011-09-30 28 views
37

Tengo dos base de datos de, llamada DB1 y DB2 en el servidor SQL 2008. Estos dos bases de datos de las tablas tienen los mismos y los mismos datos de la tabla también. Sin embargo, quiero verificar si hay alguna diferencia entre los datos en estas tablas.Cómo comparar los datos entre los dos tipos de tabla en diferentes bases de datos utilizando SQL Server 2008?

Podría alguien ayudarme con una secuencia de comandos para esto?

+5

¡Obtenga una buena herramienta para hacer ese trabajo por usted! [Red-Gate SQL Compare] (http://www.red-gate.com/products/sql-development/sql-compare/) para la comparación estructural, [Red-Gate SQL Data Compare] (http: // www. .red-gate.com/products/sql-development/sql-data-compare /) para comparar los datos/contenidos de sus tablas. –

+0

[DB Solo] (http://www.dbsolo.com/) es otra herramienta muy útil para comparar datos DB así como esquemas. –

Respuesta

5

i'v hecho cosas como esta usando la función de suma de comprobación (*)

En essance crea una suma de comprobación de nivel de fila en todos los datos de las columnas, que podría entonces comparar la suma de comprobación de cada fila para cada tabla para cada uno otra, use una combinación a la izquierda, para encontrar filas que son diferentes.

esperanza que tenía sentido ...

mejor con un ejemplo ....

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 
+1

Esto no funciona ya que 'UserAccounts' no está definido. – MoonKnight

+11

¿Qué quieres decir? Su psuedocode ... – Matt

3
select * from DB1.dbo.Table a inner join DB2.dbo.Table b on b.PrimKey = a.PrimKey 
where a.FirstColumn <> b.FirstColumn ... 

suma de comprobación que Matt recomendado es probablemente un mejor enfoque para comparar columnas en lugar de comparar cada columna

+0

Entonces, para cada tabla necesitamos escribir la nueva consulta, ¿verdad? –

+0

puede escribir un script t-sql que crea todas esas consultas programáticamente. Todos los metadatos están en tablas del sistema y vistas – evpo

+0

vea esta pregunta para obtener las claves principales http://stackoverflow.com/questions/222217/how-do-i-determine-if-a-column-is-in-the-primary -key-of-its-table-sql-server – evpo

2

Si la base de datos se encuentran en el mismo servidor utiliza [DatabaseName].[Owner].[TableName] formato cuando se accede a una tabla que reside en una base de datos diferente.

Ej: [DB1].[dbo].[TableName]

Si las bases de datos en un aspecto diferente del servidor en el Creating Linked Servers (SQL Server Database Engine)

23
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 

Código de ensayo:

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 

Resultado:

ID 
----------- 
1 
3 
+0

por favor hagame entender, ¿qué es la palabra clave "except" y "union all"? –

+2

@JagadisSahu "EXCEPTO devuelve valores distintos de la consulta de la izquierda que no se encuentran también en la consulta correcta". http://msdn.microsoft.com/en-us/library/ms188055.aspx –

+2

@JagadisSahu "UNION Especifica que los conjuntos de resultados múltiples se combinen y devuelvan como un conjunto de resultados único". http://msdn.microsoft.com/en-us/library/ms180026.aspx –

1

Otra solución (no T-SQL): se puede usar tablediff utilidad. Por ejemplo, si se desea comparar dos tablas (Localitate) de dos servidores diferentes (ROBUH01 & ROBUH02), puede utilizar este comando 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 

Resultados:

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. 
------------------------------------------------------------------------ 
23

yo sugiero que las personas que encuentran este problema van a buscar una herramienta de comparación de bases de datos de terceros.

Motivo: estas herramientas ahorran mucho tiempo y hacen que el proceso sea menos propenso a errores.

He usado comparison tools de ApexSQL (Diff y Data Diff) pero no puedes equivocarte con otras herramientas que marc_s y Marina Nastenko ya han señalado.

Si está completamente seguro de que sólo se va a comparar las tablas a continuación, una vez que SQL está bien, pero si usted va a necesitar esto de vez en cuando va a ser mejor con un poco de herramienta tercera parte.

Si usted no tiene presupuesto para comprar, entonces sólo tiene que utilizar en el modo de prueba para hacer el trabajo.

espero nuevos lectores encontrarán esto útil a pesar de que es una respuesta tardía ...

4

Comparando las dos bases de datos en la base de datos SQL. Prueba esta consulta, puede ser útil.

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] 
0

Si ambas bases de datos están en el mismo servidor. Puede comprobar tablas similares mediante el uso siguiente consulta:

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  

Al enumerar a cabo tabla similar se puede comparar esquema de columnas usando sys.columns vista.

Espero que esto te ayude.

0

Para comparar dos bases de datos, he escrito los procedimientos a continuación. Si quiere comparar dos tablas, puede usar el procedimiento 'CompareTables'. Ejemplo:

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

Si desea comparar dos bases de datos, utilice el procedimiento 'CompareDatabases'. Ejemplo:

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

Nota: - Traté de hacer los procedimientos de seguridad, pero de todos modos, esos procedimientos son sólo para pruebas y depuración. - Si desea una solución completa para la comparación usar terceros como (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 [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

¿Cómo es esto diferente a la respuesta aceptada de @Mikael Eriksson? Parece que reutilizó la respuesta aceptada y la puso en una instrucción 'CREATE PROC'. –

Cuestiones relacionadas