SQLite中的Oracle INSTR替换

时间:2019-05-27 08:33:35

标签: sql oracle sqlite

我目前正在将应用程序的一部分从Oracle移植到SQLite后端(Java,使用纯JDBC)。经常使用的一种Oracle特定功能是具有3个参数的INSTR函数:

  

INSTR(<字符串>,<搜索字符串>,<位置>)

此函数在字符串中搜索从特定位置开始的搜索字符串。第三个参数可以是正数或负数。如果为负,则从字符串的末尾开始向后搜索。

此功能在SQLite中不可用,我能想到的最好的方法是嵌套其他一些功能:

如果是肯定的:

  

LENGTH()-LENGTH(SUBSTR(SUBSTR(,   ),STRPOS(SUBSTR(),   )+1))

如果为负(在我们的示例中,-1是唯一使用的负值):

  

LENGTH()-LENGTH(REPLACE(,   RTRIM(<字符串>,REPLACE(<字符串>,<搜索字符串>,   '')),''))

这似乎给出了预期的结果,但是您可以看到为什么我并不真正赞成这种方法。当然,因为在原始语法中,INSTR经常使用并且也被嵌套。此后将成为维护的灾难。

是否有人对更优雅的方法有其他建议,或者我可能会因为看起来很琐碎的任务而缺少其他本机解决方案?任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:3)

实际上,SQLite 确实支持INSTR函数。但是,它没有第三个参数,这意味着它总是从字符串的开头开始搜索。

但是,我们可以通过以下方式解决此问题:将子字符串传递到INSTR,然后通过添加子字符串的偏移量来偏移找到的位置。

因此,例如,Oracle的电话:

INSTR('catsondogsonhats', 'on', 7)
将返回11

变为:

INSTR(SUBSTR('catsondogsonhats', 7), 'on') + 6

答案 1 :(得分:0)

SQL

   CASE WHEN position = 0
        THEN INSTR(string, substring)
        WHEN position > 0
        THEN INSTR(SUBSTR(string, position), substring) + position - 1
        WHEN position < 0
        THEN LENGTH(RTRIM(REPLACE(string,
                                  substring,
                                  REPLACE(HEX(ZEROBLOB(LENGTH(substring))),
                                          '00',
                                          '¬')),
                          string)) - LENGTH(substring) + 1
   END

它假设¬字符不会成为搜索字符串的一部分(但是在极少数情况下,这种假设为假,当然可以更改为另一个很少使用的字符)。

SQLFiddle演示

此处提供了一些可行的示例:http://sqlfiddle.com/#!5/7e40f9/5

积分

  1. 积极的position方法改编自Tim Biegeleisen的回答。 (但是零值需要单独处理)。
  2. 否定的position方法以该问题中描述的方法为起点。
  3. this simplified answer中提取了一个由重复 n 次字符组成的字符串。