ORA-01722: 插入行时数字无效
Posted
技术标签:
【中文标题】ORA-01722: 插入行时数字无效【英文标题】:ORA-01722: invalid number when insert a row 【发布时间】:2021-04-19 19:15:06 【问题描述】:我有一个 oracle 触发器,当我想插入一行时,它给了我无效的数字错误。我认为比较运算符之一有问题。我试图编辑它们但没有用。对于比我花更多时间在数据库上的人来说,这可能很容易。 我的列类型是: id、question_id、answer_id、student_id - 数字、varchar2、varchar2、varchar2。
create or replace
trigger results_insert
after INSERT
ON results
FOR EACH ROW DECLARE
BEGIN
IF INSERTING
THEN
MERGE INTO results rs
USING (select :new.id id, :new.question_id qid, :new.answer_id aid, :new.student_id stid
from dual) t1
ON (t1.qid = rs.question_id AND t1.stid = rs.student_id)
WHEN MATCHED THEN
UPDATE SET rs.answer_id = t1.aid
WHEN NOT MATCHED THEN
INSERT (id, question_id, answer_id, student_id)
VALUES (t1.id, t1.qid, t1.aid, t1.stid);
END IF;
COMMIT;
END;
我的插入语句:
insert into results(id,question_id, answer_id, student_id) values (1,'qst1', 'answ2', 'stud3');
DDL:
--------------------------------------------------------
-- File created - Monday-April-19-2021
--------------------------------------------------------
--------------------------------------------------------
-- DDL for Table RESULTS
--------------------------------------------------------
CREATE TABLE "BIGFIVE"."RESULTS"
( "ID" NUMBER(10,0),
"ANSWER_ID" VARCHAR2(40 CHAR),
"QUESTION_ID" VARCHAR2(5 CHAR),
"STUDENT_ID" VARCHAR2(9 CHAR)
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SYSTEM" ;
--------------------------------------------------------
-- DDL for Index SYS_C007820
--------------------------------------------------------
CREATE UNIQUE INDEX "BIGFIVE"."SYS_C007820" ON "BIGFIVE"."RESULTS" ("ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SYSTEM" ;
--------------------------------------------------------
-- DDL for Index UQ_RESULT
--------------------------------------------------------
CREATE UNIQUE INDEX "BIGFIVE"."UQ_RESULT" ON "BIGFIVE"."RESULTS" ("QUESTION_ID", "STUDENT_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SYSTEM" ;
--------------------------------------------------------
-- Constraints for Table RESULTS
--------------------------------------------------------
ALTER TABLE "BIGFIVE"."RESULTS" ADD CONSTRAINT "UQ_RESULT" UNIQUE ("QUESTION_ID", "STUDENT_ID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SYSTEM" ENABLE;
ALTER TABLE "BIGFIVE"."RESULTS" MODIFY ("STUDENT_ID" NOT NULL ENABLE);
ALTER TABLE "BIGFIVE"."RESULTS" MODIFY ("QUESTION_ID" NOT NULL ENABLE);
ALTER TABLE "BIGFIVE"."RESULTS" MODIFY ("ANSWER_ID" NOT NULL ENABLE);
ALTER TABLE "BIGFIVE"."RESULTS" ADD PRIMARY KEY ("ID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SYSTEM" ENABLE;
ALTER TABLE "BIGFIVE"."RESULTS" MODIFY ("ID" NOT NULL ENABLE);
--------------------------------------------------------
-- Ref Constraints for Table RESULTS
--------------------------------------------------------
ALTER TABLE "BIGFIVE"."RESULTS" ADD CONSTRAINT "RESULTS_ANSWERS_FK1" FOREIGN KEY ("ANSWER_ID")
REFERENCES "BIGFIVE"."ANSWERS" ("ANSW_ID") ENABLE;
ALTER TABLE "BIGFIVE"."RESULTS" ADD CONSTRAINT "RESULTS_QUESTIONS_FK1" FOREIGN KEY ("QUESTION_ID")
REFERENCES "BIGFIVE"."QUESTIONS" ("QST_ID") ENABLE;
ALTER TABLE "BIGFIVE"."RESULTS" ADD CONSTRAINT "RESULTS_STUDENT_DIM_FK1" FOREIGN KEY ("STUDENT_ID")
REFERENCES "BIGFIVE"."STUDENT_DIM" ("STU_ID") ENABLE;
--------------------------------------------------------
-- DDL for Trigger RESULTS_INSERT
--------------------------------------------------------
CREATE OR REPLACE TRIGGER "BIGFIVE"."RESULTS_INSERT"
after INSERT
ON results
FOR EACH ROW DECLARE
BEGIN
IF INSERTING
THEN
MERGE INTO results rs
USING (select :new.id id, :new.question_id qid, :new.answer_id aid, :new.student_id stid
from dual) t1
ON (t1.qid = rs.question_id AND t1.stid = rs.student_id)
WHEN MATCHED THEN
UPDATE SET rs.answer_id = t1.aid
WHEN NOT MATCHED THEN
INSERT (id, question_id, answer_id, student_id)
VALUES (t1.id, t1.qid, t1.aid, t1.stid);
END IF;
END;
/
ALTER TRIGGER "BIGFIVE"."RESULTS_INSERT" ENABLE;
【问题讨论】:
您不能在触发器中提交。顺便说一句,您要插入 哪些 值?仅通过查看您的代码很难猜测。此外,您不能对正在使用的表进行操作(您会得到一个 mutating table 错误)。 更新了我的问题! @Littlefoot 好的,谢谢。但是,正如我所说,该触发器不会返回 INVALID NUMBER 错误,而是返回 mutating table 错误。你从哪里得到无效号码? 对不起,不知道你的意思是我在哪里得到无效号码。我在脚本输出中得到它。如果它对您有帮助,触发器会给我这个异常:线程 [status-0,2 ,main]: java.lang.NullPointerException 看起来很奇怪,因为您在图片中显示的表格和您合并到的表格有不同的列:图片中有空格,代码中没有空格。这真的是您在代码中使用的表的输出吗?请同时为您的表提供 DDL,以便我们重现您的问题 【参考方案1】:这就是我的意思:先放样表:
SQL> create table results (id number, question_id varchar2(20),
2 answer_id varchar2(20), student_id varchar2(20));
Table created.
没有代码的触发器,它只是提交:
SQL> create or replace
2 trigger results_insert
3 after INSERT
4 ON results
5 FOR EACH ROW DECLARE
6 BEGIN
7 commit;
8 end;
9 /
Trigger created.
SQL> insert into results(id,question_id, answer_id, student_id) values (1,'qst1', 'answ2', 'stud3');
insert into results(id,question_id, answer_id, student_id) values (1,'qst1', 'answ2', 'stud3')
*
ERROR at line 1:
ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "SCOTT.RESULTS_INSERT", line 3
ORA-04088: error during execution of trigger 'SCOTT.RESULTS_INSERT'
你的触发器(“原样”,我没有修改任何东西):
SQL> create or replace
2 trigger results_insert
3 after INSERT
4 ON results
5 FOR EACH ROW DECLARE
6 BEGIN
7 IF INSERTING
8 THEN
9 MERGE INTO results rs
10 USING (select :new.id id, :new.question_id qid, :new.answer_id aid, :new.student_id stid
11 from dual) t1
12 ON (t1.qid = rs.question_id AND t1.stid = rs.student_id)
13 WHEN MATCHED THEN
14 UPDATE SET rs.answer_id = t1.aid
15 WHEN NOT MATCHED THEN
16 INSERT (id, question_id, answer_id, student_id)
17 VALUES (t1.id, t1.qid, t1.aid, t1.stid);
18 END IF;
19 COMMIT;
20 END;
21 /
Trigger created.
SQL> insert into results(id,question_id, answer_id, student_id) values (1,'qst1', 'answ2', 'stud3');
insert into results(id,question_id, answer_id, student_id) values (1,'qst1', 'answ2', 'stud3')
*
ERROR at line 1:
ORA-04091: table SCOTT.RESULTS is mutating, trigger/function may not see it
ORA-06512: at "SCOTT.RESULTS_INSERT", line 5
ORA-04088: error during execution of trigger 'SCOTT.RESULTS_INSERT'
变异表,不是无效数字错误。
你应该做的是首先使用MERGE
。放弃触发器,它只会带来痛苦。就DROP
吧。那么:
插入新行:
SQL> merge into results rs
2 using (select 1 id, 'qst1' qid, 'answ2' aid, 'stud3' stid from dual) t1
3 on ( t1.qid = rs.question_id
4 and t1.stid = rs.student_id
5 )
6 when matched then update set
7 rs.answer_id = t1.aid
8 when not matched then insert (id, question_id, answer_id, student_id)
9 values (t1.id, t1.qid, t1.aid, t1.stid);
1 row merged.
SQL> select * From results;
ID QUESTION_ID ANSWER_ID STUDENT_ID
---------- -------------------- -------------------- --------------------
1 qst1 answ2 stud3
匹配question_id
和student_id
(以便合并执行更新;检查answer_id
):
SQL> merge into results rs
2 using (select 1 id, 'qst1' qid, 'answ9' aid, 'stud3' stid from dual) t1
3 on ( t1.qid = rs.question_id
4 and t1.stid = rs.student_id
5 )
6 when matched then update set
7 rs.answer_id = t1.aid
8 when not matched then insert (id, question_id, answer_id, student_id)
9 values (t1.id, t1.qid, t1.aid, t1.stid);
1 row merged.
SQL> select * From results;
ID QUESTION_ID ANSWER_ID STUDENT_ID
---------- -------------------- -------------------- --------------------
1 qst1 answ9 stud3
SQL>
【讨论】:
感谢您的回答,我已经从触发器中删除了提交。我必须使用触发器来完成它,因为我将它与 java 一起使用并将用户的测试答案插入结果表。我想检查用户是否已经回答了问题。如果存在则更新他的答案,如果不存在则插入。 不,您不必必须使用触发器。您宁愿使用接受 4 个参数并包含 MERGE 语句的 存储过程(就像我发布的那样)。然后从您的 Java 程序中调用该过程并传递适当的参数。 好的,我会这样做。感谢您的快速帮助!以上是关于ORA-01722: 插入行时数字无效的主要内容,如果未能解决你的问题,请参考以下文章
使用python将数据从csv文件插入oracle时出现错误ORA-01722:无效数字