目前要把網(wǎng)站整體業(yè)務(wù)遷移到云,并且又現(xiàn)在的oracle轉(zhuǎn)換成MySQL數(shù)據(jù)庫,實(shí)現(xiàn)去ioe,現(xiàn)在有個(gè)任務(wù)是把oracle的一個(gè)視圖在mysql中創(chuàng)建上,相關(guān)的基表已經(jīng)創(chuàng)建完畢,想當(dāng)然覺得只要把oracle的創(chuàng)建語句有拿出來,在mysql執(zhí)行就可以了,其實(shí)真正過程遇到了很多問題,具體如下:
1,mysql 沒有oracle的decode函數(shù),
2,mysql t沒有oracle的translate函數(shù),
3,mysql create view 不能有子查詢 ( 視圖 第1349號(hào)錯(cuò)誤解決方法)ERROR 1349 (HY000): View's SELECT contains a subquery in the FROM clause
我的解決辦法是 視圖中包含視圖
4,mysql CONCAT_WS和CONCAT的區(qū)別
首先看一下oracle當(dāng)前的視圖創(chuàng)建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='正式';
針對(duì)遇到的問題,來作出相應(yīng)的調(diào)整:
1,mysql 沒有oracle的decode函數(shù):
oracle中的decode函數(shù)的用處:
decode(條件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值)
該函數(shù)的含義如下:
IF 條件=值1 THEN
RETURN(翻譯值1)
ELSIF 條件=值2 THEN
RETURN(翻譯值2)
......
ELSIF 條件=值n THEN
RETURN(翻譯值n)
ELSE
RETURN(缺省值)
END IF
decode(字段或字段的運(yùn)算,值1,值2,值3)
這個(gè)函數(shù)運(yùn)行的結(jié)果是,當(dāng)字段或字段的運(yùn)算的值等于值1時(shí),該函數(shù)返回值2,否則返回值3
當(dāng)然值1,值2,值3也可以是表達(dá)式,這個(gè)函數(shù)使得某些sql語句簡(jiǎn)單了許多.
解決辦法:
用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函數(shù)
首先oracle的translate函數(shù)的作用:
TRANSLATE(string,from_str,to_str)
返回將(所有出現(xiàn)的)from_str中的每個(gè)字符替換為to_str中的相應(yīng)字符以后的string。TRANSLATE 是 REPLACE 所提供的功能的一個(gè)超集。如果 from_str 比 to_str 長(zhǎng),那么在 from_str 中而不在 to_str 中的額外字符將從 string 中被刪除,因?yàn)樗鼈儧]有相應(yīng)的替換字符。to_str 不能為空。Oracle 將空字符串解釋為 NULL,并且如果TRANSLATE 中的任何參數(shù)為NULL,那么結(jié)果也是 NULL。
注意:一定注意oracle的translate的函數(shù)是一一對(duì)應(yīng)的替換,并且它針對(duì)的是單個(gè)字符,而且是把from_str里面出現(xiàn)的字符全部都對(duì)應(yīng)著換掉(要么換成to_str中對(duì)應(yīng)的字符,要沒有對(duì)應(yīng)的就直接去掉),要區(qū)別于replace,replace針對(duì)的是字符串,必須要全部對(duì)應(yīng)上,才能整體把from_str替換成to_str。
oracle TRANSLATE實(shí)例:
語法:TRANSLATE(expr,from,to)
expr: 代表一串字符,from 與 to 是從左到右一一對(duì)應(yīng)的關(guān)系,如果不能對(duì)應(yīng),則視為空值。
舉例:
SQL> select translate('abcbbaadef','ba','#@') from dual; (b將被#替代,a將被@替代)
TRANSLATE(
----------
@#c##@@def
SQL> select translate('abcbbaadef','bad','#@') from dual; (b將被#替代,a將被@替代,d對(duì)應(yīng)的值是空值,將被移走)
TRANSLATE
---------
@#c##@@ef
oracle replace實(shí)例:
SQL> select replace('abcbbaadef','ba','#@') from dual; 將出現(xiàn)的整體ba替換成了#@
REPLACE('A
----------
abcb#@adef
SQL> select replace('abcbbaadef','bad','#@') from dual; ##沒有完全匹配上的的bad,就沒有替換
REPLACE('A
----------
abcbbaadef
針對(duì)mysql 沒有oracle的translate函數(shù)的解決辦法:
將TRANSLATE (memberinfo.CUST_NAME,'''"','__')替換成replace(replace(memberinfo.CUST_NAME,'''','_'),'"','_'),也就是先用replace替換單引號(hào)‘,然后在用個(gè)replace替換雙引號(hào)“,(注意在sql中兩個(gè)單引代表一個(gè)單引號(hào))。
3,mysql create view 不能有子查詢,否則報(bào)錯(cuò)ERROR 1349 (HY000): View's SELECT contains a subquery in the FROM clause
解決辦法:把相關(guān)子查詢提前創(chuàng)建成一個(gè)視圖,如下所示:
創(chuàng)建云上的視圖:
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='正式';
創(chuàng)建云上的子視圖:
create view mail_task_testas
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.最后總結(jié)下mysql 中CONCAT_WS和CONCAT的區(qū)別:
因?yàn)閙ysql中不能像oracle那樣使用管道符||在sql中拼接字符串,但是可以使用CONCAT或者CONCAT_WS函數(shù)來實(shí)現(xiàn)拼接的目的。
MySQL字符串處理函數(shù)concat_ws()和MySQL字符串處理函數(shù)concat()類似,但是處理的字符串不太一樣,concat_ws()函數(shù), 表示concat with separator,即有分隔符的字符串連接 ,當(dāng)然分隔符為空的情況就更類似于concat()。
1)如連接后以逗號(hào)分隔
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()函數(shù)在執(zhí)行的時(shí)候,不會(huì)因?yàn)镹ULL值而返回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的過程還是很艱難的。
網(wǎng)頁題目:mysql實(shí)現(xiàn)oracle的decode和translate以及管道符拼接
本文鏈接:
http://weahome.cn/article/gpppgs.html