2017-01-11 42 views
1

我正在使用Oracle SQL,并且想知道下面的2个查询如何返回完全相同的东西,而有时会返回不同的结果。SQL:与substr一起使用to_char

select substr(to_char(min_code + 10, '099'),1,3) 
from x 
where a = b; 


select substr(min_code + 10,1,2) 
from x 
where a = b; 

首届查询的SUBSTR长度设置为3,而第二个查询具有SUBSTR长度设置为2。然而,当min_code等于151两种查询将返回16.这怎么可能?

我知道它必须与substr如何计算使用to_char时的长度有关,但我的理解是第二个参数(在这些情况下为1)是子串开始的位置,第三个参数是子串的长度。然而,第一个查询仍然会返回16而不是我想象中的161。

然后,当我用min_code等于051的记录测试它时,第1个查询将返回06,而第2个查询将返回61.我理解第2个查询如何获取61,因为它在执行时必须丢弃前导0算术运算,但如何在第一个查询(与to_char函数)返回06.我期望061长度为3.

+1

尝试'选择'|' || to_char(151,'099')|| '|' from dual',然后将格式掩码编辑为'FM099'';这应该可以帮助你找到问题 – Aleksej

回答

1

只是把你的测试在一个单一的查询,并删除+10(问题是不存在),这是你有什么:

SQL> with testCases(n) as (select 151 from dual union select 51 from dual) 
    2 select n, 
    3   substr(to_char(n, '099'),1,3) as substr_3, 
    4   substr(n,1,2) as substr_3 
    5 from testCases; 

     N SUBSTR_3  SUBSTR_3 
---------- ------------ -------- 
     51 05   51 
     151 15   15 

我相信是什么让你期望一个不同的结果是to_char应该做什么;澄清一下,看看下面的结果:

SQL> with testCases(n) as (select 151 from dual union select 51 from dual) 
    2 select n, 
    3   '|' || to_char(n, '099') || '|' as to_char 
    4 from testCases; 

     N TO_CHA 
---------- ------ 
     51 | 051| 
     151 | 151| 

这里可以看到,to_char添加一个空格所得到的字符串;这会使你的子字符串逻辑失效,给你意想不到的结果。 这种行为清楚地解释here

额外的前导空格是潜在的减号。要删除 空间,您可以在格式

事实上使用FM,如果编辑格式掩码,您有

SQL> with testCases(n) as (select 151 from dual union select 51 from dual) 
    2 select n, 
    3   '|' || to_char(n, 'FM099') || '|' as to_char 
    4 from testCases; 

     N TO_CHA 
---------- ------ 
     51 |051| 
     151 |151| 

和测试用例成为:

SQL> with testCases(n) as (select 151 from dual union select 51 from dual) 
    2 select n, 
    3   substr(to_char(n, 'FM099'),1,3) as substr_3, 
    4   substr(n,1,2) as substr_2 
    5 from testCases ; 

     N SUBSTR_3  SUBSTR_2 
---------- ------------ -------- 
     51 051   51 
     151 151   15