【问题标题】:Why Does Oracle 10g to_char(date time) Truncate Strings?为什么 Oracle 10g to_char(date time) 会截断字符串?
【发布时间】:2017-02-08 03:28:01
【问题描述】:

我得到了一个 bug report,其中 Oracle 10g 正在截断来自 to_char(datetime) 的返回值:

SQL> select to_char(systimestamp, '"day:"DD"hello"') from dual;

TO_CHAR(SYSTIMESTAMP,'"DAY:"DD"HE
---------------------------------
day:27hel

值得注意的是,Oracle 11g 似乎没有发生这种情况。我的问题是,为什么会发生这种情况?是否需要设置一些配置变量来告诉to_char(datetime) 为其返回值分配更大的缓冲区?

【问题讨论】:

  • 我在 10.2.0.5 中没有看到。您在哪个补丁级别(可能是平台)上看到了这个?
  • OP 说:“Oracle 版本:Oracle 数据库 10g 企业版版本 10.2.0.1.0 - 64 位生产。”
  • 下面Rusty的回答似乎是正确的。对于此类功能,Oracle 中没有任何与“缓冲区分配”相关的参数。只有当结果超出预期的结果类型(例如 varchar2 像这里的 4000 )时,你才会得到一个异常。我在您的“错误报告”中给出了红色示例,并且可以看到结果取决于表达式的长度。因此,对于未命名的列,它看起来像是 SQL Plus 的默认行为。显示时修剪结果。尝试为列指定别名并使用 COLUMN 命令设置适当的宽度。见docs.oracle.com/cd/B19306_01/server.102/b14357/ch6.htm

标签: oracle buffer truncate to-char


【解决方案1】:

我不确定,但它可能只是在 SQL*Plus 中显示。您是否尝试在 Toad 中运行它?或者,如果您将结果分配给 PL/SQL 块中的 varchar2 并输出结果?

我在 SQL*Plus Reference for 10g 中找到的内容如下:

SQL*Plus 中未格式化的 DATE 列的默认宽度和格式 由数据库 NLS_DATE_FORMAT 参数确定。否则, 默认格式宽度为 A9。请参阅 COLUMN 的 FORMAT 子句 命令以获取有关格式化 DATE 列的更多信息。

您的值被修剪为 9 个字符,对应于默认 A9 格式。我没有相同的版本,并且这种行为在 11g 中没有重现,所以你能检查一下我的理论吗?

【讨论】:

【解决方案2】:

我遇到了同样的问题,我知道解决方案。 我使用的是 11.2.0.4.0 版本,但我相信在其他版本中可能会重复这种情况。它以某种方式取决于客户。 (例如,我不能使用 SQL*Plus 重复它,只能使用 PL/SQL 开发人员) 试试这个:

select to_char(systimestamp, '"day:"DD"йцукенг OR any other UTF-encoded-something"') from dual
union all
select to_char(systimestamp, '"day:"DD"hello"') from dual;

你会得到以下结果:

day:08йцукенг OR any other UTF-encoded-so
day:08hello

你可以看到“东西”丢失了。由于 7 个两字节符号“йцукенг”,这恰好超过了 7 个字节。 Oracle 为字符数分配缓冲区,而不是所需字节数。 命令

alter session set nls_length_semantics=byte/char

很遗憾不会影响这种行为。

所以我的解决方案是将结果转换为 varchar2(enough_capacity)

select cast(to_char(systimestamp, '"day:"DD"йцукенг OR any other UTF-encoded-something"') as varchar(1000)) from dual
union all
select to_char(systimestamp, '"day:"DD"hello"') from dual

显式类型转换使表达式独立于客户端或配置。 顺便说一句,所有隐式 to_char 转换都会发生同样的事情。例如。

case [numeric_expression]
when 1 then '[unicode_containing_string]'
end

结果可能会被删减。

【讨论】:

猜你喜欢
  • 2015-12-20
  • 2013-09-23
  • 2019-10-17
  • 1970-01-01
  • 1970-01-01
  • 2017-08-15
  • 2012-01-29
  • 2011-08-21
  • 1970-01-01
相关资源
最近更新 更多