Oracle ltrim的异常行为

时间:2018-06-29 12:53:33

标签: oracle trim texttrimming

select ltrim('PREPROCESSINGLIST_AOD', 'PREPROCESSINGLIST_') as node_code from dual;

预期结果是AOD,但是当我通过更改第一个字符串来运行时会出现意外行为。 下面是我尝试通过更改_之类的字符(例如BOD, COD...ZOD)而尝试并运行的线索,下面是奇怪的结果。

When    AOD Result==>   AOD
When    BOD Result==>   BOD
When    COD Result==>   D
When    EOD Result==>   D
When    FOD Result==>   FOD
When    GOD Result==>   D
When    HOD Result==>   HOD
When    IOD Result==>   D
When    JOD Result==>   JOD
When    KOD Result==>   KOD
When    LOD Result==>   D
When    MOD Result==>   MOD
When    NOD Result==>   D
When    OOD Result==>   D
When    POD Result==>   D
When    QOD Result==>   QOD
When    ROD Result==>   D
When    SOD Result==>   D
When    TOD Result==>   D
When    UOD Result==>   UOD
When    VOD Result==>   VOD
When    WOD Result==>   WOD
When    XOD Result==>   XOD
When    YOD Result==>   YOD
When    ZOD Result==>   ZOD

然后...我的问题为什么是这种奇怪的行为?

3 个答案:

答案 0 :(得分:4)

这不是奇怪的行为。这是已记录的行为。

根据the documentation of LTRIM

  

LTRIM char 的左端删除 set 中包含的所有字符。

因此,第二个参数尽管是字符串 type ,但不是 string ,而是要修剪的一组字符。

所以这个:

ltrim('PREPROCESSINGLIST_COD', 'PREPROCESSINGLIST_')

由于DC都在O中,因此最终将返回PREPROCESSINGLIST_

PREPROCESSINGLIST_
     ^^
     here

_AOD,但是A未在集合中,因此修剪在此处停止。

如果进行测试,您会发现您得到的行为完全相同:

ltrim('PREPROCESSINGLIST_COD', 'CEGILNOPRST_')

该字符应与PREPROCESSINGLIST_中的字符相同。

答案 1 :(得分:3)

LasseVågsætherKarlsen已经回答了为什么您的代码如此操作的问题。要实现所需的功能,可以使用正则表达式:

select regexp_replace('PREPROCESSINGLIST_COD', 
                      '^PREPROCESSINGLIST_', 
                      '') as node_code 
from dual;

这将从字符串中删除前导PREPROCESSINGLIST,但是如果它位于字符串的中间,则将其保留在该字符串中(因为^锚定为字符串的开头)。

答案 2 :(得分:3)

  

如果我只想要_后面的子字符串,最好使用什么?

目前尚不清楚是否只删除确切的字符串'PREPROCESSINGLIST_',如果要删除,则仅在字符串的开头或任何位置进行匹配;或者您要删除直到第一个下划线的所有内容,或删除至任何下划线的所有内容。

根据您的实际数据和想要获得的结果,可以使用regexp_replace(),如@FrankScmitt显示的那样(带有或不带有锚点),也可以使用普通的replace()或{ {1}}和instr()

在CTE中提供了一些带有各种模式的虚构数据:

substr()

如果可以多种方式获得所需的结果,则避免正则表达式通常更为有效,但有时它们是唯一(明智的选择)。与往常一样,最好根据实际数据自己测试这些选项,以查看哪种方法最有效-或至少足够有效。