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_idstudent_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:无效数字

insert插入数据时 SQL 错误: ORA-01722: 无效数字

Oracle报错ORA-01722: 无效数字排查解决方案

什么是“oracle ORA-01722”无效数字?

ORA-01722: 无效的数字 where 子句

Oracle sql 错误 ora-01722 无效数字 ora-02063 前行来自