首页 > 解决方案 > SQLite 中的 Oracle INSTR 替换

问题描述

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

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

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

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

如果 <position> 为正:

LENGTH(<string>) - LENGTH(SUBSTR(SUBSTR(<string>, <position>), STRPOS(SUBSTR(<string>, <position>), <search-string>) + 1))

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

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

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

是否有更优雅的方法,或者我是否会错过一些其他本机解决方案来完成似乎相当微不足道的任务?

标签: sqloraclesqlite

解决方案


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方法改编自蒂姆·比格莱森的回答。(但零值需要单独处理)。
  2. 否定position法以本题所描述的方法为出发点。
  3. 由重复n次的字符组成的字符串的创建取自这个简化的答案

推荐阅读