捕获导致 ORA-01438 的列:值大于此列允许的指定精度
Posted
技术标签:
【中文标题】捕获导致 ORA-01438 的列:值大于此列允许的指定精度【英文标题】:Capture the column causing ORA-01438: value larger than specified precision allowed for this column 【发布时间】:2019-08-07 05:09:26 【问题描述】:我正在使用 Oracle 12C。 如果我的插入语句因 ORA-01438 失败,我如何捕获导致错误的列。例如看下面的代码-
create table T1 ( c1 number(3,2) , c2 number(4,2), c3 number(5,2) );
insert into T1 ( c1 ,c2, c3) values ( 1, 22,333); --good
commit;
insert into T1 ( c1 ,c2, c3) values ( 1, 22,3330); --ORA-01438 for c1
insert into T1 ( c1 ,c2, c3) values ( 1, 222,3330); ---ORA-01438 for c1, c2
insert into T1 ( c1 ,c2, c3) values ( 11, 222,3330); --ORA-01438 for c1, c2, c3
我什至尝试过 DBMS_ERRLOG.CREATE_ERROR_LOG 但我无法识别导致错误数据的列。请看下面的代码-
EXECUTE DBMS_ERRLOG.CREATE_ERROR_LOG('T1', 'T1_bad');
insert into T1 ( c1 ,c2, c3) values ( 11, 222,3330);
log errors into T1_bad;
SELECT * FROM T1_bad;
【问题讨论】:
恐怕无法使用DBMS_ERRLOG
获取列名。
可能重复 -- ORA-01438: value larger than specified precision allows for this column - How do i get which column it is referring to?
【参考方案1】:
您可以设置事件来追踪罪魁祸首:
ALTER SESSION SET EVENTS='1438 TRACE NAME ERRORSTACK FOREVER, LEVEL 12';
以下代码显示了相同的演示:
SQL> create table test (name varchar2(1), name1 varchar2(1));
Table created.
SQL> ALTER SESSION SET EVENTS='1438 TRACE NAME ERRORSTACK FOREVER, LEVEL 12';
Session altered.
SQL> insert into test values('ad','a');
insert into test values('ad','a')
*
ERROR at line 1:
ORA-12899: value too large for column "TEJASH"."TEST"."NAME" (actual: 2, maximum:
1)
SQL> insert into test values('d','ad');
insert into test values('d','ad')
*
ERROR at line 1:
ORA-12899: value too large for column "TEJASH"."TEST"."NAME1" (actual: 2, maximum:
1)
SQL>
干杯!!
【讨论】:
解决方案不适用于数字,因为引发了ORA-01438
,它没有列信息。
是的,对于 NUMBER 列,错误是 ORA-1438,对于 VARCHAR2,错误是 ORA-12899。如果它是数字,您将不会获得该列名。您可以使用 SQL*Plus,它会在导致错误的列值下显示 *。但是,我知道这是手动选项。【参考方案2】:
我找到的一个解决方案是使用动态 sql (How can I get position of an error in Oracle SQL query?) 然后DBMS_SQL.LAST_ERROR_POSITION
来获取错误位置:
DECLARE
c INTEGER := DBMS_SQL.open_cursor ();
erg INTEGER;
l_sql VARCHAR2(4000) := 'INSERT INTO test(id, description) VALUES (3333, ''Test'')';
BEGIN
DBMS_SQL.parse (c, l_sql, DBMS_SQL.native);
erg := DBMS_SQL.EXECUTE(c);
DBMS_SQL.close_cursor (c);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(sqlerrm);
dbms_output.put_line(l_sql);
dbms_output.put_line(LPAD('*', DBMS_SQL.LAST_ERROR_POSITION+1));
DBMS_SQL.close_cursor (c);
END;
输出:
ORA-01438: ...
INSERT INTO test(id, description) VALUES (3333, 'Test')
*
【讨论】:
以上是关于捕获导致 ORA-01438 的列:值大于此列允许的指定精度的主要内容,如果未能解决你的问题,请参考以下文章
插入 3 时出现“ORA-01438: 值大于此列允许的指定精度”
插入 3 时出现“ORA-01438: 值大于此列允许的指定精度”
错误:“ORA-01438:值大于此列允许的指定精度”故障因素:“空”详细信息:org.kxml2.kdom.Node@99c0b9c
EBS_DBA_问题:关于ORA-01438: value larger than specified precision allowed for this column