Oracle-将字符串与utl_raw.cast_的结果连接到_varchar2函数

Oracle-将字符串与utl_raw.cast_的结果连接到_varchar2函数,oracle,oracle11g,Oracle,Oracle11g,我试图将一个字符串连接到utl\u raw.cast\u to\u varchar2函数(也是一个字符串)的结果。它应该是透明的,但我无法在utl\u raw.cast\u to\u varchar2的结果中添加任何内容 以下是一个例子: select utl_raw.cast_to_varchar2((nlssort('"' || CITY_NAME || ', ' || STATE_CODE || '"', 'nls_sort=binary_ai'))) || ' test' from

我试图将一个字符串连接到
utl\u raw.cast\u to\u varchar2
函数(也是一个字符串)的结果。它应该是透明的,但我无法在
utl\u raw.cast\u to\u 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)

我希望结果是“纽约州纽约市”测试,但我只得到了“纽约市纽约市纽约市”

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

使用
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
,位于cast
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实际上正在连接字符串,您也无法看到结果

在连接之前,您可以删除空值,例如使用
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

您现在可以看到它没有尾随的空字符。

这可能是由于一个导致
nlssort
添加字符串终止符的“bug”;你可以找到更多的东西。例如,如果您尝试从dual中选择dump(utl_raw.cast_to_varchar2((nlssort('something','nls_sort=binary_ai')),您将看到字符串末尾添加了
0
字符,因此无论您在该字符后面添加什么字符串,将被忽略,因为它位于字符串末尾。@Aleksej-我觉得它听起来很熟悉,但我找不到我以前在哪里见过它*8-)空值后面的内容并不总是被完全忽略,例如,整个连接的字符串在SQL Developer中显示,但即使在那里也不处于可用状态(无法复制/粘贴).非常感谢您的详细回答。“在我看来,它确实像一只讨厌的虫子。”@AlexArt.-我不确定这是一个错误;这种行为并没有真正的文档化,但文档中确实提到了截断,而且函数并不是真正为您所做的事情而设计的。我怀疑空终止符在内部很重要。