【问题标题】:Oracle INSTR replacement in SQLiteSQLite 中的 Oracle INSTR 替换
【发布时间】:2019-10-12 19:31:24
【问题描述】:

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

INSTR(, , )

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

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

如果 为正:

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

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

LENGTH() - LENGTH(REPLACE(, RTRIM(, REPLACE(, , '')), ''))

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

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

【问题讨论】:

    标签: sql oracle sqlite


    【解决方案1】:

    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 次的字符组成的字符串的创建取自 this simplified answer

    【讨论】:

    • 不太确定否定位置建议是否是对我当前方法的改进,仍然使用大量嵌套并且维护起来也不那么优雅。但是在阅读了这篇文章并进行了一些额外的研究之后,似乎没有办法解决这个问题,这将是我们必须忍受的事情。
    • 对我来说,问题中描述的方法不适用于负值,除非找到的字符串是在字符串的其余部分中找不到的字符 - 请参阅最后的 OP_instr 值在this fiddle.
    【解决方案2】:

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

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

    所以,作为一个例子,Oracle 的调用:

    INSTR('catsondogsonhats', 'on', 7)
    

    将返回11,将变为:

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

    【讨论】:

    • 谢谢,我知道带有 2 个参数的 INSTR,但没有考虑在此构造中使用它。您的建议似乎适用于正位置参数,并且与我的方法相比已经简单多了。不过,恐怕负面立场并不那么微不足道。
    猜你喜欢
    • 2015-01-22
    • 2013-03-10
    • 2021-06-17
    • 2017-05-13
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    相关资源
    最近更新 更多