sql语句中,MySQL函数替换成Oracle函数

sql语句中,MySQL函数替换成Oracle函数

转载:数据库迁移(MySQL函数转化为Oracle函数)_mysql语句转oracle语句在线工具_呓语肿弟的博客-CSDN博客

非常实用的文章。

ifnull()函数–Oracle使用nvl()替换

-- mysql
IFNULL(t.name, '');

-- oracle
nvl(t.name, '');

concat()函数

oracle也可以使用这个函数,但是建议超过两个以上使用函数嵌套来拼接字符串

-- mysql
concat('ac','eg','gg')

-- oracle
'ac' || 'eg' || 'gg'

-- 或者
concat(concat('ac','eg'),'gg')

substring()–Oracle使用substr()替换

截取字符串:从特定位置开始的字符串返回一个给定长度的子字符串
SUBSTRING(字符串,position);//获得字符串的position位置之后的所有字符
-- 如果position为0,则返回一个空串 

SUBSTRING(string,position,length);//获得字符串的position位置之后的length个字符

例子

--mysql
    SELECT substring('I LIKE MYSQL', 3) FROM dual;//LIKE MYSQL
    SELECT substring('I LIKE MYSQL', 0) FROM dual;// 
    SELECT substring('I LIKE MYSQL', -3) FROM dual;//SQL
    SELECT substring('I LIKE MYSQL',3,6) FROM dual;//LIKE M
    
--oracle
    SELECT SUBSTR('I LIKE MYSQL', 1) FROM dual --截取所有字符串,返回'I LIKE MYSQL'
	SELECT SUBSTR('I LIKE MYSQL', 2) FROM dual --从第2个字符开始,截取到末尾。返回' LIKE MYSQL'
	SELECT SUBSTR('I LIKE MYSQL', -4) FROM dual   --从倒数第4个字符开始,截取到末尾。返回'YSQL'
	SELECT SUBSTR('I LIKE MYSQL', 3, 6) FROM dual --从第3个字符开始,截取6个字符。返回'LIKE M'
	SELECT SUBSTR('I LIKE MYSQL', -4, 3) FROM dual--从倒数第4个字符开始,截取3个字符。返回'YSQ'

substring_index()–Oracle使用substr()、instr()替换

substring_index(“待截取有用部分的字符串”,“截取数据依据的字符”,截取字符的位置N)

Oracle instr()函数介绍

instr()函数的格式 (俗称:字符查找函数)
格式一:instr(string1,string2 ) // instr(源字符串, 目标字符串)
格式二:instr(string1,string2 [,start_position [,nth_appearance]])//instr(源字符串, 目标字符串, 起始位置, 匹配序号)

解析:string2 的值要在string1中查找,是从start_position给出的数值(即:位置)开始在string1检索,检索第nth_appearance(几)次出现string2。

注:在Oracle/PLSQL中,instr函数返回要截取的字符串在源字符串中的位置。只检索一次,也就是说从字符的开始到字符的结尾就结束。
    
例子
格式一:
select instr('helloworld','l') from dual; --返回结果:3 默认第一次出现“l”的位置
select instr('helloworld','lo') from dual; --返回结果:4 即第一个“lO”出现的位置
select instr('helloworld','wo') from dual; --返回结果:6 即“wo”同时出现,第一个字母“w”出现的位置

格式二:
select instr('helloworld','l',2,2) from dual;
	--返回结果:4 	也就是说:在"helloworld"的第2(e)个位置开始,查找第二次出现“l”的位置
select instr('helloworld','l',3,2) from dual;  
	--返回结果:4    也就是说:在"helloworld"的第3(l)个位置开始,查找第二次出现的“l”的位置
select instr('helloworld','l',4,2) from dual;  
	--返回结果:9    也就是说:在"helloworld"的第4(l)个位置开始,查找第二次出现的“l”的位置
select instr('helloworld','l',-1,1) from dual;  
	--返回结果:9    也就是说:在"helloworld"的倒数第1(d)个位置开始,往回查找第一次出现的“l”的位置
select instr('helloworld','l',-2,2) from dual;  
	--返回结果:4    也就是说:在"helloworld"的倒数第2(l)个位置开始,往回查找第二次出现的“l”的位置
select instr('helloworld','l',2,3) from dual;  
	--返回结果:9    也就是说:在"helloworld"的第2(e)个位置开始,查找第三次出现的“l”的位置
select instr('helloworld','l',-2,3) from dual; 
	--返回结果:3    也就是说:在"helloworld"的倒数第2(l)个位置开始,往回查找第三次出现的“l”的位置

例子

--mysql
	SELECT SUBSTRING_INDEX('192-168-8-203','-',1); //192 (取第一个'-'前面的字符串)
	SELECT SUBSTRING_INDEX('192-168-8-203','-',-1); //203(取倒数第一个'-'后面的字符串)
	SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('192-168-8-203','-',2),'-',-1); //168
    SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('192-168-8-203','-',-2),'-',1); //8
    
--oracle
    SELECT SUBSTR('192-168-8-203',1,INSTR('192-168-8-203','-',1,1)-1) FROM DUAL //192
	SELECT SUBSTR('192-168-8-203',INSTR('192-168-8-203','-',-1,1)+1) FROM DUAL //203
    SELECT SUBSTR('192-168-8-203',INSTR('192-168-8-203','-',1,1)+1,(INSTR('192-168-8-203','-',1,2)-(INSTR('192-168-8-203','-',1,1)+1))) FROM DUAL; //168
	SELECT SUBSTR('192-168-8-203',INSTR('192-168-8-203','-',1,2)+1,(INSTR('192-168-8-203','-',1,3)-(INSTR('192-168-8-203','-',1,2)+1))) FROM DUAL; //8

locate()–Oracle使用instr()替换

mysql locate()函数介绍

- locate(字符串1,字符串2)
从字符串2的第一个位置开始找,找到并返回 字符串1在字符串2中第一次出现的位置

- locate(字符串1,字符串2,pos)
从字符串2的pos位置开始找,找到并返回字符串1在字符串2中第一次出现的位置

如果找不到则返回0

例子

--mysql
	locate('bar', 'foobarbar') //4
	locate('x','abxz') //3
	locate('a','bxz') //0
--oracle
	instr('foobarbar','bar') //4
   	instr('bxz','a') //0

replace()

Oracle同样也是这个函数

datediff()–Oracle使用ROUND(TO_NUMBER())替换

mysql datediff()函数介绍

datediff函数:返回两个日期之间的天数。
    
datediff(date1,date2);//date1-date2
date1 和 date2 参数是合法的日期或日期/时间表达式。

注释:只有值的日期部分参与计算。

SELECT DATEDIFF('2008-12-30','2008-12-29') AS DiffDate //1

SELECT DATEDIFF('2008-12-29','2008-12-30') AS DiffDate //-1

例子

遇到datediff函数时,可以用以下方法在oracle中实现该函数的功能:
天:
ROUND(TO_NUMBER(END_DATE - START_DATE))
小时:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24)
分钟:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60)
秒:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60)
毫秒:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60 * 60)

--mysql
    DATEDIFF(dat1.DT_ACCOUNTING, dat2.DT_ACCOUNTING);
--Oracle
    ROUND(TO_NUMBER(TO_DATE(dat1.DT_ACCOUNTING)-TO_DATE(dat2.DT_ACCOUNTING)));

--mysql
    DATEDIFF('2022-09-09', '2022-09-08');
--oracle
	ROUND(TO_NUMBER(TO_DATE('2022-09-09','yyyy-MM-dd HH24:mi:ss') - TO_DATE('2022-09-08','yyyy-MM-dd HH24:mi:ss')))

date_format()–Oracle使用to_char()替换

例子

-- mysql
date_format(sysdate(), '%Y-%m-%d')

-- oracle
to_char(sysdate,'YYYY-MM-DD')

str_to_date()–Oracle使用to_date()替换

例子

-- mysql
str_to_date('2023-01-01', '%Y-%m-%d')

-- oracle
to_date('2023-01-01','YYYY-MM-DD')

char_length()–Oracle使用lengthb()替换

mysql char_length()介绍

返回以字符来测量字符串str的长度。一个多字节字符算作一个字符。
这意味着,对于包含五个两字节字符的字符串,那么 length() 返回10,而 char_length() 返回5select char_length("text"); //4

例子

-- mysql
	SELECT LENGTH('abc我') FROM dual;//4
	SELECT CHAR_LENGTH('abc我') FROM dual;//6
	
-- Oracle
    SELECT LENGTH('abc我') FROM dual;//4
	SELECT LENGTHB('abc我') FROM dual;//6

-- 参数为 null 或 空字符串'',返回null
-- 不传参,抛出异常

curdate(),NOW(),CURTIME()–Oracle使用sysdate()替换

select sysdate();

date_sub()/subdate()

mysql date_sub()/subdate()介绍

DATE_SUB(date,INTERVAL expr type); //从日期减去指定的时间间隔
DATE_SUB("2022-09-10", INTERVAL 3 DAY);//2022-09-07

SUBDATE(date, INTERVAL expr unit);//从日期减去指定的时间间隔
SUBDATE("2022-09-10", INTERVAL 3 DAY);//2022-09-07

oracle可以直接使用INTERVAL来计算时间

-- mysql
	date_sub('2022-09-10 13:13:20',interval 2 day);//2022-09-08 13:13:20
	
-- oracle
	select TO_DATE('2022-09-10 13:13:20','yyyy-MM-dd HH24:mi:ss') - interval '2' day FROM DUAL;//2022-09-08 13:13:20
-- 或
    SELECT TO_DATE('2022-09-10 13:13:20','yyyy-MM-dd HH24:mi:ss') - 2 FROM DUAL;

Mapper.xml中
--mysql
    SELECT DATE_SUB(CURDATE(), INTERVAL #{dtInterval}-1 DAY) FROM DUAL;
--oracle
    SELECT SYSDATE - INTERVAL #{dtInterval}-'1' DAY FROM DUAL;

year()/month()/day()/quarter()

mysql year()/month()/day()/quarter介绍

--year()
	获取一个日期的年份值,范围为10009999,如果日期为零,YEAR()函数返回0
	SELECT year("2022-09-10") FROM DUAL; //2022
--month()
    获取一个日期的月份值
    SELECT month("2022-09-10") FROM DUAL; //09
--day()
    获取一个日期的日期值
    SELECT day("2022-09-10") FROM DUAL; //10
--quarter()
    获取一个日期所在第几个季度
    SELECT quarter("2018-01-07 10:17:12"); // 1
	SELECT quarter("2018-12-07"); // 4

例子

-- oracle
  -- 年
	SELECT to_number(to_char(to_date('2022-09-10','yyyy-MM-dd'),'yyyy')) FROM DUAL;//2022SELECT EXTRACT(year from to_date('2022-09-10','yyyy-MM-dd')) FROM DUAL;//2022
  -- 月
	SELECT to_number(to_char(to_date('2022-09-10','yyyy-MM-dd'),'mm')) FROM DUAL;//9
 	-- 或
    SELECT EXTRACT(month from to_date('2022-09-10','yyyy-MM-dd')) FROM DUAL;//9
  -- 日
	SELECT to_number(to_char(to_date('2022-09-10','yyyy-MM-dd'),'dd')) FROM DUAL;//10SELECT EXTRACT(day from to_date('2022-09-10','yyyy-MM-dd')) FROM DUAL;//10
  -- 季度
   	SELECT TO_CHAR (to_date('2022-09-10','yyyy-MM-dd'), 'q') FROM dual; //3
    SELECT TO_CHAR (SYSDATE, 'q') FROM dual; //获取当前季度

find_in_set()

mysql find_in_set()介绍

FIND_IN_SET(str,strlist)
str:要查询的字符串
strlist:字段名参数以","分隔如(1,2,6,8,10,22)
查询字段(strlist)中包含(str)的结果,返回结果为null或记录
如果str 在由N个子链组成的字符串列表strlist 中,则返回值的范围在1到N之间。
一个字符串列表就是一个由一些被","符号分开的子链组成的字符串。如果第一个参数是一个常数字符串, 而第二个是	type SET,则FIND_IN_SET函数被优化,使用比特计算。
如果str不在strlist或strlist为空字符串,则返回值为0。
如果任意一个参数为NULL,则返回值为NULL。这个函数在第一个参数包含一个逗号时将无法正常运行。

oracle 没有对应的函数,可以使用自己编写的函数

CREATE OR REPLACE FUNCTION FIND_IN_SET(piv_str1 varchar2, piv_str2 varchar2, p_sep varchar2 := ',')

RETURN NUMBER IS      

  l_idx    number:=0; -- 用于计算piv_str2中分隔符的位置  

  str      varchar2(500);  -- 根据分隔符截取的子字符串  

  piv_str  varchar2(500) := piv_str2; -- 将piv_str2赋值给piv_str  

  res      number:=0; -- 返回结果  

  loopIndex number:=0;

BEGIN  

-- 如果piv_str中没有分割符,直接判断piv_str1和piv_str是否相等,相等 res=1  

IF instr(piv_str, p_sep, 1) = 0 THEN  

   IF piv_str = piv_str1 THEN   

      res:= 1;  

   END IF;  

ELSE  

-- 循环按分隔符截取piv_str  

LOOP  

    l_idx := instr(piv_str,p_sep);  

     loopIndex:=loopIndex+1;

-- 当piv_str中还有分隔符时  

      IF l_idx > 0 THEN  



   -- 截取第一个分隔符前的字段str  

         str:= substr(piv_str,1,l_idx-1);  

   -- 判断 str 和piv_str1 是否相等,相等 res=1 并结束循环判断  

         IF str = piv_str1 THEN   

           res:= loopIndex;  

           EXIT;  

         END IF;  

        piv_str := substr(piv_str,l_idx+length(p_sep));  

      ELSE  

   -- 当截取后的piv_str 中不存在分割符时,判断piv_str和piv_str1是否相等,相等 res=1  

        IF piv_str = piv_str1 THEN   

           res:= loopIndex;  

        END IF;  

        -- 无论最后是否相等,都跳出循环  

        EXIT;  

      END IF;  

END LOOP;  

-- 结束循环  

END IF;  

-- 返回res  

RETURN res;  

END FIND_IN_SET;  

group_concat()–Oracle使用listagg()替换

例子

create table emp(
    emp_id int primary key auto_increment comment '编号',
    emp_name char(20) not null default '' comment '姓名',
    salary decimal(10,2) not null default 0 comment '工资',
    department char(20) not null default '' comment '部门'
);

insert into emp(emp_name,salary,department) 
values('张晶晶',5000,'财务部'),('王飞飞',5800,'财务部'),('赵刚',6200,'财务部'),('刘小贝',5700,'人事部'),('王大鹏',6700,'人事部'),('张小斐',5200,'人事部'),('刘云云',7500,'销售部'),('刘云鹏',7200,'销售部'),('刘云鹏',7800,'销售部');

select group_concat(emp_name) from emp;
//张晶晶,王飞飞,赵刚,刘小贝,王大鹏,张小斐,刘云云,刘云鹏,刘云鹏

select department,group_concat(emp_name) from emp group by department;
| 人事部     | 刘小贝,王大鹏,张小斐          
| 财务部     | 张晶晶,王飞飞,赵刚            
| 销售部     | 刘云云,刘云鹏,刘云鹏

group_concat( [DISTINCT] 要连接的字段 [Order BY 排序字段 ASC/DESC] [Separator ‘分隔符’] )1)使用distinct可以排除重复值;
(2)如果需要对结果中的值进行排序,可以使用order by子句;
(3)separator是一个字符串值,默认为逗号
-- 改前
JSON_UNQUOTE(JSON_EXTRACT(CONCAT('[',GROUP_CONCAT(CONCAT('"',case when
cs_cif_rating.MT_RATING_TYP_CD='CS_CRR' then cs_cif_rating.GRADE else null end,'"') ORDER BY cs_cif_rating.DT_CREATED DESC),']'),'$[0]')) GRADE

--改后
JSON_VALUE(CONCAT(CONCAT('[',(LISTAGG(case when
cs_cif_rating.MT_RATING_TYP_CD='CS_CRR' then cs_cif_rating.GRADE else null end,',') WITNIN GROUP(ORDER BY cs_cif_rating.DT_CREATED DESC))),']'),'$[0]') GRADE

未完待续…

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值