【问题标题】:Oracle string is too long for internal buffer when using INTERVAL as string使用 INTERVAL 作为字符串时,Oracle 字符串对于内部缓冲区来说太长了
【发布时间】:2020-04-14 20:52:50
【问题描述】:

表创建脚本:

CREATE TABLE "TEST"("INTERVAL_COL" INTERVAL DAY (0) TO SECOND (6));
Insert into TEST (INTERVAL_COL) values ('+00 11:00:24.920000');
Insert into TEST (INTERVAL_COL) values ('+00 11:00:26.890000');
Insert into TEST (INTERVAL_COL) values ('+00 11:00:28.460000');
Insert into TEST (INTERVAL_COL) values ('+00 11:00:30.140000');
Insert into TEST (INTERVAL_COL) values ('+00 11:00:31.790000');
commit;

在 SQL Developer 和 sqlPlus 中,运行 SELECT * FROM TEST 可以正常工作,SELECT INTERVAL_COL FROM TEST 也是如此。

但是,以下任何一个都会给我一个错误:

SELECT INTERVAL_COL || '.' FROM TEST
SELECT TO_CHAR(INTERVAL_COL, 'HH24:MM.SS') FROM TEST

错误是:

ORA-01877: 字符串对于内部缓冲区来说太长

【问题讨论】:

  • 这很奇怪,看起来可能是一个错误,尽管我看不到已发布。它似乎特别不喜欢day(0)。您可以强制转换为不受限制的间隔......但是您不能以与格式化日期或时间戳相同的方式格式化间隔,因此您要么必须操纵它来获取日期/时间戳,要么提取组件和用它们构建一个字符串 (as here)。
  • 但是您会期望SELECT INTERVAL_COL || '.' FROM TEST 开箱即用,对吧?我可以在任何地方向 Oracle 报告此问题吗?
  • 您可以通过 support.oracle.com 提出服务请求,但您需要一个帐户和一份支持合同。
  • 你传递的是一个字符串,而不是一个区间。 INSERT INTO TEST (INTERVAL_COL) VALUES (INTERVAL '+00 11:00:24.920000' DAY TO SECOND);
  • @WernfriedDomscheit 插入工作正常,并创建了一个有效的间隔 - 这不是问题

标签: oracle oracle12c intervals to-char


【解决方案1】:

如果您想将此day to second 数据转换为HH24:MI:SS,则可以使用:

TO_CHAR(CAST((TRUNC(SYSTIMESTAMP)+INTERVAL_COL) AS DATE), 'HH24:MI.SS')

正如亚历克斯所评论的,

TO_CHAR(TRUNC(SYSDATE)+INTERVAL_COL, 'HH24:MI.SS')

也可以。

【讨论】:

  • 这似乎不起作用 - 它增加了 4 分钟的时间:+00 11:00:24.920000 输出为 11:04.24
  • ...因为你想要的是MI 而不是MM。然后就可以了,谢谢-但没有解释我遇到的错误
  • 是的,需要 MI。已在答案中更正
  • 不确定你为什么要选角;您可以简化为TO_CHAR(TRUNC(SYSDATE)+INTERVAL_COL, 'HH24:MI.SS'),或使用日期或时间戳文字而不是截断。
  • @simonalexander2005 - 不过你有个约会;投射不会恢复小数秒。但你可以这样做:TO_CHAR(TIMESTAMP '2000-01-01 00:00:00' + INTERVAL_COL, 'HH24:MI:SS.FF6')
【解决方案2】:

尽管记录了 TO_CHAR 似乎不适用于 INTERVAL 值。 INTERVAL 的输出格式始终是固定的,即它不依赖于当前用户会话 NLS-Settings,因此您可以使用 RegExp。

试试这个:

REGEXP_REPLACE(REGEXP_SUBSTR(INTERVAL_COL, '\d{2}:\d{2}:\d{2}'), ':(\d{2})$', '.\1') 

注意,如果间隔可能大于 24 小时,那么结果将是错误的(同样适用于像 TO_CHAR(CAST((TRUNC(SYSTIMESTAMP)+INTERVAL_COL) AS DATE), 'HH24:MI.SS') 这样的解决方案)

【讨论】:

  • to_char 确实(通常)在您以间隔开头并以字符串结尾的意义上起作用;你只是不能指定格式。无论如何...这仍然会遇到相同的错误/错误,来自隐式to_char(interval_col)。 (除非你 cast(INTERVAL_COL as interval day to second) 有效,但不应该是必要的......)从好的方面来说,我认为 day(0) 似乎导致这意味着它不能超过 24 小时 *8-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-08
相关资源
最近更新 更多