使用信息模式检查两个表之间的元数据

时间:2015-12-14 05:35:07

标签: sql-server tsql

如何使用information_schema比较两个表之间的列名,数据类型,数据类型长度。

1 个答案:

答案 0 :(得分:1)

在回答之前,我想告诉您stackoverflow是一个可以发布您被解决的问题的地方。因此,当您发布问题时,请发布到您工作的部分和您正在努力的部分。

为了实现这一点,您需要创建两个动态sql查询,以获取需要比较的源表和目标表中的列名,数据类型,数据类型长度。然后将它们插入两个临时表中,并运行一个select查询来比较它们。

@srvname1 VARCHAR(100)
    ,@srvname2 VARCHAR(100)
    ,@SourceDB SYSNAME
    ,@TargetDb SYSNAME

srvname1和srvname2属于您拥有表的服务器名称,SourceDB和TargetDB属于各种数据库。

以下是代码。

INSERT INTO #TABLIST_SOURCE (DATABASENAME
, TABLENAME
, COLUMNNAME
, DATATYPE
, NULLABLE)
EXEC (
'SELECT ''' + @SourceDB + ''', T.TABLE_NAME TABLENAME, 
             C.COLUMN_NAME COLUMNNAME,
             TY.name + case when TY.name IN (''char'',''varchar'',''nvarchar'') THEN    
                ''(''+CASE WHEN C.CHARACTER_MAXIMUM_LENGTH>0 THEN CAST(C.CHARACTER_MAXIMUM_LENGTH AS VARCHAR) ELSE ''max''END+'')''
                ELSE    
                    ''''
                END
                DATATYPE,
                CASE WHEN C.is_nullable=''NO'' THEN 
                    ''NOT NULL'' 
                    ELSE
                    ''NULL''
                END NULLABLE
                    FROM ' + @srvname1 + '.' + @SourceDB + '.INFORMATION_SCHEMA.TABLES T 
                        INNER JOIN  ' + @srvname1 + '.' + @SourceDB + '.INFORMATION_SCHEMA.COLUMNS C
                            ON T.TABLE_NAME=C.TABLE_NAME
                            and T.TABLE_CATALOG=C.TABLE_CATALOG
                            and T.TABLE_SCHEMA=C.TABLE_SCHEMA
                         INNER JOIN ' + @srvname1 + '.' + @SourceDB + '.sys.types TY
                        ON C.DATA_TYPE =TY.name     
                        ORDER BY TABLENAME, COLUMNNAME,C.ORDINAL_POSITION'
);

INSERT INTO #TABLIST_TARGET (DATABASENAME
, TABLENAME
, COLUMNNAME
, DATATYPE
, NULLABLE)
EXEC (
'SELECT ''' + @TargetDB + ''', T.TABLE_NAME TABLENAME, 
             C.COLUMN_NAME COLUMNNAME,
             TY.name + case when TY.name IN (''char'',''varchar'',''nvarchar'') THEN    
                ''(''+CASE WHEN C.CHARACTER_MAXIMUM_LENGTH>0 THEN CAST(C.CHARACTER_MAXIMUM_LENGTH AS VARCHAR) ELSE ''max''END+'')''
                ELSE    
                    ''''
                END
                DATATYPE,
                CASE WHEN C.is_nullable=''NO'' THEN 
                    ''NOT NULL'' 
                    ELSE
                    ''NULL''
                END NULLABLE
                    FROM ' + @srvname2 + '.' + @TargetDB + '.INFORMATION_SCHEMA.TABLES T 
                        INNER JOIN  ' + @srvname2 + '.' + @TargetDB + '.INFORMATION_SCHEMA.COLUMNS C
                            ON T.TABLE_NAME=C.TABLE_NAME
                            and T.TABLE_CATALOG=C.TABLE_CATALOG
                            and T.TABLE_SCHEMA=C.TABLE_SCHEMA
                         INNER JOIN ' + @srvname2 + '.' + @TargetDB + '.sys.types TY
                        ON C.DATA_TYPE =TY.name     
                        ORDER BY TABLENAME, COLUMNNAME,C.ORDINAL_POSITION'
);

上面创建了一个名为TABLIST_SOURCE和另一个TABLIST_TARGET的临时表,并将列名,数据类型,数据类型长度插入其中。

然后运行下面的代码,它将比较两个表并给你差异。

INSERT INTO #TAB_MATCH_RESULTS (SOURCE_SERVER
, TARGET_SERVER
, SOURCE_DATABASE
, TARGET_DATABASE
, SOURCE_TABLE
, TARGET_TABLE
, SOURCE_COLUMN
, TARGET_COLUMN
, SOURCE_DATATYPE
, TARGET_DATATYPE
, SOURCE_NULLABLE
, TARGET_NULLABLE
, REASON)
    (
    SELECT
        @srvname1 AS SOURCE_SERVER,
        @srvname2 AS TARGET_SERVER,
        @SourceDB AS SOURCE_DATABASE,
        @TargetDb AS TARGET_DATABASE,
        TS.TABLENAME,
        TT.TABLENAME,
        TS.COLUMNNAME,
        TT.COLUMNNAME,
        TS.DATATYPE,
        TT.DATATYPE,
        TS.NULLABLE,
        TT.NULLABLE,
        CASE
            WHEN (TS.TABLENAME <> TT.TABLENAME) THEN 'FAIL'
            WHEN (TS.COLUMNNAME <> TT.COLUMNNAME) THEN 'FAIL'
            WHEN (TS.DATATYPE <> TT.DATATYPE) THEN 'FAIL'
            WHEN (TS.NULLABLE <> TT.NULLABLE) THEN 'FAIL'
            ELSE 'PASS'
        END AS REASON
    FROM #TABLIST_SOURCE TS
    FULL JOIN #TABLIST_TARGET TT
        ON TS.TABLENAME = TT.TABLENAME
    WHERE TS.COLUMNNAME = TT.COLUMNNAME
    )

在上面我创建了另一个临时表来存储TABLIST_SOURCE和TABLIST_TARGET的比较细节。将所有这些代码放在一个脚本中,最后您可以对表TAB_MATCH_RESULTS运行查询并获取不匹配的详细信息。希望这会对你有所帮助。