【问题标题】:Why is Oracle eating my string?为什么 Oracle 会吃掉我的字符串?
【发布时间】:2011-06-01 12:58:28
【问题描述】:

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

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

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

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

我已经尝试使用嵌套的to_char() 和trim(),但没有任何变化。我也在不同的数据库上尝试过,但总是一样的。

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

【问题讨论】:

  • 看来你一直在挨饿。定期向它提供数据,它不会吃不该吃的东西。

标签: oracle oracle10g plsqldeveloper


【解决方案1】:

发出以下查询:

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() 返回以空值结尾的字符串(可能是一个错误)。因此,对于您的查询,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 选择打印一个空格而不是那个 null,然后继续处理字符串的其余部分,打印右大括号。

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

【讨论】:

  • 看起来像是一个特定于 PL/SQL Developer 的错误。 Oracle SQL Developer 将 \0 显示为一个小方块,并显示附加到字符串的任何字符。
  • @Jeffrey Kemp 是的,但我认为 tz_offset() 在任何情况下都不应该返回以 null 结尾的字符串。
  • 这是 SQL,字符串不需要终止符 - 字符串末尾的 chr(0) 虽然没用,但完全合法
【解决方案2】:

它适用于子字符串,但这并不能真正回答您的问题为什么会发生:-):

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

【讨论】:

    【解决方案3】:

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

    regexp_replace(tz_offset('Canada/Mountain'),'[[:cntrl:]]','')

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      • 2012-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多