我想在Oracle 11g数据库中转换包含SQL select中日期的字符串。
原始字符串(CLOB)示例:
"1.12.2011 - event 1
2.2.2012 - event 2
13.3.2012 - event 44"
期望的输出:
"20111201 - event 1
20120202 - event 2
20120313 - event 44"
是否有比使用4个单独替换更好(更快)的方式?
regexp_replace(regexp_replace(regexp_replace(regexp_replace(my_string,
'(\d\d)\.(\d\d)\.(20\d\d)', '\3\2\1'),
'(\d\d)\.(\d)\.(20\d\d)', '\30\2\1'),
'(\d)\.(\d\d)\.(20\d\d)', '\3\20\1'),
'(\d)\.(\d)\.(20\d\d)', '\30\20\1')
答案 0 :(得分:1)
特别是如果你使用clobs,你必须要小心,除非你确定那里有数据。
但是,如果你的clob只是那样,那么你需要三个regexp_replace
才能使它工作;它也会更有活力。只需使用[[:digit:]]
明确指定数字,然后使用{1,2}
指定这些数字的最小和最大次数。
然后以下内容将起作用:
select regexp_replace(
regexp_replace(
regexp_replace( my_string
, '([[:digit:]]{1,2})\.([[:digit:]]{1,2})\.(20[[:digit:]]{2})'
, '\3-\2-\1')
, '-([[:digit:]]{1}(-|$))'
, '0\1' )
, ('-')
, '')
from dual
这意味着:
然后只取出第1,2和3组,即忽略完整停止并按顺序返回3,2,1用连字符填充
然后替换后跟连字符或字符串结尾的任何[digit]
,即-0[digit]
的位数仅为1。
最后替换所有连字符。
另外,我同意tbone。将这些数据存储在单独的表(event_id number, event_date date)
中会更有意义。任何字符串转换都很容易,不会出错,不像在这种情况下,数据很容易查询和比较。
答案 1 :(得分:0)
没有更好的选择(正确和可读)具有更好的性能 - 或者如果有,没有人关心..
答案 2 :(得分:0)
我更喜欢日期部分的2级regexp_replace:
select regexp_replace(
regexp_replace( my_string,
'([[:digit:]]{1,2})\.([[:digit:]]{1,2})\.(20[[:digit:]]{2})',
'\3-0\2-0\1' ),
'(20[[:digit:]]{2})-0?([[:digit:]]{2})-0?([[:digit:]]{2})',
'\3\2\1' )
from dual;
答案 3 :(得分:-1)
也许尝试做:
select to_char(to_date('13.3.2011', 'DD.MM.YYYY'),'YYYYMMDD') from dual;