Sql 从字符串中检索数字是最有效的方法

Sql 从字符串中检索数字是最有效的方法,sql,oracle,Sql,Oracle,我想知道是否有更好、更优化的方法从字符串中检索数字 例如 作为输出,我只想得到数字: 006 0109 0110 我知道如何使用instr、substr、replace函数来实现它。但是读起来很糟糕。我在寻找其他解决方案,有什么提示吗 谢谢您可以使用regexp\u subtr: 然后删除多余的字符: select replace(replace(regexp_substr(val, '/[0-9]+_', 1, 1), '/', ''), '_', '') 这只是第二个下划线之前的第三个斜

我想知道是否有更好、更优化的方法从字符串中检索数字 例如

作为输出,我只想得到数字:

006
0109
0110
我知道如何使用instr、substr、replace函数来实现它。但是读起来很糟糕。我在寻找其他解决方案,有什么提示吗

谢谢

您可以使用regexp\u subtr:

然后删除多余的字符:

select replace(replace(regexp_substr(val, '/[0-9]+_', 1, 1), '/', ''), '_', '')

这只是第二个下划线之前的第三个斜杠后面的部分:

substr(str, instr(str, '/', 1, 3) + 1, instr(str, '_', 1, 2) - instr(str, '/', 1, 3) - 1)

假设您需要的数字总是在最后一个斜杠/和最后一个下划线之间,并且中间没有字符-就像在示例中一样-最好的解决方案只使用substr和instr。请注意,正则表达式比直接substr和instr慢;有些情况下,唯一的解决方案是regexpr,或者regexpr更易于编写和维护,但这不是其中之一

select substr(val, instr(val,'/',-1)+1, instr(val,'_',-1)-instr(val,'/',-1)-1)

当然,最有效的方法是将单独的信息存储在单独的列中。除了上面的注释之外,您还应该在数据库层之前拦截数据,并对其进行格式化,以便您的数字已经被隔离。我完全同意您的看法。不幸的是,我需要基于这个字符串。Gordon建议我使用regexp\u substr。谢谢我忘记了regexp函数。。。这是很新的。谢谢:如果您的Oracle版本>=11.1,您不需要“替换更好”来使用trim?-如果使用子表达式,如下所示:选择regexp_substrval,'/[0-9]+_',1,1,null,1。匹配表达式[0-9]+的数字部分用括号括起来。这在OracleSpeak中称为subexpression,如果使用regexp_substr的第六个参数,则返回subexpression。有关子表达式的这种用法,请参见Oracle文档:
substr(str, instr(str, '/', 1, 3) + 1, instr(str, '_', 1, 2) - instr(str, '/', 1, 3) - 1)
select substr(val, instr(val,'/',-1)+1, instr(val,'_',-1)-instr(val,'/',-1)-1)