Substr 在 oracle 中的 sql 中给出不正确的输出
Posted
技术标签:
【中文标题】Substr 在 oracle 中的 sql 中给出不正确的输出【英文标题】:Substr giving incorrect output in sql in oracle 【发布时间】:2020-03-17 18:11:54 【问题描述】:我有桌子 ot.plan:
有
NAME
--------------------------------------------------------------------------------
EXISTS(SELECT 1 from zzz_temp b where SUBSTR(a.hehrircal,1,4)=b.acc_num
EXISTS(SELECT 1 from zzz_temp b where SUBSTR(a.clinet,1,4)=b.acc_num
我的预期输出是:
NAME
--------------------------------------------------------------------------------
zzz_temp
zzz_temp
我试过了:
select SUBSTR(name,INSTR(name,'from')+5,INSTR(name,'b')) from ot.plan;
它给了我输出:
zzz_temp b where SUBSTR(a.hehri
zzz_temp b where SUBSTR(a.cline
我该如何解决?
【问题讨论】:
考虑改用REGEXP_SUBSTR()
。
如已回答,INSTR
的第二个参数是长度,而不是结束位置。另请注意,只要表名不包含 b,您的 b 检测才能正常工作。您可以改为寻找 ' b '
(前导和尾随空白)。
从ot.plan中选择SUBSTR(name,INSTR(name,'from')+5,INSTR(name,'b')-INSTR(name,'from')+5);还是不行
【参考方案1】:
您可以使用regexp_substr
达到预期的效果,如下所示:
Select regexp_substr(name, 'from (.+) b',1,1,null,1)
From ot.plan;
干杯!!
【讨论】:
【参考方案2】:您似乎认为最后一个参数是停止的位置。它实际上是包含在结果中的字符数。
尝试从结束位置减去开始位置来确定长度。
【讨论】:
从ot.plan中选择SUBSTR(name,INSTR(name,'from')+5,INSTR(name,'b')-INSTR(name,'from')+5);还是不行 @Randomguy 在最后一个表达式中,您需要减去 5(并可能将其向上或向下移动 1)。如果您的第一个表达式是N+5
,则第二个表达式应该是B-(N+5)
或B-N-5
。【参考方案3】:
select SUBSTR(name,INSTR(name,'from')+5,INSTR(name,'b')-INSTR(name,'from')+5) from ot.plan;还是不行
你试图从另一个数字中减去一个数字,但作为其中的一部分,你有一个加法。您需要将第二部分括在括号中:
select SUBSTR(name,INSTR(name,'from')+5,INSTR(name,' b')-(INSTR(name,'from')+5)) from ot.plan;
SUBSTR(NAME,INSTR(NAME,'FROM')+5,INSTR(NAME,'B')-(INSTR(NAME,'FROM')+5)
-----------------------------------------------------------------------
zzz_temp
zzz_temp
或将加号改为减号:
select SUBSTR(name,INSTR(name,'from')+5,INSTR(name,' b')-INSTR(name,'from')-5) from ot.plan;
SUBSTR(NAME,INSTR(NAME,'FROM')+5,INSTR(NAME,'B')-INSTR(NAME,'FROM')-5)
-----------------------------------------------------------------------
zzz_temp
zzz_temp
您可以查看所涉及的各个数字以了解它在做什么:
select
INSTR(name,'from') as start_from,
INSTR(name,'from')+5 as start_table,
INSTR(name,' b') as b,
INSTR(name,' b')-(INSTR(name,'from')+5) as length_a,
INSTR(name,' b')-INSTR(name,'from')-5 as length_b
from ot.plan;
START_FROM START_TABLE B LENGTH_A LENGTH_B
---------- ----------- ---------- ---------- ----------
17 22 30 8 8
17 22 30 8 8
前三个是您要搜索的字符的位置;长度是减法的两个变体 - 因此总体上表明您正在寻找从位置 22 开始的 8 个字符。
但是,鉴于 cmets 中提到的这种脆弱性,无论如何,您可能最好使用正则表达式方法。
【讨论】:
以上是关于Substr 在 oracle 中的 sql 中给出不正确的输出的主要内容,如果未能解决你的问题,请参考以下文章
Oracle SQL 正则表达式 (regexp_substr)
如何使用Oracle中的SQL中的REGEXP_SUBSTR将自定义消息替换为空插槽