为什么Oracle吃我的字符串?

时间:2011-06-01 12:58:29

标签: oracle oracle10g plsqldeveloper

我目前尝试在Oracle DB上执行以下查询

select tzname || ' (UTC'|| tz_offset(tzname) || ')' from v$timezone_names

似乎并不复杂。只是timzone的名称和大括号中的UTC偏移量。但是当我在Windows上使用PL / SQL Developer执行查询时,它总是吃掉最后一个支撑。

所以我去了sqlplus并在那里执行了,现在我得到了我的最后一个大括号,但在最后一个大括号之前还有一个额外的空格作为额外的好东西。

我已尝试使用嵌套to_char()trim(),但没有任何变化。我也尝试过不同的DB,但它总是一样的。

有人知道tz_offset和字符串连接是否有问题?

3 个答案:

答案 0 :(得分:7)

发出以下查询:

select dump(tz_offset(tzname)) from v$timezone_names;

你得到的结果如下:

Typ=1 Len=7: 43,48,49,58,48,48,0
Typ=1 Len=7: 43,48,49,58,48,48,0
Typ=1 Len=7: 43,48,49,58,48,48,0
Typ=1 Len=7: 43,48,49,58,48,48,0
Typ=1 Len=7: 43,48,49,58,48,48,0
Typ=1 Len=7: 43,48,49,58,48,48,0
...

这表明tz_offset()返回以null结尾的字符串(可能是一个错误)。因此,对于您的查询,Oracle正在返回

"Africa/Algiers (UTC+01:00\0)" // Note \0 -> null character
"Africa/Cairo (UTC+03:00\0)" // Note \0 -> null character
...

考虑到这一点,我想PL / SQL Developer将\ 0解释为字符串结尾(可能是另一个错误,SQL字符串不是以空值终止的),因此它不会编写其余的字符串,所以你失去了尾随支撑。 SQL * PLus选择打印空格而不是那个空格,然后继续字符串的其余部分,打印右括号。

作为解决方法,您可以将tz_offset(...)替换为replace(tz_offset(...), chr(0))。这将删除任何tz_offset(...)返回的空值。

答案 1 :(得分:1)

它适用于子字符串,但这并没有真正回答你的问题: - ):

选择tzname || '(UTC'|| substr(tz_offset(tzname),1,6)||')'来自v $ timezone_names;

答案 2 :(得分:0)

我正在创建一个JSON ajax资源,它返回需要包含时区偏移量的时间戳...尾随控制字符真的很烦我,如果关闭,我会修剪如下:

REGEXP_REPLACE(TZ_OFFSET( '加拿大/山'), '[[:CNTRL:]]', '')