SQLite中的Oracle INSTR替换

The*_*bit 13 sql sqlite oracle

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

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

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

该功能在SQLite中不可用,而我能想到的最好的方法是通过嵌套其他一些功能来实现:

如果<position>为正:

LENGTH(<字符串>)-LENGTH(SUBSTR(SUBSTR(<字符串>,<位置>),STRPOS(SUBSTR(<字符串>,<位置>),<搜索字符串>)+ 1))

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

LENGTH(<string>)-LENGTH(REPLACE(<string>,RTRIM(<string>,REPLACE(<string>,<search-string>,'')),''))

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

是否有一种更优雅的方法,或者我可能缺少一些看似微不足道的任务的其他本机解决方案?

Ste*_*ers 6

的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
Run Code Online (Sandbox Code Playgroud)

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

SQLFiddle演示

一些可行的示例在这里:http : //sqlfiddle.com/#!5/7e40f9/5

学分

  1. 积极的position方法改编自蒂姆·比格莱森(Tim Biegeleisen)的答案。(但是零值需要单独处理)。
  2. 否定position方法以该问题中描述的方法为起点。
  3. 这个简化的答案中得出了一个字符串,该字符串由重复n次的字符组成。


Tim*_*sen 5

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

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

因此,例如,Oracle的电话:

INSTR('catsondogsonhats', 'on', 7)
Run Code Online (Sandbox Code Playgroud)

将返回11,将变为:

INSTR(SUBSTR('catsondogsonhats', 7), 'on') + 6
Run Code Online (Sandbox Code Playgroud)