直接比较
虽然说是直接比较,你不可能一个表一个表的用肉眼对比,这里当然也是借助比较工具(Beyond Compare)啦。
第一步
选中正式数据库右键 => 任务 => 生成脚本,选择全部的表,高级里面选择“仅限架构”,生成保存到新建查询窗口。
这里是 SQL Server 数据库
测试库同样的操作。
第二步
打开Beyond Compare => 选择文本比较,把上面正式和测试环境中的两个查询分别复制粘贴到文本比较的左右两边,比较即可。
数据库中比较
按理说上面的方法已经够直观,快速的了,为啥还要多此一举?就是因为我没有正式和测试库的相关权限,我只有查询权限,我只能进行查询……(哭……)
好了,直接上代码,查询比较:
declare @TableName nvarchar(50)='******';
WITH CTE_Test AS(
SELECT
A.name, A.is_nullable, A.max_length, ColumnType=B.name--, ColumnDescription=C.value
FROM
test.sys.columns A JOIN
test.sys.types B ON A.user_type_id=B.user_type_id LEFT JOIN
test.sys.extended_properties C ON A.object_id=C.major_id AND A.column_id=C.minor_id
WHERE
A.object_id=OBJECT_ID(@TableName)
),CTE AS(
SELECT
A.name, A.is_nullable, A.max_length, ColumnType=B.name--, ColumnDescription=C.value
FROM
formal.sys.columns A JOIN
formal.sys.types B ON A.user_type_id=B.user_type_id LEFT JOIN
formal.sys.extended_properties C ON A.object_id=C.major_id AND A.column_id=C.minor_id
WHERE
A.object_id=(SELECT object_id FROM formal.sys.tables WHERE TYPE='U' AND name=@TableName)
),CTE_Merge AS(
SELECT
AName=A.name, AIsNull=A.is_nullable, AMaxLength=A.max_length, AType=A.ColumnType,
分隔='|||||',
BName=B.name, BIsNull=B.is_nullable, BMaxLength=B.max_length, BType=B.ColumnType
FROM
CTE A LEFT JOIN // 这里左连接,意思就是以左边库作为标准(这里左边是正式库,右边是测试库)
CTE_Test B on A.name=B.name
)
SELECT * FROM CTE_Merge
where AName!=BName or BName is null or AIsNull!=BIsNull or AMaxLength!=BMaxLength or AType!=BType
如图:
- 第一行 AIsNull=1,BIsNull=0 说明正式库该字段允许 null,二测试库不允许
- 第二行 BName 为 null,说明测试库没有 ZJType 的字段
上面需要一个表一个表的查询,还是显的麻烦,接下来我们继续修改,直接一个查询显示所有不一致的地方,直接上代码:
WITH CTE_Test AS(
SELECT
tableName=D.name, A.name, A.is_nullable, A.max_length, ColumnType=B.name--, ColumnDescription=C.value
FROM
test.sys.tables D JOIN -- 新加的连接表
test.sys.columns A ON D.object_id=A.object_id AND D.type='U' AND D.is_ms_shipped=0 JOIN -- 这里筛选了用户表
test.sys.types B ON A.user_type_id=B.user_type_id LEFT JOIN
test.sys.extended_properties C ON A.object_id=C.major_id AND A.column_id=C.minor_id
),CTE AS(
SELECT
tableName=D.name, A.name, A.is_nullable, A.max_length, ColumnType=B.name--, ColumnDescription=C.value
FROM
formal.sys.tables D JOIN -- 新加的连接表
formal.sys.columns A ON D.object_id=A.object_id AND D.type='U' AND D.is_ms_shipped=0 JOIN -- 这里筛选了用户表
formal.sys.types B ON A.user_type_id=B.user_type_id LEFT JOIN
formal.sys.extended_properties C ON A.object_id=C.major_id AND A.column_id=C.minor_id
),CTE_Merge AS(
SELECT
ATableName=A.tableName, AName=A.name, AIsNull=A.is_nullable, AMaxLength=A.max_length, AType=A.ColumnType,
分隔='|||||',
BTableName=B.tableName, BName=B.name, BIsNull=B.is_nullable, BMaxLength=B.max_length, BType=B.ColumnType
FROM
CTE A LEFT JOIN -- 这里左连接,意思就是以左边库作为标准(这里左边是正式库,右边是测试库)
CTE_Test B on A.name=B.name
)
SELECT * FROM CTE_Merge
WHERE
(ATableName=BTableName OR BTableName IS NULL) AND -- 新加的条件,注意这里是 AND
(
AName!=BName OR BName is null OR AIsNull!=BIsNull OR AMaxLength!=BMaxLength OR AType!=BType
)
ORDER BY ATableName
嗯……,看我图红长度应该能猜出来一共有四张表的字段不一致吧?