将数值转换为 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;
有没有人观察到这种行为或者可以告诉我,哪个数据库设置可能导致这种情况?
这个答案是对问题的框架挑战。
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 个)。
无需将存储在 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 文件结尾
可以复现:
- 使用标准设置创建数据库(
max_string_size=STANDARD
)
检查,转换是否正常:
select cast(cast(12345 as NUMBER(19)) as VARCHAR2(4000 char))
按照此处所述迁移到 max_string_size=EXTENDED
:
https://dbaclass.com/article/max_string_size-parameter-oracle-12c/
再次执行相同的查询,将失败:
select cast(cast(12345 as NUMBER(19)) as VARCHAR2(4000 char))
当我们 运行 针对 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;
有没有人观察到这种行为或者可以告诉我,哪个数据库设置可能导致这种情况?
这个答案是对问题的框架挑战。
NUMBER [ (p [, s]) ]
Number having precisionp
and scales
. The precisionp
can range from 1 to 38. The scales
can range from -84 to 127. Both precision and scale are in decimal digits. ANUMBER
value requires from 1 to 22 bytes.
因此,如果您将值格式化为字符串,它的最大值可以为:
-999999999999999999999999999999999999990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
也就是127个字符,或者如果考虑最大的负指数那么
-.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099999999999999999999999999999999999999
长度为 169 个字符(如果有前导零,则为 170 个)。
无需将存储在 table 中的数值转换为超过此大小的任何值,因此您可以使用:
CAST(value AS VARCHAR2(200 CHAR))
而且它不仅仅可以处理存储在 NUMBER
列中的所有值。
错误是由Oracle 12c中引入的max_string_size=EXTENDED
引起的
如果此参数设置为 EXTENDED
,将 NUMBER(X byte)
转换为 VARCHAR2(4009 byte or greater)
将导致数据库崩溃。结果,您将在通信通道 .
可以复现:
- 使用标准设置创建数据库(
max_string_size=STANDARD
) 检查,转换是否正常:
select cast(cast(12345 as NUMBER(19)) as VARCHAR2(4000 char))
按照此处所述迁移到
max_string_size=EXTENDED
:
https://dbaclass.com/article/max_string_size-parameter-oracle-12c/再次执行相同的查询,将失败:
select cast(cast(12345 as NUMBER(19)) as VARCHAR2(4000 char))