【问题标题】:Translate Oracle Regular Expression Query to MSSQL将 Oracle 正则表达式查询转换为 MSSQL
【发布时间】:2019-06-25 10:55:49
【问题描述】:

您好,我需要将此查询从 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.

例子:

这不应该匹配:

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

【问题讨论】:

  • SQL Server 并没有真正的正则表达式支持。您能否提供一些数据示例,说明哪些匹配,哪些不匹配?
  • 这里不应该匹配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
  • 照原样,熟悉Oracle正则表达式和SQL Server的T-SQL的人都可以回答您的问题。为了改进您的更改以尽快获得好的答案,我会忘记 Oracle 部分,而是专注于 SQL Server 部分。作为 DDL+DML(创建表和插入语句)的示例数据和预期结果应该可以很快为您提供准确的答案。
  • @ZoharPeled 我想使用 BI 工具运行这个查询,所以我需要避免 DDL+DML
  • 样本数据的 DDL+DML 不适合您,我们可以将其复制并粘贴到测试环境中,以便我们可以运行我们提出的任何查询并确保它产生所需的结果在发布答案之前。

标签: sql-server regex oracle regexp-like


【解决方案1】:

我个人会使用字符串拆分函数来解决这个问题,该函数在逗号分隔的字符串之一中查找适当的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 |
+----+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

【讨论】:

    猜你喜欢
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 2011-10-02
    • 2016-04-02
    • 1970-01-01
    • 2019-05-11
    相关资源
    最近更新 更多