如何根据特定模式从oracle中的varchar获取子字符串值

时间:2018-05-25 11:06:54

标签: sql oracle

我有一个列具有以下特定格式的记录: -

ParamName1+ParamVal1;ParamName2+ParamVal2;ParamName3+ParamVal3;

目前我正在使用下面的查询逻辑,但是这个逻辑也带来了搜索ParamName的部分匹配的值: -

TRIM(REGEXP_REPLACE(REGEXP_SUBSTR(TO_CHAR(ITEM_ATRS_LIST),'ID\+[^;]*'),'ID\+',''))

例如,如果我有值EmpID+1234;Name+ABCD;Age+21; 使用查询

TRIM(REGEXP_REPLACE(REGEXP_SUBSTR(TO_CHAR(ITEM_ATRS_LIST), 'ID\+[^;]*'),'ID\ + ',''))

给出了值1234但我们想要NULL,因为ParamName ID不存在。

我们有没有办法带来与搜索paramName完全匹配的价值?

2 个答案:

答案 0 :(得分:1)

您正在寻找属性的值,例如“EmpID'”。这就是我提出的:

regexp_replace( regexp_substr(item_atrs_list, 
                              '(^|;)EmpID\+.*?(;|$)'
                             ),
                '^.*?\+(.*?)\;?$',
                '\1'
              )

(^|;)EmpID\+.*?(;|$)'的解释:

  • (^|;)字符串的开头或字符串
  • 中的分号
  • EmpID后跟EmpID
  • \+后跟加号
  • .*?(;|$)'可能后跟一些字符(值),最后是分号或点击字符串的结尾

'^.*?\+(.*?)\;?$'的解释:

  • ^字符串的开头
  • ^.*?\+可能后跟一些字符,然后加号(即&#39 ;; EmpID +'或' EmpID +')
  • (.*?)\;?$'可能后跟一些我们记忆的字符(值),然后可能是分号,然后是字符串的结尾

\1的解释:

  • 我们记住的第一个(也是唯一的)字符串,即值

(我对正则表达式不太好。可能有一种更容易实现的方法。如上所述,我宁愿使用PL / SQL等编程语言。)

答案 1 :(得分:1)

这是使用公用表格表达式(CTE)处理它的另一种方法。第一个'tbl',只是为原始数据设置了一个源。 'params'创建一个名称 - 值对表,使用connect by循环并在分号的分隔符上进行分割,然后再按加号进行循环。然后,只需从那里选择您的名字匹配。

-- Original data
with tbl(data) as (
  select 'EmpID+1234;Name+ABCD;Age+21;' from dual
),
-- make a table of name-value pairs
params(name, value) as (
  select regexp_substr(data, '(^|;)(.*?)\+', 1, level, NULL, 2),
         regexp_substr(data, '\+(.*?)(;|$)', 1, level, NULL, 1)
  from tbl
  connect by level <= regexp_count(data, ';')
)
--select * from params;
-- Get the value for the name
select name, value
from params
where name = 'EmpID';