基于数据库字典或目录视图对数据库对象结构进行比较
2011-10-18 09:09
393 查看
基础知识
1、Oracle Dictionary Views
2、SQLServer目录视图
关于Oracle与SQL Server的不同或相同就不整理了,试着用两者完成相同的功能的同时自然就知道两者那些是一致的哪些地方是各自的。当然,要真是非常的了解Oracle与SQL深层次的不同,那么再回过头来看类似查询这样那样数据的工作就显得简单多了。
依据需求分析得出Oracle这块需要对表、视图、触发器、函数\过程、类型进行查询处理,包括知道
哪些对象在A用户下有而在B用户下却没了?
A用户下C表有一些字段而在B用户下C表却对不起来,也就是哪些丢了那些是多余的?
A用户下C表中哪些字段类型与B用户下C表中字段类型对不上?
用户下的过程\函数哪些是内容不一致的?
Oracle这块Oracle实现
Oracle实现时有个权限相关的问题,就是SYSTEM用户下的存储过程内部查个别ALL_**视图时存储过程下得不到数据的问题,这时需要用sys运行那个存储过程就可以了,大多数ALL_**视图在存储过程下访问也是正常的,但就有个别的不可以。。。
统计两用户下的表对象缺失情况
使用连接
使用子查询
统计两用户下的表的字段结构情况
这块用存储过程做也蛮方便的,但是后期还得时刻想着存储过程的移植等问题。使用存储过程就没有特殊处理long类型的问题。
这条SQL是有局限的,原因在于LONG类型的列内容比较问题,这块的处理也有很多方案基本思路就是把LONG类型的列转成VARCHAR2或CLOB类型的数据存放到个临时表里然后通过连接或子查询的方式都可以
1、使用临时表存储LONG类型的转换值
CREATE TABLE TMP_CV_LONG(TMP_CHAR VARCHAR(2000), TMP_CLOB CLOB)
INSERT INTO TMP_CV_LONG SELECT '', TO_LOB(DATA_DEFAULT) FROM ALL_TAB_COLS WHERE OWNER='ABC' AND DEFAULT_LENGTH<>0
UPDATE TMP_CV_LONG SET TMP_CHAR = TO_CHAR(TMP_CLOB)
2、在JDBC那块做处理,当默认值长度不等的情况下取LONG类型的数据然后处理(这样做就特别累了)
其它情况
其它情况包括函数\过程内容比较,在Oracle中可以通过ALL_SOURCE视图查出来,具体的问题是怎么比的问题,那简单的A.CTX = B.CTX是不能满足要求的。这块可以看人家SVN或Beyond Compare那样的结果。
SQL Server这块
SQL Server这块数据字典信息相关资料直接通过SQL Server联机丛书的内容就够用了,因为Oracle与SQL Server在整个结构上是不一致的(具体要去baidu文库找Oracle与SQL Server深度对比,文章写的非常棒,边实践边看完它基本上对Oracle与SQL Server就大致有个数了),所以SQL Server下需要做另一套查询SQL。
统计两用户下的表对象缺失情况
统计两用户下的表的字段结构情况
其它情况
1、Oracle Dictionary Views
2、SQLServer目录视图
关于Oracle与SQL Server的不同或相同就不整理了,试着用两者完成相同的功能的同时自然就知道两者那些是一致的哪些地方是各自的。当然,要真是非常的了解Oracle与SQL深层次的不同,那么再回过头来看类似查询这样那样数据的工作就显得简单多了。
依据需求分析得出Oracle这块需要对表、视图、触发器、函数\过程、类型进行查询处理,包括知道
哪些对象在A用户下有而在B用户下却没了?
A用户下C表有一些字段而在B用户下C表却对不起来,也就是哪些丢了那些是多余的?
A用户下C表中哪些字段类型与B用户下C表中字段类型对不上?
用户下的过程\函数哪些是内容不一致的?
Oracle这块Oracle实现
Oracle实现时有个权限相关的问题,就是SYSTEM用户下的存储过程内部查个别ALL_**视图时存储过程下得不到数据的问题,这时需要用sys运行那个存储过程就可以了,大多数ALL_**视图在存储过程下访问也是正常的,但就有个别的不可以。。。
统计两用户下的表对象缺失情况
使用连接
SELECT (CASE WHEN A.A_TABLE_NAME IS NULL THEN B.B_TABLE_NAME ELSE A.A_TABLE_NAME END) AS TABLE_NAME, (CASE WHEN A.A_TABLE_NAME IS NULL THEN '1' WHEN B.B_TABLE_NAME IS NULL THEN '2' ELSE '-1' END) AS TYPE FROM ( SELECT OBJECT_NAME AS A_TABLE_NAME ,OBJECT_ID AS A_OBJECT_ID FROM ALL_OBJECTS WHERE OBJECT_TYPE = 'TABLE' AND OWNER='USER_A' ) A FULL JOIN ( SELECT OBJECT_NAME AS B_TABLE_NAME ,OBJECT_ID AS B_OBJECT_ID FROM ALL_OBJECTS WHERE OBJECT_TYPE = 'TABLE' AND OWNER='USER_B' ) B ON A.A_TABLE_NAME = B.B_TABLE_NAME WHERE A.A_TABLE_NAME IS NULL OR B.B_TABLE_NAME IS NULL
使用子查询
SELECT '1' TYPE, A.OBJECT_NAME AS TABLE_NAME FROM ALL_OBJECTS A WHERE OWNER='USER_A' AND OBJECT_TYPE='TABLE' AND NOT EXISTS( SELECT 1 FROM ALL_OBJECTS B WHERE B.OBJECT_NAME=A.OBJECT_NAME AND B.OWNER='USER_B') UNION ALL SELECT '2' TYPE, A.OBJECT_NAME AS TABLE_NAME FROM ALL_OBJECTS A WHERE OWNER='USER_B' AND OBJECT_TYPE='TABLE' AND NOT EXISTS( SELECT 1 FROM ALL_OBJECTS B WHERE B.OBJECT_NAME=A.OBJECT_NAME AND B.OWNER='USER_A')
统计两用户下的表的字段结构情况
这块用存储过程做也蛮方便的,但是后期还得时刻想着存储过程的移植等问题。使用存储过程就没有特殊处理long类型的问题。
SELECT * FROM ( SELECT A.TABLE_NAME,A.COLUMN_NAME, (CASE WHEN A.DATA_TYPE <> B.DATA_TYPE THEN A.DATA_TYPE || '!=' || B.DATA_TYPE ELSE NULL END) DATA_TYPE, (CASE WHEN A.DATA_LENGTH <> B.DATA_LENGTH THEN A.DATA_LENGTH || '!=' || B.DATA_LENGTH ELSE NULL END) DATA_LENGTH, (CASE WHEN A.DATA_PRECISION <> B.DATA_PRECISION THEN A.DATA_PRECISION || '!=' || B.DATA_PRECISION ELSE NULL END) DATA_PRECISION, (CASE WHEN A.DATA_SCALE <> B.DATA_SCALE THEN A.DATA_SCALE || '!=' || B.DATA_SCALE ELSE NULL END) DATA_SCALE, (CASE WHEN A.NULLABLE <> B.NULLABLE THEN A.NULLABLE || '!=' || B.NULLABLE ELSE NULL END) NULLABLE, (CASE WHEN A.DEFAULT_LENGTH <> B.DEFAULT_LENGTH THEN A.DEFAULT_LENGTH || '!=' || B.DEFAULT_LENGTH ELSE NULL END) DEFAULT_LENGTH /* (CASE WHEN A.DATA_DEFAULT <> B.DATA_DEFAULT THEN A.DATA_DEFAULT || '!=' || B.DATA_DEFAULT ELSE NULL END) DATA_DEFAULT */ FROM ( SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE,DATA_LENGTH,DATA_PRECISION,DATA_SCALE,NULLABLE,DEFAULT_LENGTH,DATA_DEFAULT FROM ALL_TAB_COLS WHERE OWNER='USER_A' ) A FULL JOIN ( SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE,DATA_LENGTH,DATA_PRECISION,DATA_SCALE,NULLABLE,DEFAULT_LENGTH,DATA_DEFAULT FROM ALL_TAB_COLS WHERE OWNER='USER_B' ) B ON A.TABLE_NAME = B.TABLE_NAME AND A.COLUMN_NAME = B.COLUMN_NAME WHERE A.TABLE_NAME IS NOT NULL AND B.TABLE_NAME IS NOT NULL ) C WHERE C.DATA_TYPE IS NOT NULL OR C.DATA_LENGTH IS NOT NULL OR C.DATA_PRECISION IS NOT NULL OR C.DATA_SCALE IS NOT NULL OR C.NULLABLE IS NOT NULL OR C.DEFAULT_LENGTH IS NOT NULL
这条SQL是有局限的,原因在于LONG类型的列内容比较问题,这块的处理也有很多方案基本思路就是把LONG类型的列转成VARCHAR2或CLOB类型的数据存放到个临时表里然后通过连接或子查询的方式都可以
1、使用临时表存储LONG类型的转换值
CREATE TABLE TMP_CV_LONG(TMP_CHAR VARCHAR(2000), TMP_CLOB CLOB)
INSERT INTO TMP_CV_LONG SELECT '', TO_LOB(DATA_DEFAULT) FROM ALL_TAB_COLS WHERE OWNER='ABC' AND DEFAULT_LENGTH<>0
UPDATE TMP_CV_LONG SET TMP_CHAR = TO_CHAR(TMP_CLOB)
2、在JDBC那块做处理,当默认值长度不等的情况下取LONG类型的数据然后处理(这样做就特别累了)
其它情况
其它情况包括函数\过程内容比较,在Oracle中可以通过ALL_SOURCE视图查出来,具体的问题是怎么比的问题,那简单的A.CTX = B.CTX是不能满足要求的。这块可以看人家SVN或Beyond Compare那样的结果。
SQL Server这块
SQL Server这块数据字典信息相关资料直接通过SQL Server联机丛书的内容就够用了,因为Oracle与SQL Server在整个结构上是不一致的(具体要去baidu文库找Oracle与SQL Server深度对比,文章写的非常棒,边实践边看完它基本上对Oracle与SQL Server就大致有个数了),所以SQL Server下需要做另一套查询SQL。
统计两用户下的表对象缺失情况
SELECT (CASE WHEN A_NAME IS NULL THEN '1' WHEN B_NAME IS NULL THEN '2' ELSE '-1' END) TYPE, (CASE WHEN A_NAME IS NULL THEN B_NAME ELSE A_NAME END) TABLE_NAME FROM ( SELECT UPPER(NAME) A_NAME,OBJECT_ID A_OID FROM USER_A.SYS.TABLES ) A FULL JOIN ( SELECT UPPER(NAME) B_NAME, OBJECT_ID B_OID FROM USER_B.SYS.TABLES ) B ON A.A_NAME = B.B_NAME AND A.A_OID = B.B_OID WHERE A.A_NAME IS NULL OR B.B_NAME IS NULL ORDER BY TYPE
统计两用户下的表的字段结构情况
SELECT * FROM ( SELECT A.TABLE_NAME,A.COLUMN_NAME, (CASE WHEN A.A_DATATYPE <> A.B_DATATYPE THEN (UPPER(A.A_DATATYPE) + '!='+ UPPER(A.B_DATATYPE)) ELSE NULL END) FIELD_TYPE, (CASE WHEN A.A_ORD_POSI <> A.B_ORD_POSI THEN (UPPER(A.A_ORD_POSI) + '!='+ UPPER(A.B_ORD_POSI)) ELSE NULL END) FIELD_ORID, (CASE WHEN A.A_COL_DEF <> A.B_COL_DEF THEN (UPPER(A.A_COL_DEF) + '!=' + UPPER(A.B_COL_DEF)) ELSE NULL END) FIELD_DEFVALUE, (CASE WHEN A.A_ISNULL <> A.B_ISNULL THEN (UPPER(A.A_ISNULL) + '!=' + UPPER(A.B_ISNULL)) ELSE NULL END ) FIELD_ISNULL, (CASE WHEN A.A_CMAXLEN <> A.B_CMAXLEN THEN (UPPER(A.A_CMAXLEN) + '!=' + UPPER(A.B_CMAXLEN)) ELSE NULL END) FIELD_LEN, (CASE WHEN A.A_NUM_PREC <> A.B_NUM_PREC THEN (UPPER(A.A_NUM_PREC) + '!=' + UPPER(A.B_NUM_PREC)) ELSE NULL END) FIELD_PRE, (CASE WHEN A.A_NUMSCAL <> A.B_NUMSCAL THEN (UPPER(A.A_NUMSCAL) + '!=' + UPPER(A.B_NUMSCAL)) ELSE NULL END) FIELD_SCA FROM ( SELECT UPPER(A.TABLE_NAME) AS TABLE_NAME, UPPER(A.COLUMN_NAME) AS COLUMN_NAME, A.ORDINAL_POSITION AS A_ORD_POSI, A.COLUMN_DEFAULT AS A_COL_DEF, UPPER(A.DATA_TYPE) A_DATATYPE, A.IS_NULLABLE AS A_ISNULL, A.CHARACTER_MAXIMUM_LENGTH AS A_CMAXLEN, A.NUMERIC_PRECISION AS A_NUM_PREC, A.NUMERIC_SCALE AS A_NUMSCAL, B.ORDINAL_POSITION AS B_ORD_POSI, B.COLUMN_DEFAULT AS B_COL_DEF, UPPER(B.DATA_TYPE) B_DATATYPE, B.IS_NULLABLE AS B_ISNULL, B.CHARACTER_MAXIMUM_LENGTH AS B_CMAXLEN, B.NUMERIC_PRECISION AS B_NUM_PREC, B.NUMERIC_SCALE AS B_NUMSCAL FROM USER_A.INFORMATION_SCHEMA.COLUMNS A, USER_B.INFORMATION_SCHEMA.COLUMNS B WHERE A.TABLE_NAME = B.TABLE_NAME AND A.COLUMN_NAME = B.COLUMN_NAME ) A ) B WHERE B.FIELD_TYPE IS NOT NULL OR B.FIELD_DEFVALUE IS NOT NULL OR B.FIELD_ORID IS NOT NULL OR B.FIELD_ISNULL IS NOT NULL OR B.FIELD_LEN IS NOT NULL OR B.FIELD_PRE IS NOT NULL OR B.FIELD_SCA IS NOT NULL
其它情况
相关文章推荐
- 使用Red Gate Sql Compare 数据库同步工具进行SQL Server的两个数据库的结构比较、同步
- 两个数据库比较 对比视图存储过程及表结构差异
- 两个数据库比较 对比视图存储过程及表结构差异增加外键差异
- 两个数据库比较 对比视图存储过程及表结构差异
- CodeIgniter学习笔记一:基本结构、控制器、视图、超级对象、数据库
- 两个数据库比较 对比视图存储过程及表结构差异
- 比较两个数据库中的视图/存储过程的结构(结构比较,不是功能比较)
- 笔记之Oracle 数据字典视图:v$fixed_table里包含了三类对象:X$对象、基于X$表的GV$和V$视图
- 两个数据库比较 对比视图存储过程及表结构差异
- SQL Server 比较两个数据库的视图和存储过程结构差异
- (转载) 两个数据库比较 对比视图存储过程及表结构差异
- 基于数据字典的通用查询系统(二)数据库组成结构的分析
- sqlserver数据库进行数据和结构比较和同步 Visual Studio2017 数据库架构比较
- 两个数据库比较 对比视图存储过程及表结构差异
- Oracle之SQL基础--创建数据库对象(序列 视图)及索引
- SAP HANA 数据库文件系统的目录结构(SAP Hana DB filesystem directory structure)
- 在SELECT语句的FROM子句中最多可以指定多少个表或视图,相互之间要用什么分隔,当所查询的表不在当前数据库时,可用什么格式来指出表或视图对象?
- 内置对象Clob对从数据库表中取的字符大对象CLOB类型的列值进行读取操作
- python mysql 插入的数据是字典时,可以直接插入到数据库,不要进行for循环读取每一个字段
- 转:邹建--比较两个数据库的表结构差异2