2017-05-09 391 views
1

我想连接一个字符串到utl_raw.cast_to_varchar2函数(它也是一个字符串)的结果。它应该是透明的,但我无法附加任何东西到utl_raw.cast_to_varchar2的结果。Oracle - 与utl_raw.cast_to_varchar2函数的结果连接的字符串

下面是一个例子:

select utl_raw.cast_to_varchar2((nlssort('"' || CITY_NAME || ', ' || STATE_CODE || '"', 'nls_sort=binary_ai'))) || ' test' 
from (select 'New York' as CITY_NAME, 'NY' as STATE_CODE from dual) 

我希望得到的结果是"new york, ny" test,但我只得到"new york, ny"

+3

这可能是由于一个“错误”导致'nlssort'添加一个字符串终止符; [here](http://stackoverflow.com/questions/19774073/strange-behavior-of-length-command-oracle)你可以找到更多的东西。例如,如果您尝试从双重'选择转储(utl_raw.cast_to_varchar2((nlssort('something','nls_sort = binary_ai')))),您会看到在字符串末尾添加了“0”字符,所以无论你在这个char之后添加的字符串,都会被忽略,因为它在字符串结尾之后。 – Aleksej

+0

@Aleksej - 我认为这听起来很熟悉,但我找不到之前看到它的地方* 8-)什么是在null之后并不总是完全忽略,整个串联的字符串显示在SQL Developer中,例如,但即使真的(不能复制/粘贴),它也不处于可用状态。 –

回答

3

这是什么可以被认为是一个错误的组合 - 但实际上可能是至关重要的到Oracle如何使用nlssort - 以及您的客户端如何处理字符串。在SQL Developer中,例如,当它作为语句或脚本时,这似乎按预期工作,但我无法从工作表或查询结果网格中复制和粘贴结果。

使用dump()功能,你可以看到,弥补结果的字符:

select dump(utl_raw.cast_to_varchar2((nlssort('"' || CITY_NAME || ', ' || STATE_CODE || '"', 
    'nls_sort=binary_ai'))) || ' test', 1016) as dumped_result 
from (select 'New York' as CITY_NAME, 'NY' as STATE_CODE from dual); 

DUMPED_RESULT                      
---------------------------------------------------------------------------------------------------- 
Typ=1 Len=20 CharacterSet=AL32UTF8: 22,6e,65,77,20,79,6f,72,6b,2c,20,6e,79,22,0,20,74,65,73,74 
                      ^

我标志着^标记来突出显示在输出0,投nlssort()结果与之间您正在添加test。还是有点更清楚而不串联:

select dump(utl_raw.cast_to_varchar2(nlssort('ABC')), 1016) as dumped_result 
from (select 'New York' as CITY_NAME, 'NY' as STATE_CODE from dual); 

DUMPED_RESULT                      
---------------------------------------------------------------------------------------------------- 
Typ=1 Len=4 CharacterSet=AL32UTF8: 41,42,43,0 

甚至更​​好:

select dump(nlssort('ABC'), 1016) as dumped_result from dual; 

DUMPED_RESULT                      
---------------------------------------------------------------------------------------------------- 
Typ=23 Len=4: 41,42,43,0 

nlssort()呼叫添加空字节,显示为转储输出0,到结果。你的客户端看到,作为字符串的结尾,所以即使Oracle实际上串联字符串,你也看不到结果。

您可以删除null(例如,与rtrim(),在连接前:

select rtrim(utl_raw.cast_to_varchar2(nlssort('"' || CITY_NAME || ', ' || STATE_CODE || '"', 
    'nls_sort=binary_ai')), chr(0)) || ' test' as result 
from (select 'New York' as CITY_NAME, 'NY' as STATE_CODE from dual); 

RESULT                        
---------------------------------------------------------------------------------------------------- 
"new york, ny" test 

或与较短的原始字符串:

select dump(rtrim(utl_raw.cast_to_varchar2(nlssort('ABC')), chr(0)), 1016) as dumped_result 
from (select 'New York' as CITY_NAME, 'NY' as STATE_CODE from dual); 

DUMPED_RESULT                      
---------------------------------------------------------------------------------------------------- 
Typ=1 Len=3 CharacterSet=AL32UTF8: 41,42,43 

,你可以看到现在有没有尾随空字符。

+0

非常感谢您的详细解答。它看起来像一个讨厌的bug给我。 –

+0

@AlexArt。 - 我不确定这是一个错误;行为没有真正的记录,但文档确实指的是截断,而函数并不是真正为你正在做的事情设计的。我怀疑空终止符在内部很重要。 –