如何使用information_schema比较两个表之间的列名,数据类型,数据类型长度。
答案 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运行查询并获取不匹配的详细信息。希望这会对你有所帮助。