SQL更改日期格式在字符串中

时间:2012-02-21 15:36:39

标签: sql regex string oracle date

我想在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')

4 个答案:

答案 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) 1或2位数
  • 匹配一个句号。
  • 匹配(第2组) 1或2位数
  • 匹配句号
  • 匹配(第3组) 20 + 2位数。

然后只取出第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;

Demo

答案 3 :(得分:-1)

也许尝试做:

select to_char(to_date('13.3.2011', 'DD.MM.YYYY'),'YYYYMMDD') from dual;