如何比较两个数据库中所有表的所有列

时间:2016-11-15 07:20:30

标签: sql sql-server sql-server-2008 tsql

我有两个数据库。一个用于交易目的,另一个用于审计目的。数据库名称为CLX_DEVELOPMENTCLX_DEVELOPMENT_AUDIT。两个数据库都应具有相同数量的表和列。

我的要求是我必须检查CLX_DEVELOPMENT_AUDIT中是否缺少任何列。

2 个答案:

答案 0 :(得分:1)

这将返回一个数据库中不存在于另一个数据库的相应表中的列:

WITH DB1 AS (
    SELECT objects.name AS TBL, columns.name AS COL
    FROM       CLX_DEVELOPMENT.sys.objects 
    INNER JOIN CLX_DEVELOPMENT.sys.columns ON objects.object_id = columns.object_id
    WHERE objects.type = 'U' -- user table
), DB2 AS (
    SELECT objects.name AS TBL, columns.name AS COL
    FROM       CLX_DEVELOPMENT_AUDIT.sys.objects 
    INNER JOIN CLX_DEVELOPMENT_AUDIT.sys.columns ON objects.object_id = columns.object_id
    WHERE objects.type = 'U' -- user table
)
SELECT DB1.TBL, DB1.COL
FROM DB1
LEFT JOIN DB2 ON DB1.TBL = DB2.TBL and DB1.COL = DB2.COL
WHERE DB2.TBL IS NULL

生成两个数据库的 列diff 的更通用的解决方案如下:

WITH CTE AS (
    SELECT TABLE_NAME, COLUMN_NAME FROM Database1.INFORMATION_SCHEMA.COLUMNS
    UNION
    SELECT TABLE_NAME, COLUMN_NAME FROM Database2.INFORMATION_SCHEMA.COLUMNS
)
SELECT CTE.TABLE_NAME, CTE.COLUMN_NAME, CASE
    WHEN DB1.COLUMN_NAME IS NULL THEN 'DB2 Only'
    WHEN DB2.COLUMN_NAME IS NULL THEN 'DB1 Only'
    ELSE 'BOTH DB'
END AS [Present In]
FROM CTE
LEFT JOIN Database1.INFORMATION_SCHEMA.COLUMNS AS DB1 ON CTE.TABLE_NAME = DB1.TABLE_NAME AND CTE.COLUMN_NAME = DB1.COLUMN_NAME
LEFT JOIN Database2.INFORMATION_SCHEMA.COLUMNS AS DB2 ON CTE.TABLE_NAME = DB2.TABLE_NAME AND CTE.COLUMN_NAME = DB2.COLUMN_NAME
WHERE DB1.COLUMN_NAME IS NULL OR DB2.COLUMN_NAME IS NULL

答案 1 :(得分:0)

dataedo的一个很好的解决方案。链接如下:

https://dataedo.com/kb/query/sql-server/compare-tables-and-columns-in-two-databases

peradventure链接下面的脚本出现故障:

select isnull(db1.table_name, db2.table_name) as [table],
       isnull(db1.column_name, db2.column_name) as [column],
       db1.column_name as database1, 
       db2.column_name as database2
from
(select schema_name(tab.schema_id) + '.' + tab.name as table_name, 
       col.name as column_name
   from [dataedo_6.0].sys.tables as tab
        inner join [dataedo_6.0].sys.columns as col
            on tab.object_id = col.object_id) db1
full outer join
(select schema_name(tab.schema_id) + '.' + tab.name as table_name, 
       col.name as column_name
   from [dataedo_7.0].sys.tables as tab
        inner join [dataedo_7.0].sys.columns as col
            on tab.object_id = col.object_id) db2
on db1.table_name = db2.table_name
and db1.column_name = db2.column_name
where (db1.column_name is null or db2.column_name is null)
order by 1, 2, 3

说明

用要比较的两个数据库(在SQL Server实例上)的名称替换[dataedo_6.0]和[dataedo_7.0]。

您还可以使用Visual Studio中提供的SQL模式比较工具。