将数值转换为 VARCHAR2 会抛出 ORA-03113

Casting numerical value to VARCHAR2 throws ORA-03113

当我们 运行 针对 Oracle 12c 企业版 12.2.0.1.0 的语句(其中包含将数值转换为 VARCHAR2(4000 字符))时,我们收到 ORA-03113通信通道上的文件结尾

各种资源 - 例如 https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9527821800346583868 描述,这可能是由错误的数据库配置引起的。提到的资源 (asktom.oracle.com) 有一个共同点 - 他们提到了我们遇到错误的相同边界 1002 / 1003。但是,我无法找到导致此行为的特定 configuration/explanation - 特别是在 1002/1003 边界的情况下。让我展示一个示例查询:

这个有效:

select cast(numerical_value as varchar2(1002 char)) 
from my_table;

这失败了,ORA-03113:

select cast(numerical_value as varchar2(1003 char)) 
from my_table;

有没有人观察到这种行为或者可以告诉我,哪个数据库设置可能导致这种情况?

这个答案是对问题的框架挑战。

来自Oracle Datatype limits

NUMBER [ (p [, s]) ] Number having precision p and scale s. The precision p can range from 1 to 38. The scale s can range from -84 to 127. Both precision and scale are in decimal digits. A NUMBER value requires from 1 to 22 bytes.

因此,如果您将值格式化为字符串,它的最大值可以为:

-999999999999999999999999999999999999990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

也就是127个字符,或者如果考虑最大的负指数那么

-.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099999999999999999999999999999999999999

长度为 169 个字符(如果有前导零,则为 170 个)。

db<>fiddle

无需将存储在 table 中的数值转换为超过此大小的任何值,因此您可以使用:

CAST(value AS VARCHAR2(200 CHAR))

而且它不仅仅可以处理存储在 NUMBER 列中的所有值。

错误是由Oracle 12c中引入的max_string_size=EXTENDED引起的

如果此参数设置为 EXTENDED,将 NUMBER(X byte) 转换为 VARCHAR2(4009 byte or greater) 将导致数据库崩溃。结果,您将在通信通道 .

上收到提到的错误消息 ORA-03113 文件结尾

可以复现:

  1. 使用标准设置创建数据库(max_string_size=STANDARD)
  2. 检查,转换是否正常:

    select cast(cast(12345 as NUMBER(19)) as VARCHAR2(4000 char))
    
  3. 按照此处所述迁移到 max_string_size=EXTENDED
    https://dbaclass.com/article/max_string_size-parameter-oracle-12c/

  4. 再次执行相同的查询,将失败:

    select cast(cast(12345 as NUMBER(19)) as VARCHAR2(4000 char))