Перевести запрос регулярных выражений Oracle на MSSQL - PullRequest
0 голосов
/ 25 июня 2019

Здравствуйте! Мне нужно перевести этот запрос из базы данных Oracle в MSSQL и получить точно такой же результат:

WHEN REGEXP_LIKE(E.EVENTS, 'selfServe:[^:]*:completed[:]').

Все мои следующие попытки потерпели неудачу:

WHEN EVENTS LIKE '%[:]selfServe[:][^:]%[:]completed[:]%'

EVENTS LIKE '%[:]selfServe[:]%[^:][:]completed[:]%'

WHERE PATINDEX('selfServe:[^:]*:completed[:]', EVENTS) != 0

WHERE PATINDEX('selfServe:[^:]%:completed[:]', EVENTS) != 0.

Примеры:

Это не должноmatch:

OpenQ,
Payment,
Payment:selfServe:Payment-Cancel_Scheduled:initiated::,
Payment:authentication:Authentication:initiated::,
Payment:authentication:Authentication:completed::,
HUP

Пока это должно совпадать:

OpenQ2,
Payment,
Payment:selfServe:Payment:initiated::,
Payment:authentication:Authentication:initiated::,
Payment:authentication:Authentication:initiated::,
Payment:authentication:Authentication:completed::,
Payment:selfServe:Payment:completed::,
HUP

В первом случае у меня есть authentication:completed, но нет selfServe:Payment:completed.

1 Ответ

0 голосов
/ 25 июня 2019

Лично я бы справился с этим с помощью функции разделения строк, которая ищет соответствующие selfServe:...:completed в одной из строк, разделенных запятыми. Если вы используете довольно современную версию SQL Server, вы можете сделать это, используя встроенную функцию string_split:

string_split

declare @t table(id int,t varchar(1000));
insert into @t values
 (1,'OpenQ,Payment,Payment:selfServe:Payment-Cancel_Scheduled:initiated::,Payment:authentication:Authentication:initiated::,Payment:authentication:Authentication:completed::,HUP')
,(2,'OpenQ2,Payment,Payment:selfServe:Payment:initiated::,Payment:authentication:Authentication:initiated::,Payment:authentication:Authentication:initiated::,Payment:authentication:Authentication:completed::,Payment:selfServe:Payment:completed::,HUP');


select t.id
      ,s.value
      ,t.t
from @t as t
    cross apply string_split(t.t,',') as s
where case when patindex('%:selfServe:%',s.value) > 0
                and patindex('%:completed:%',s.value) > 0
            then 1
            else 0
            end = 1;

выход

+----+---------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id |                 value                 |                                                                                                                          t                                                                                                                           |
+----+---------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  2 | Payment:selfServe:Payment:completed:: | OpenQ2,Payment,Payment:selfServe:Payment:initiated::,Payment:authentication:Authentication:initiated::,Payment:authentication:Authentication:initiated::,Payment:authentication:Authentication:completed::,Payment:selfServe:Payment:completed::,HUP |
+----+---------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Если нет, вам нужно будет запустить свой собственный разделитель строк. Я предполагаю, что у вас могут быть довольно длинные строки (более 4000 символов), и поэтому я использую сплиттер на основе XML, который хорошо работает с max типами данных.

Поскольку вы делаете это с помощью инструмента BI, который, как я предполагаю, не позволит вам создать новую табличную функцию в базе данных, вам потребуется довольно сложный оператор для обработки ваших данных, который включает встроенный разделитель строк:

Раскатайся

declare @t table(id int,t varchar(1000));
insert into @t values
 (1,'OpenQ,Payment,Payment:selfServe:Payment-Cancel_Scheduled:initiated::,Payment:authentication:Authentication:initiated::,Payment:authentication:Authentication:completed::,HUP')
,(2,'OpenQ2,Payment,Payment:selfServe:Payment:initiated::,Payment:authentication:Authentication:initiated::,Payment:authentication:Authentication:initiated::,Payment:authentication:Authentication:completed::,Payment:selfServe:Payment:completed::,HUP');

with s as
(       -- Convert the string to an XML value, replacing the delimiter with XML tags
    select id
          ,t
          ,convert(xml,'<x>' + replace((select '' + t for xml path('')),',','</x><x>') + '</x>').query('.') as s
    from @t
)
select id
        ,item
        ,t     -- Select the values from the generated XML value by CROSS APPLYing to the XML nodes
from(select id
            ,t
            ,n.x.value('.','nvarchar(max)') as item
    from s
            cross apply s.nodes('x') as n(x)
    ) a
where case when patindex('%:selfServe:%',a.item) > 0
                and patindex('%:completed:%',a.item) > 0
            then 1
            else 0
            end = 1;

выход

+----+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id |                  item                   |                                                                                                                          t                                                                                                                           |
+----+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  2 |   Payment:selfServe:Payment:completed:: | OpenQ2,Payment,Payment:selfServe:Payment:initiated::,Payment:authentication:Authentication:initiated::,Payment:authentication:Authentication:initiated::,Payment:authentication:Authentication:completed::,Payment:selfServe:Payment:completed::,HUP |
+----+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...