自动产生不同数据库下指定schema间DDL同步脚本的存储过程

| No Comments

写这个自动产生同步脚本的代码足足用了我两天的时间,今天上午终于做完了。

我这里说一下我处理这个问题的思路:

现在要做的是ipra开发环境ipradev的用户ipramasipra国航测试环境caipratest的用户caipracamas之间的DDL同步。注意这里是不同数据库下不同schema间的DDL同步,并且这些schema下的default tablespace和索引所在的tablespace均不相同

   

    我原先本来用streams已经实现了上述DDL同步,但是因为streams不够稳定,我决定放弃streams,转而用代码来自动产生同步脚本

    生成这个同步脚本的思路是:

    1、比较两边数据库相对应schema下同名objectlast_ddl_time,以ipradev为同步的源头,去同步那些在caipratestlast_ddl_time滞后的object

    2、如果ipradev中有object,但在caipratest中并不存在同名object,则在caipratest中建立该object

    3、如果caipratest中有object,但在ipradev中并不存在同名object,则在caipratestdropobject

 

    在写上述代码的时候考虑到了如下问题:

1、考虑到了tableconstrainttable中的字段的default值、table commentcolumn commentindexviewsequencetypetype bodyfunctionpackagepackage bodyproceduretrigger间的同步。

2、考虑到了按指定的"表空间映射"生成的DDL脚本中的表空间转换。

       3、不支持synonym的同步、因为synonym的目标可能是不同的schema,这个schema间的转换我无法事前知道,synonym的同步就手工做一下好了。

       4dbms_metadata.get_ddl的返回值是CLOB,我专门写了一个子存储过程来一行一行打印CLOB

5dbms_output.put_line打印行的时候有一个不能超过255byte的限制,如果你要print 的行的长度超过255byteoracle这里会报错 ORA-06502: PL/SQL numeric or value error: host bind array too small,在我代码里专门对这种情况做了处理,并且考虑到了中文,这个里面为了保证print出来的代码能够顺利的在目标数据库执行,并没有生硬的从254处截断。

6oracleserver output的最大长度是100万,如果你一次更新需要print的内容太多,会超过这个100万的限制,此时oracle会报错:ORA-20000: ORU-10027: buffer overflow, limit of 1000000 bytes,出现这种情况的时候需要手工处理一下。

 

P_SYS_GEN_DIFF_DEV_AND_TEST.prc是自动产生同步脚本的主存储过程

P_SYS_PRINT_DDL.prc是专门处理CLOB的子存储过程

 

Leave a comment