亲自体验oracle转mysql

在下小小程序员,现在正在做oracle转向mysql,就是把oracle数据库上的所有表结构,视图,存储过程,函数,包等等等都转到mysql中,现在留下一点点记录,不对之处希望各位能够指出,也很希望一起分享你的经验:

 

 

表之间的转换,如果暂不说其中调用的函数,还是没什么问题的,因为使用的非常规类型很少

 

视图之间的转换出了不少问题:

oracle 支持的子表,例如:

 

select * from dept, (select * from emp where emp.sal>8000) where dept.id = emp.deptid

 

 mysql不支持子表,所以较为简单的转换方法为左连表

 

select * from dept left emp on emp.sal>8000 where dept.id = emp.deptid

 

 

oracle 最常用的左连表 emp.deptid = emp.id(+) 的 (+)

 

select * from emp, (select * from dept where dept.no = 10) where emp.deptid = emp(+)

 

mysql当然没有这个(+),所以都要改为left join

但是mysql支持这种写法:

 

 

select * from emp left join (dept , company, province) on (emp.deptid = dept.id and emp.companyid = company.id and emp.provinceid = province.id) -- 可以简化left join写法,但是感觉上没有(+)写的方便

 

--------------------------------------------------------------

 

上边的知识虽然看似无华,单支持了mysql最大的弱点,就是试图机制不完善;不同于oracle的视图概念-优化的sql语句,mysql的查询sql语句有时是不能写在视图中的。我知识抛砖引玉,优秀的程序员应该不止单单会看懂代码滴。我是sb,这只是我的一点sb的解释。

 

--------------------------------------------------------------

 

ok,废话少说

 

 

oracle 还有一强大之处就是其分析函数,相比用过oracle的个人新老用户们,多多少少都接触过。

 

oracle有如下代码:

select *
  from (select pt.xmid,pt.xmmc,mast.dmnr,ct.KHQC ,pt.jhks ,pt.jhjs ,pt.xmzje,
               rank() over(partition by pt.xmid order by pt.xmbbh desc) rn
          from T_LPROMIS_XMGL_GBBXMXX pt,T_LPROMIS_YXGL_KHXX ct,t_lpromis_base_mast mast 
         where pt.xmid in (select ct.xmid from T_LPROMIS_YXGL_HTXX ct)
           and mast.DMBH = pt.CWLX 
           and mast.dmlb = '0114'
           and pt.khid = ct.id
           and extract(year from pt.xmjhjssj) > extract(year from sysdate)) t
 where t.rn = 1

 这样就可以取符合条件中每个项目(pt.xmid)中版本(pt.xmbbh)最大的一条记录

 

而mysql中,没有如rank() dense_rank() row_number()等等这些可以带over([partition by xx][order by xx])分析函数. 但是可以用它伟而大的用户变量解决

 

SELECT
	t.xmid,
	t.ssbmid,
	t.xmmc,
	t.dmnr,
	t.KHQC,
	t.XMJHKSSJ,
	t.XMJHJSSJ,
	t.xmzje
FROM
	(
		SELECT
			t1.xmid,
			t1.ssbmid,
			t1.xmmc,
			mast.dmnr,
			ct.KHQC,
			t1.XMJHKSSJ,
			t1.XMJHJSSJ, 
			t1.xmzje ,
		IF (
			@pro_id = t1.xmid ,@rk := @rk + 1 ,@rk := 1
		) AS rank,
		@pro_id := t1.xmid -- rank() over(partition by pt.xmid order by pt.xmbbh desc) rn
	FROM
t_lpromis_base_mast mast,
	(
		SELECT
			@rownum := 0 ,@pro_id := NULL,
			@rk := 0
	) init,
		(
			SELECT
				*
			FROM
				T_LPROMIS_XMGL_GBBXMXX pt
			ORDER BY
				pt.xmid,
				pt.xmbbh
		) t1
	LEFT JOIN T_LPROMIS_YXGL_KHXX ct ON t1.khid = ct.ID
	
WHERE
	t1.xmid IN (
		SELECT
			ct.xmid
		FROM
			T_LPROMIS_YXGL_HTXX ct
	)
AND mast.DMBH = t1.CWLX 
AND mast.dmlb = '0114' 
and extract(year from t1.xmjhjssj) =
extract(year from now()) + 1
	) t 
where t.rank = 1
 

 

-----------------------------------------------------------------------------------

 

这里再给出一些小小的tip,看之无害,也可能没用

 

做分页mysql 有 limited; oracle 用 rownum

 

时间类型mysql 有 date datetime stamptime time 等等, 而且可以直接比较; oracle 则要用 to_data取比较

 

oracle的函数可以返回record; mysql还没有找到可以返回对应的方法;

 

oracle的函数可以使用管道,返回table, 代码如下; mysql还没有找到对应方法

 

create type human_record_type is object(compyname nvarchar2(40),deptname nvarchar2(40));
 create type human_table_type is table of human_record_type;   
 create or replace function get_human_resource return human_table_type pipelined as
 hr human_record_type;
 begin
   for myrow in (select * from t_lpromis_hr_bm) loop -- loop record of data to pipe row information
     hr := human_record_type(myrow.comy,myrow.dept)
     pipe row(hr);
   end loop;
   return ;
 end;     

 

简易调用:

select * from table(get_human_resource)

 

 

----------------------------------------------------------------------------------------------------

 

未完

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

未完

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值