在SQL中搜索和子串

时间:2013-11-08 14:41:16

标签: sql substring ibm-midrange db2-400

我想在DB2 for i(以前称为iSeries或AS / 400)上使用SQL从字符串中提取值。

该字符串包含类似JSON的分隔键:值对列表。例如:

("EventType":"XYZ","EffectiveDate":20131000,"ClientNo":2012020860902)

给定一个键字符串,如“事件类型”,我想找到冒号(':')后的值,在这种情况下,它将是“XYZ”。但请记住,我的密钥字符串可能并不总是“事件类型”。

3 个答案:

答案 0 :(得分:0)

SELECT  SUBSTR( str,
                INSTR(str, ':') + 1,
                INSTR(str, ',') - INSTR(str, ':') - 1
              ) AS str_result
FROM
(
        SELECT  '("EventType":"XYZ","EffectiveDate":20131000,"ClientNo":2012020860902)' str
        FROM    sysibm.sysdummy1
)  t
;

答案 1 :(得分:0)

由于INSTR()不可用,因此无法在i上使用它。但是,可以使用POSSTR(),它可以在字符串中定位搜索字符串的位置。 LENGTH()函数可以给出搜索字符串的长度。这两个值一起基本上可以说明冒号的位置。

如果你知道冒号在哪里,可以确定下一个逗号的位置;并且表示要提取的子字符串的长度。

所需搜索字符串配对值的位置可能会使用:

POSSTR(str, 'EffectiveDate') +
  LENGTH('EffectiveDate') + 2 

“+ 2”让我们超过了 search-string 和冒号的结束语。我们处于配对价值的第一个角色。我们将这个表达式称为'exprA'。 (当然, search-string 本身可能是主变量而不是文字常量。)

使用exprA的值,我们可以从该位置开始提取并延伸到完整字符串的末尾。此时我们不需要知道配对值的长度。我们将简单地引用它来为我们找到下一个逗号提供良好的起点。该逗号将告诉我们配对值的长度。

SUBSTR( str, exprA )

我们称之为'exprB'。它将给出一个中间值,该值具有从最左侧位置开始的所需配对值。现在我们可以想到这样的事情:

POSSTR( exprB, ',' ) - 1

在我们提取的子字符串中找到第一个逗号。使用“ - 1”,它返回到配对值的结束字符并有效地提供其长度。我们称之为'exprC'。现在我们可以想到一些看起来像这样的代码:

SUBSTR( exprB ,
        1 ,
        exprC
      )

我们生成exprB以获得我们在位置1中具有所需配对值的初始子串,并且我们通过使用exprC来提供长度的子串。现在我们需要扩展我们的表达式并查看整个混乱:

SELECT   SUBSTR(
                 SUBSTR( str,
                         POSSTR(str, 'EffectiveDate') +
                           LENGTH('EffectiveDate') + 2
                       ) ,
                 1 ,
                 POSSTR( SUBSTR( str,
                                 POSSTR(str, 'EffectiveDate') +
                                   LENGTH('EffectiveDate') + 2
                               ),
                         ','
                       ) - 1
               )  AS str_result

现在需要的是SELECT可以选择FROM的东西。我们可以使用上面提供的短语:

FROM
(
        SELECT  '("EventType":"XYZ","EffectiveDate":20131000,"ClientNo":2012020860902)' str
        FROM    sysibm.sysdummy1
)  t
;

然而,仍然存在一个小问题。有三个示例值对。前两个将处理好,但任何系列中的最后一对都没有'exprC'的尾随逗号来定位; POSSTR()函数将返回零。它可以通过在混乱中添加一个丑陋的CASE结构来处理,但它已经看起来足够复杂了。最简单的可能是简化以确保存在尾随逗号。如果样本值有效,最简单的方法可能是:

REPLACE( '("EventType":"XYZ","EffectiveDate":20131000,"ClientNo":2012020860902)' , ')', ',' )

用逗号替换右边的paren,一切都应该有用。

但是,在我看来,通过一些相当简单的程序代码可以更好地完成这样的过程。创建一个外部函数并完成它。

答案 2 :(得分:0)

我的第二个动作是创建一个函数来进行键/值解析,所以你最终不会在这个地方找到代码。我不同意许多人认为所述功能必须以高级语言驻留在数据库之外的倾向。如果你创建一个SQL函数来执行键/值解析,最好是一个表函数,因为它们比标量函数更灵活,访问数据库的任何语言或请求者应用程序都可以访问该函数,并且对该表函数的引用甚至可以捆绑在将使用已解析值的同一SQL语句中。当然,对于那些需要一个并且不需要引用数据库的应用程序,也应该存在客户端键/值HLL解析器。