加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

oracle – ORA-01400:奇怪的行为

发布时间:2020-12-12 13:14:02 所属栏目:百科 来源:网络整理
导读:Oracle Database 11g企业版11.2.0.3.0版 – 64位生产 A,B,C和D是VARCHAR2 E是DATE (A,C,D,E)是TABLEDESTINATION的主要关键 truncate table TABLEDESTINATION;INSERT /*+ parallel(10) */ INTO TABLEDESTINATION (A,E) SELECT TABLE1.DATA1,TABLE2.DATA2,TABL
Oracle Database 11g企业版11.2.0.3.0版 – 64位生产

A,B,C和D是VARCHAR2

E是DATE

(A,C,D,E)是TABLEDESTINATION的主要关键

truncate table TABLEDESTINATION;

INSERT  /*+ parallel(10) */  INTO TABLEDESTINATION (A,E)
  SELECT
    TABLE1.DATA1,TABLE2.DATA2,TABLE2.DATA3,NVL(TABLE3.DATA4,'-') DATA4,TRUNC(TABLE1.DATA_DATE,'MONTH') DATA_DATE
  FROM TABLE1 
    INNER JOIN TABLE2 ON TABLE1.DATA1 = TABLE2.DATA1 AND TABLE1.Z = TABLE2.Z
    LEFT JOIN TABLE3 ON TABLE1.X=TABLE3.X
  GROUP BY 
    TABLE1.DATA1,'-'),'MONTH');

将导致“ORA-01400:无法插入NULL(”USER“.”TABLEDESTINATION“.”E“)”

现在,如果我使用完全相同的查询,但使用临时表:

truncate table TABLEDESTINATION;

CREATE TABLE TEST_TABLE AS
  SELECT
    TABLE1.DATA1,'MONTH');

INSERT  /*+ parallel(10) */  INTO TABLEDESTINATION (A,E)
  select DATA1,DATA2,DATA3,DATA4,DATA_DATE
  from TEST_TABLE;

正确插入行,没有任何错误.

现在我尝试相同的查询,但使用日期的NVL:

INSERT  /*+ parallel(10) */  INTO TABLEDESTINATION (A,/* -> */ NVL(TRUNC(TABLE1.DATA_DATE,'MONTH'),SYSDATE) /* <- */ DATA_DATE
  FROM TABLE1 
    INNER JOIN TABLE2 ON TABLE1.DATA1 = TABLE2.DATA1 AND TABLE1.Z = TABLE2.Z
    LEFT JOIN TABLE3 ON TABLE1.X=TABLE3.X
  GROUP BY 
    TABLE1.DATA1,SYSDATE) /* <- */
  ;

正确插入行,没有任何错误.

从逻辑上讲,这意味着我在DATA_DATE中有NULL值:

SELECT
  TABLE1.DATA1,NVL(TRUNC(TABLE1.DATA_DATE,SYSDATE) DATA_DATE
FROM TABLE1 
  INNER JOIN TABLE2 ON TABLE1.DATA1 = TABLE2.DATA1 AND TABLE1.Z = TABLE2.Z
  LEFT JOIN TABLE3 ON TABLE1.X=TABLE3.X
WHERE 
  TABLE1.DATA_DATE IS NULL
;

返回0行

SELECT
  TABLE1.DATA1,SYSDATE) DATA_DATE
FROM TABLE1 
  INNER JOIN TABLE2 ON TABLE1.DATA1 = TABLE2.DATA1 AND TABLE1.Z = TABLE2.Z
  LEFT JOIN TABLE3 ON TABLE1.X=TABLE3.X
WHERE 
  TRUNC(TABLE1.DATA_DATE) IS NULL
;

返回0行

怎么可能在DATA_DATE中没有NULL值但是Oracle却抛出了一个ORA-01400?

如何使用临时表,使用完全相同的查询,我没有得到相同的错误?

编辑:
像建议的那样,我也尝试过使用DISTINCT:

INSERT  /*+ parallel(10) */  INTO TABLEDESTINATION (A,E)
  SELECT DISTINCT
    TABLE1.DATA1,'MONTH') DATA_DATE
  FROM TABLE1 
    INNER JOIN TABLE2 ON TABLE1.DATA1 = TABLE2.DATA1 AND TABLE1.Z = TABLE2.Z
    LEFT JOIN TABLE3 ON TABLE1.X=TABLE3.X

返回以下错误:ORA-12805:并行查询服务器意外死亡

EDIT2:如果我删除并行提示,我收到此错误:“ORA-00001:违反了唯一约束(ZRA.ZRAQX_VENTE_DOPR_MOIS_PK2)”
我仍然不明白,因为我在主键上使用GROUP BY,而且我没有任何NULL值…

EDIT3:我尝试使用隐式游标:

FOR CURTEST IN (/* same select as above */) LOOP
INSERT INTO TABLEDESTINATION (A,E) values (CURTEST.DATA1,CURTEST.DATA2,CURTEST.DATA3,CURTEST.DATA4,CURTEST.DATA_DATE);
END LOOP;

而且意外:它有效!没有错误.

没有任何意义了……

解决方法

我发现了这个bug的起源:

TRUNC(TABLE1.DATA_DATE,'MONTH') DATA_DATE

如果我改用它:

TRUNC(TABLE1.DATA_DATE,'MM') DATA_DATE

有用 !

之后我能用MONTH重现错误.

所以它确实是TRUNC和’MONTH’的Oracle错误

谢谢大家的意见.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读