欢迎光临
我们一直在努力

mysql实现oracle的decode和translate以及管道符拼接

目前要把网站整体业务迁移到云,并且又现在的oracle转换成mysql数据库,实现去ioe,现在有个任务是把oracle的一个视图在mysql中创建上,相关的基表已经创建完毕,想当然觉得只要把oracle的创建语句有拿出来,在mysql执行就可以了,其实真正过程遇到了很多问题,具体如下:

1,mysql 没有oracle的decode函数,

2,mysql t没有oracle的translate函数,

3,mysql create view 不能有子查询 ( 视图 第1349号错误解决方法)ERROR 1349 (HY000): View’s SELECT contains a subquery in the FROM clause

我的解决办法是 视图中包含视图

4,mysql CONCAT_WS和CONCAT的区别

首先看一下oracle当前的视图创建sql:

create or replace view infoservice.mail_tasks as

select a.mid as member_id,a.dingyue_id as dingyue_id ,a.cust_email as cust_email,duration_days,

memberinfo.cust_right_group as level1,

‘{“member_name”:”‘|| TRANSLATE (memberinfo.CUST_NAME,”'”‘,’__’) ||'”,”keyword”:”‘||

TRANSLATE (a.keyword,”'”‘,’__’)||'”,”table_name2″:”‘||a.topicid||'”,

“area_id”:”‘||a.areaid||'”,”category_id”:”‘||a.industryid||'”}’ as query

from

(

select t.record_id as dingyue_id ,t.member_id as mid,t.cust_email as cust_email,

t.duration_days as duration_days,t.keyword as keyword,t.table_name,

t.industryid,

t.areaid,

decode( t.topicid , ‘,’ ,decode(t.table_name,’zbxx’,’,a,b,c,d,e,f,g,h,’,’xmxx’,’,i,j,k,’), t.topicid) as topicid

from infoservice.t_member_my t,infoservice.t_member_my_info i

where i.my_id=’1′

and t.member_id=i.member_id and t.sign = 0

and length(t.cust_email)>3

)

a ,infoservice.t_member_info memberinfo

where a.mid=memberinfo.record_id and memberinfo.cust_right_group != ‘0’ and memberinfo.cust_status=’正式’;

针对遇到的问题,来作出相应的调整:

1,mysql 没有oracle的decode函数:

oracle中的decode函数的用处:

decode(条件,值1,返回值1,值2,返回值2,…值n,返回值n,缺省值)

该函数的含义如下:

IF 条件=值1 THEN

    RETURN(翻译值1)

ELSIF 条件=值2 THEN

    RETURN(翻译值2)

    ……

ELSIF 条件=值n THEN

    RETURN(翻译值n)

ELSE

    RETURN(缺省值)

END IF

decode(字段或字段的运算,值1,值2,值3)

这个函数运行的结果是,当字段或字段的运算的值等于值1时,该函数返回值2,否则返回值3

当然值1,值2,值3也可以是表达式,这个函数使得某些sql语句简单了许多.

解决办法:

用case when 来替换:

把decode( t.topicid , ‘,’ ,decode(t.table_name,’zbxx’,’,a,b,c,d,e,f,g,h,’,’xmxx’,’,i,j,k,’), t.topicid) as topicid

替换成

CASE WHEN t.topicid=’,’ then (case when t.table_name=’zbxx’ then ‘,a,b,c,d,e,f,g,h,’ when t.table_name=’xmxx’ then ‘,i,j,k,’ end ) else t.topicid end as topicid

2.mysql 没有oracle的translate函数

首先oracle的translate函数的作用:

TRANSLATE(string,from_str,to_str)

返回将(所有出现的)from_str中的每个字符替换为to_str中的相应字符以后的string。TRANSLATE 是 REPLACE 所提供的功能的一个超集。如果 from_str 比 to_str 长,那么在 from_str 中而不在 to_str 中的额外字符将从 string 中被删除,因为它们没有相应的替换字符。to_str 不能为空。Oracle 将空字符串解释为 NULL,并且如果TRANSLATE 中的任何参数为NULL,那么结果也是 NULL。

注意:一定注意oracle的translate的函数是一一对应的替换,并且它针对的是单个字符,而且是把from_str里面出现的字符全部都对应着换掉(要么换成to_str中对应的字符,要没有对应的就直接去掉),要区别于replace,replace针对的是字符串,必须要全部对应上,才能整体把from_str替换成to_str。

oracle TRANSLATE实例:

语法:TRANSLATE(expr,from,to)

expr: 代表一串字符,from 与 to 是从左到右一一对应的关系,如果不能对应,则视为空值。

举例:

SQL> select translate(‘abcbbaadef’,’ba’,’#@’) from dual; (b将被#替代,a将被@替代)

TRANSLATE(

———-

@#c##@@def 

SQL> select translate(‘abcbbaadef’,’bad’,’#@’) from dual; (b将被#替代,a将被@替代,d对应的值是空值,将被移走)

TRANSLATE

———

@#c##@@ef 

oracle replace实例:

SQL> select replace(‘abcbbaadef’,’ba’,’#@’) from dual; 将出现的整体ba替换成了#@

REPLACE(‘A

———-

abcb#@adef

SQL> select replace(‘abcbbaadef’,’bad’,’#@’) from dual; ##没有完全匹配上的的bad,就没有替换

REPLACE(‘A

———-

abcbbaadef

针对mysql 没有oracle的translate函数的解决办法:

将TRANSLATE (memberinfo.CUST_NAME,”'”‘,’__’)替换成replace(replace(memberinfo.CUST_NAME,””,’_’),'”‘,’_’),也就是先用replace替换单引号‘,然后在用个replace替换双引号“,(注意在sql中两个单引代表一个单引号)。

3,mysql create view 不能有子查询,否则报错ERROR 1349 (HY000): View’s SELECT contains a subquery in the FROM clause

解决办法:把相关子查询提前创建成一个视图,如下所示:

创建云上的视图:

create or replace view info.mail_tasks as

select a.mid as member_id,a.dingyue_id as dingyue_id ,a.cust_email as cust_email,duration_days,

memberinfo.cust_right_group as level1,

CONCAT_WS(”,'{“member_name”:”‘,replace(replace(memberinfo.CUST_NAME,””,’_’),'”‘,’_’),'”,”keyword”:”‘,replace(replace(a.keyword,””,’_’),'”‘,’_’),'”,”table_name2″:”‘,a.topicid,'”,”area_id”:”‘,a.areaid,'”,”category_id”:”‘,a.industryid,'”}’) as query

from info.mail_task_test

a ,info.v_member_info memberinfo

where a.mid=memberinfo.id and memberinfo.cust_right_group != ‘0’ and memberinfo.cust_status=’正式’;

创建云上的子视图:

create view mail_task_test as

select t.record_id as dingyue_id ,t.member_id as mid,t.cust_email as cust_email,

t.duration_days as duration_days,t.keyword as keyword,t.table_name,

t.industryid,

t.areaid,

CASE WHEN t.topicid=’,’ then (case when t.table_name=’zbxx’ then ‘,a,b,c,d,e,f,g,h,’ when t.table_name=’xmxx’ then ‘,i,j,k,’ end ) else t.topicid end as topicid

from info.v_member_my t,info.v_member_my_info i

where i.my_id=’1′

and t.member_id=i.member_id and t.sign = 0

and length(t.cust_email)>3

)

4.最后总结下mysql 中CONCAT_WS和CONCAT的区别:

因为mysql中不能像oracle那样使用管道符||在sql中拼接字符串,但是可以使用CONCAT或者CONCAT_WS函数来实现拼接的目的。

MySQL字符串处理函数concat_ws()和MySQL字符串处理函数concat()类似,但是处理的字符串不太一样,concat_ws()函数, 表示concat with separator,即有分隔符的字符串连接 ,当然分隔符为空的情况就更类似于concat()。

1)如连接后以逗号分隔

MariaDB [(none)]> select concat_ws(‘,’,’11’,’he2′,’liu’);

+———————————+

| concat_ws(‘,’,’11’,’he2′,’liu’) |

+———————————+

| 11,he2,liu |

+———————————+

2)连接后以空分割,可以理解为没有分隔。非常类似于concat()

MariaDB [(none)]> select concat_ws(”,’11’,’he2′,’liu’);

+——————————–+

| concat_ws(”,’11’,’he2′,’liu’) |

+——————————–+

| 11he2liu |

+——————————–+

MariaDB [(none)]> select concat(”,’11’,’he2′,’liu’);

+—————————–+

| concat(”,’11’,’he2′,’liu’) |

+—————————–+

| 11he2liu |

+—————————–+

1 row in set (0.00 sec)

3)concat_ws()和concat()不同的是, concat_ws()函数在执行的时候,不会因为NULL值而返回NULL.

MariaDB [(none)]> select concat_ws(‘,’,’11’,’22’,NULL);

+——————————-+

| concat_ws(‘,’,’11’,’22’,NULL) |

+——————————-+

| 11,22 |

+——————————-+

1 row in set (0.00 sec)

MariaDB [(none)]> select concat_ws(”,’11’,’22’,NULL);

+——————————+

| concat_ws(”,’11’,’22’,NULL) |

+——————————+

| 1122 |

+——————————+

1 row in set (0.00 sec)

MariaDB [(none)]> select concat(’11’,’22’,NULL);

+————————+

| concat(’11’,’22’,NULL) |

+————————+

| NULL |

+————————+

1 row in set (0.00 sec)

oracle和mysql还是有很多不一样的地方,去ioe的过程还是很艰难的。

赞(0)
【声明】:本博客不参与任何交易,也非中介,仅记录个人感兴趣的主机测评结果和优惠活动,内容均不作直接、间接、法定、约定的保证。访问本博客请务必遵守有关互联网的相关法律、规定与规则。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。