我目前正在将应用程序的一部分从Oracle移植到SQLite后端(Java,使用纯JDBC)。经常使用的一种Oracle特定功能是具有3个参数的INSTR函数:
INSTR(<字符串>,<搜索字符串>,<位置>)
此函数在字符串中搜索从特定位置开始的搜索字符串。第三个参数可以是正数或负数。如果为负,则从字符串的末尾开始向后搜索。
此功能在SQLite中不可用,我能想到的最好的方法是嵌套其他一些功能:
如果
LENGTH(
)-LENGTH(SUBSTR(SUBSTR( , ),STRPOS(SUBSTR( , ), )+1))
如果
LENGTH(
)-LENGTH(REPLACE( , RTRIM(<字符串>,REPLACE(<字符串>,<搜索字符串>, '')),''))
这似乎给出了预期的结果,但是您可以看到为什么我并不真正赞成这种方法。当然,因为在原始语法中,INSTR经常使用并且也被嵌套。此后将成为维护的灾难。
是否有人对更优雅的方法有其他建议,或者我可能会因为看起来很琐碎的任务而缺少其他本机解决方案?任何帮助表示赞赏。
答案 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
积分
position
方法改编自Tim Biegeleisen的回答。 (但是零值需要单独处理)。position
方法以该问题中描述的方法为起点。