java

循环执行oracle到mysql的迁移步骤及各种注意事项

我爱IT资讯库   2021/02/24

改章节笔者在北京逛街的时候突然想到的...今天就有想写几篇关于循环执行的笔记,所以回家到之后就奋笔疾书的写出来发表了

    最近公司一个项目须要将数据库停止一次迁移,从oracle到mysql,网上资料甚少,现将我本次迁移进程中所遇到的一些问题总结于此(主要是存储进程的迁移),希望能给自己做一个日后的参考,如果有幸能帮助到大家更好。

    -- mysql中没有包的观点,因此迁移的时候将存储进程命名为'包名.存储进程名'的格式

    mysql存储进程格式:

    DELIMITER $$   -- 分隔符

    -- CREATE PROCEDURE([[IN |OUT ] 参数名 数据类型...]) ,IN和OUT写在最前面,其中IN可以省略

    CREATE PROCEDURE `pkg_ypgl.prc_ypsc`(

 prm_ypbm VARCHAR (20),  

  OUT prm_AppCode VARCHAR (20),

  -- 程序执行代码

  OUT prm_ErrorMsg VARCHAR (100)

  -- 程序执行错误信息

    )

    BEGIN

  /*变量定义*/

  DECLARE n_count DECIMAL (8) ;

 DECLARE done INT(10);

 

  /*设置游标结束标记*/

 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;  -- 如果NOT FOUND,取不到值,则将done赋值1,并且程序继承执行

    SET done=0;

 

    /*定义一个区块lavel_error,逻辑错误处理*/

   label_error :  BEGIN

  /*定义游标*/

 DECLARE cur_bdjl CURSOR FOR

  SELECT .....

   /*打开游标*/

   OPEN cur_bdjl ;

   REPEAT

     FETCH cur_bdjl INTO v_aaz001....

    IF NOT done THEN -- 如果结束标记done为0则继承循环

    ........

    END IF;

   /*结束循环,关闭游标*/ 

     UNTIL done -- 直到NOT FOUND

   END REPEAT ;

   CLOSE cur_bdjl ;

   

   SET prm_AppCode = 'noerror' ;  -- 将prm_AppCode设为正确

   SET prm_ErrorMsg = '' ;

  END;

 

  END$$

    DELIMITER ;

 

 

 

 

    数据类型:

    Oracle:varchar2    Mysql:varchar(20)  (参数自设)

    Oracle:number()    Mysql:decimal()

    Oracle:date       Mysql:datetime

 

    定义变量:

    Mysql须要在每句前面加DECLARE

 

    给变量赋值:

    Oracle:v_string := ‘asdas’;    Mysql: SET string := ‘asdas’; (等号前面的冒号可以有也可以没有)

 

    异常处理:

    Oracle:EXCEPTION WHEN OTHERS THEN….

    Mysql: DECLARE { EXIT | CONTINUE } HANDLERFOR { error-number | { SQLSTATE error-string } | condition } SQL statement;

   SQLWARNING 代表全部以01开头的错误代码 

   NOT FOUND 代表全部以02开头的错误代码,也包括游标结束的时候

   SQLEXCEPTION 代表除了SQLWARNING和NOT FOUND 的全部错误代码

    eg. DECLARE EXIT HANDLER FORSQLEXCEPTION,SQLWARNING,NOT FOUND SET a = 1;

    注:一个begin....end里头只能声明一个HANDLER,EXIT表示遇到这种异常时就执行SET a = 1然后结束这个存储进程,CONTINUE表示遇到这种异常时就SET a = 1,然后继承执行之后的存储进程

 

    跳转:

    Oracle:  GOTO label_error;

            …..

    <<label_error >>

    Mysql:初始化错误代码prm_AppCode为“错误”,定义一个区块label_error,在区块的最后将prm_AppCode set为’noerror’,中间触发条件,将GOTO label_error;改写成leave label_error;跳出区块

 

 

    游标:

    Mysql只有静态游标,没有动态游标,用存储进程代替

    定义游标的语句为DECLAREcur_bdjl CURSOR FOR …..

    Mysql不支持rec_curname.aaz001这种写法,所以必须将游标获得的全部字段FETCH INTO 到变量里

 

 

    循环:

    Mysql里有三种循环方式

    (1).WHILE循环

 WHILE  expression DO

 statements

 END   WHILE;

 (2).LOOP循环

 LOOP

  statements

  END  LOOP;

 (3).REPEAT UNTIL循环

 REPEAT

 statements

 UNTIL expression

 END  REPEAT;

 

 

    序列:

    Mysql中没有序列,用函数+表的方法代替.

    建表语句:

    CREATE TABLE `seq` (
  `name` varchar(20) NOT NULL DEFAULT '' COMMENT '序列号生成器名称',
  `val` bigint(20) unsigned NOT NULL COMMENT '序列号',
  `increment` int(4) DEFAULT '1' COMMENT '序列的增量',
  `min` bigint(20) DEFAULT NULL COMMENT '序列最小值',
  `max` bigint(20) DEFAULT NULL COMMENT '序列最大值',
  `cycle` char(1) DEFAULT 'N' COMMENT '是不是循环',
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='mysql模拟序列号生成器用表'

    

    函数如下(自己写的,可能有错):

    DELIMITER $$

    DROP FUNCTION IF EXISTS `seq`$$

    CREATE FUNCTION `seq`(seq_name VARCHAR(20))RETURNS BIGINT(20)

    BEGIN

    DECLARE v_value BIGINT(20);

    DECLARE v_CYCLE CHAR;

    DECLARE v_MIN BIGINT(20);

    DECLARE v_MAX BIGINT(20);

    SELECT a.val,a.MIN,a.MAX,a.CYCLE INTOv_value,v_MIN,v_MAX,v_CYCLE FROM seq a WHERE NAME = seq_name;

   IFv_CYCLE = 'Y' AND v_value = v_MAX THEN -- 该序列为循环且以后值为其最大值

  UPDATE seq  -- 将以后值设为 v_MIN  

  SET   val = v_MIN  

  WHERE NAME = seq_name; 

 ELSE

  UPDATE seq  -- 否则将以后值设为val + increment  

  SET   val = val + increment  

  WHERE NAME = seq_name;

  END IF;

  SELECT  val INTO v_value FROM seqWHERE NAME = seq_name;

   RETURN v_value;

    END$$

    DELIMITER ;

    

    

 

 

    更新:

    Oracle: UPDATE TABLE T SET (A,B,C) = (SELECT A,B,C FROM TABLE_2 K WHERE K.Y =T.Y) WHERE T.X = V_X;

    Mysql: UPDATE TABLE T,TABLE_2 K SET T.A =K.A,T.B=K.B,T.C=K.C WHERE  K.Y = T.Y ANDT.X = V_X

 

    GROUP BY:

    mysql的group by 语句可以select 没有被分组的字段,如

    select id,name,age from A group by age

    这个取出的id,name地点的行是每个分组中的第一行数据

 

    调用:

    Mysql: call procedure_name(全部参数);

 

 

    跳出循环:

    Oracle: EXIT;

    Mysql: 将循环的内容定义为一个区块label_loop,须要跳出循环时则 leave label_loop;

 

 

    注释:

    1、#注释内容

    2、-- 注释内容  注意-- 后须要加一个空格

    3、块注释用/*注释内容*/

 

 

    表的注释:

    在oracle中执行如下语句:

    select 'altertable '||table_name||' comment'||' '''||COMMENTS||' '''||';'fromUSER_TAB_COMMENTS where commentsis not null;

    将失掉的结果放到mysql中执行即可添加表名的注释

 

 

    表的字段注释:

    在oracle中执行如下语句:

    select distinct(data_type) FROM all_tab_columns where owner='YDMIS'

    将查询出的本次转换涉及到的数据类型用decode函数转换为Mysql中对应函数(参数)的形式,如将CHAR转换为CHAR(20),参数的值在all_tab_columns的DATA_LENGTH  DATA_PRECISION  DATA_SCALE中获得。

    在oracle中执行如下语句,注意decode函数里的参数需根据上一步的查询结果转换:

    每日一道理
爱,有的时候不须要山盟海誓的承诺,但她一定须要细致入微的关怀与问候;爱,有的时候不须要梁祝化蝶的悲壮,但她一定须要心有灵犀的默契与投合;爱,有的时候不须要雄飞雌从的追随,但她一定须要相濡以沫的支持与理解。

    select 'alter table '||a.table_name||' modify column '||a.column_name||' '||decode(b.data_type,'VARCHAR2','VARCHAR('||b.DATA_LENGTH||')','DATE','DATETIME','NUMBER','DECIMAL('||b.DATA_PRECISION||','||b.DATA_SCALE||')','CHAR','CHAR('||b.DATA_LENGTH||')','LONGRAW','mediumblob')||' comment '||''''||comments||''''||';'

    from user_col_comments a,all_tab_columns b

    where a.comments is not null

    and a.table_name = b.table_name

    and a.column_name = b.column_name

    and b.owner = 'YDMIS';

    将失掉的结果放到mysql中执行即可添加表字段的注释

 

 

    函数:

    

功能 oracle mysql 备注 eg.oracle eg.mysql
连接字符串 || concat()  'a'||'b'||'c' concat( 'a','b','c')
将其他格式转换为字符串 concat(x,'')
截取字符串 substr() substring() substr('abcd',1,3) substring('abcd',1,3)
string转换为date to_date() str_to_date(str, format) to_date(aae036,'yyyy-mm-dd hh24:mi:ss') str_to_date(aae036,'%Y-%m-%d %H:%i:%s')
获取以后日期 sysdate now(),sysdate(),current_date now()返回的是程序开始执行时的时光,sysdate()返回实时时光,
一般用now()
current_date表示以后的年月日
取出日期的指定部分 date_format(date,type) %Y:年
%c:月
%d:日
%H:小时
%i:分钟
%s:秒
date_format(now(),'%Y-%c-%d %h:%i:%s')
增长一天 sysdate+1 DATE_ADD(date,INTERVAL expr type) sysdate+1 DATE_ADD(now() ,INTERVAL 1 DAY)
类型转换 TO_CHAR 
TO_DATE 
TO_NUMBER
cast(xxx as type) type:二进制 : BINARY
字符型,可带参数 : CHAR()
日期 : DATE
时光: TIME
日期时光型 : DATETIME
浮点数 : DECIMAL
整数 : SIGNED
无符号整数 : UNSIGNED
to_char(33)  cast(33 as char(2))
精度转换 to_number(x,type) round(x,d) 保存到小数点后d位,而第d位的保存方式为四舍五入。若要保存x值小数点左边的d位,可将d设为负值
 
替换空值 NVL( string1, replace_with) ifnull(string1, replace_with)
decode() decode (expression, search_1, result_1,  default) case expression when search_1 then result_1 else default end

文章结束给大家分享下程序员的一些笑话语录: 这个世界上只有10种人:懂得二进制的和不懂得二进制的。




热门内容

2015收获的季节

2015收获的季节

—————————————————————前言————————————————————— ———————... ...

JSP中的pageEncoding和contentType属性

关于JSP页面中的pageEncoding和contentType两种属性的区别: pageEncoding是js... ...

对XX证券报关于物联网操作系统的几个问题的答复

XX证券报提问了几个关于物联网和物联网操作系统的问题,个人表达了一些粗陋的观点,在这里发表出来,与行业朋友交流和探... ...
In语句优化

In语句优化

In语句的优化 现有两张表: CLINIC_ORGANISM 数据量:1400 LAB_DRUGRESISTITE... ...
fuzzysearch, 在JavaScript中,快速而快速的模糊搜索

fuzzysearch, 在JavaScript中,快速而快速的模糊搜索

源代码名称:fuzzysearch源代码网址:http://www.github.com/bevacqua/fuzzys ...

SQL Server里的 ISNULL 与 NULLIF

SQL Server 中有两个参数,语法:     ISNULL(check_... ...

判断SD是否存在及其容量查询

这个非常简单,直接上代码: MainActivity: package com.home.getsdinf... ...

Python:如何排序(sort)

一、前言 python的列表(list)有两个排序方法: 一种是内建的list.sort()方法,可以直接改变列表的内容 ...

boost库在工作(5)作用域智能指针scoped_ptr之四

第二种情况,主要就是使用在调用异常抛出的函数的地方。如下面的例子: //异常抛出的函数,适合使用智能指针... ...

Error:couldnotopen`C:\ProgramFiles\Java\jre6\lib\i386\jvm.cfg'

昨天刚过情人节!哈哈,好久没记录学习内容了,今天在房子闲着没事重新安装jdk,按道理很简单的; 第一步下载jdk; ...

第49周二

晚上总结下今天,主要是在完善用户需求文档,同时看了jquery相关的操作技巧,主要是想学习jquery源码,在知乎jqu ...

C++ #include 和 using std::string

今天,偶尔写了一个小小的程序,关于字符串问题程序。 比如,我想连续打印用户输入的字符串。 #include&l... ...

Struts Hibernate Spring 经典面试题

Hibernate工作原理及为什么要用? 原理: 1.读取并解析配置文件 2.读取并解析映射信息,创建Ses... ...

SAP Performance浅析

本文来源于:http://scnblogs.techweb.com.cn/tcsapbw/archives/106... ...

数据库MySQL与xls文件的互导

      最近的一个项目需要将xls表导入到MySQL数据库中和将MySQL数据表导出到... ...

Head-of-Line Blocking (线头阻塞)

Head of Line (HOL) Blocking 产生的原因: 概念:队列的首个packet由于它的目的... ...

Python set的高效利用

python set的应用   ... ...

CollectionFrameWork

collectionframework如下: collection ├list │├linkedlist │├array ...

JAVA访问修饰符构造函数的问题(转)

java访问修饰符 构造函数的问题 java访问修饰符-限定符总结(类比c#) java访问修饰符--------- ...

PAT甲1004CountingLeaves【dfs】

1004counting leaves(30 分) a family hierarchy is usually p ...

171.[LeetCode]Excel Sheet Column Number

题目: Related to question Excel Sheet Column Title ... ...

在.NET中获取一台电脑名,IP地址及当前用户名

在.NET中获取一台电脑名,IP地址及当前用户名是非常简单,以下是我常用的几种方法,如果大家还有其他好的方法,可以回复一... ...
sun directory server

sun directory server

Sun One Directory Server(LDAP)安装和调整指南   ... ...
黑客讲故事:攻下隔壁女生路由器后,我都做了些什么

黑客讲故事:攻下隔壁女生路由器后,我都做了些什么

路由器被蹭网后,我有被黑的风险吗? Evi1m0,来自知道创宇,邪红色信息安全组织创始人 其实这个问题可以... ...

oracle 10g for redhat5

解压文件 解压文件命令: unzip 10201_database_linux32.zip ... ...

什么是I2C协议?

I2C协议是单片机与其它芯片常用的通讯协议,由于只需要两根线,所以很好使用。 一. I2C协议技术性能:&nb... ...

[USACO15DEC]最大流MaxFlow

题目:洛谷p3128。 题目大意:一棵n个点的树,每次将两个节点最短路径所覆盖的所有节点的流量加1。问你最后流量最大的节 ...

kde4.1 alpha1

KDE Project Ships First Alpha of KDE 4.1 KDE Commun... ...

oracle 函数 和 优化

sql语句中,如果where条件里面含有not, !=, <> ,null ,则即使该字段建有索引,也... ...
09年中国互联网企业市值排名

09年中国互联网企业市值排名

这是一个最坏的时代,也是一个最好的时代。自07年底美国次贷危机以来,全球经济发生了巨大的变化。股票市场也随之跌荡起... ...