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将自定义消息替换为空插槽

怎样在pl/sql developer中给oracle添加一个调度作业

Oracle中的SQL语句的题目,求解答啊

截取ORACLE字符串中的数字

Oracle的substr函数