Подстановка формата даты в PL / SQL. Пример: от 5й 6м 20д до 050620 - PullRequest
0 голосов
/ 03 апреля 2019

Я пишу запрос, в котором мне нужно выполнить преобразование формата даты для соответствия указанным требованиям.В базе данных, которую я должен посмотреть, формат даты выглядит как в примере: 5y 6m 10d с пробелами между ними и необязательными цифрами (10y 30d; 1m 23d; 6m также действительны), и они всегда упорядочены (первые годы, затем месяц, а затем дни).

Преобразование формата должно быть следующим:

  • 10y 6m 10d => 100610
  • 1y 10m 1d => 011001
  • 6m 2d => 000602

Чтобы вывод всегда представлял собой 6-значное число.

Я попытался написать регулярные выражения в REGEX_SUBSTR, чтобы изолировать токены, а затемобъединить их вместе в типе SELECT REGEXP_SUBSTR(text_source, '(\d+)*y') FROM database, и я также попытался использовать функцию REGEX_REPLACE.Тем не менее, я не могу выполнить преобразование до двух цифр на каждый токен без пробелов и заменить один шаблон другим, я могу только заменить шаблон на другую строку.

Хотя я могу вывести разделение токеновбез пробелов, написав функцию выше.Я не могу получить всю трансформацию.Есть ли возможность написать RegEx и объединить его с любой из функций PL / SQL, чтобы преобразовать даты, указанные в списке выше?Я также открыт, чтобы услышать любые другие решения, не связанные с RegEx, я просто подумал, что было бы разумно правильно их использовать здесь.

Большое спасибо.

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019

Вот простое решение в SQL.

  • вы получаете значения для года, месяца и дня, например, с помощью regexp_substr.
  • с помощью nvl вы устанавливаете значениедо 0, если там это ноль.
  • lpad это с 0
with tab as(
  select '10y 6m 10d' as str from dual union all
  select '1y 10m 1d ' as str from dual union all
  select '6m 2d ' as str from dual 

)
select lpad(nvl(y,0), 2,'0') ||lpad(nvl(m,0), 2,'0')|| lpad(nvl(d,0), 2,'0')
  from (
     select rtrim(regexp_substr(str, '[0-9]{1,2}y', 1),'y')  as y
           ,rtrim(regexp_substr(str, '[0-9]{1,2}m', 1),'m')  as m
           ,rtrim(regexp_substr(str, '[0-9]{1,2}d', 1),'d')  as d
      from tab
     )
;

LPAD(N
------
100610
011001
000602
0 голосов
/ 03 апреля 2019

Я надеюсь, что это работает

declare
  myDate_ varchar2(50) := REPLACE('1y 10m 81d',' ','');
  year_ varchar2(50);
  month_ varchar2(50);
  day_ varchar2(50);
begin
       if instrb(myDate_,'y',1,1)>0 then
          year_ := lpad(regexp_substr(substr(myDate_,0,instrb(myDate_,'y',1,1)), '[^y]+',1 , 1),2,0);
       end if;
       if instrb(myDate_,'m',1,1)>0 then
          month_ := lpad(regexp_substr(substr(myDate_,instrb(myDate_,'y',1,1)+1,instrb(myDate_,'m',1,1)), '[^m]+',1 , 1),2,0);
       end if;
        if instrb(myDate_,'d',1,1)>0 then
          day_ := lpad(regexp_substr(substr(myDate_,instrb(myDate_,'m',1,1)+1,instrb(myDate_,'d',1,1)), '[^d]+',1 , 1),2,0);
       end if;
       dbms_output.put_line(year_||month_||day_);
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...