【问题标题】:Multitable insert into a table with primary key in Oracle多表插入到Oracle中具有主键的表中
【发布时间】:2020-05-23 07:36:03
【问题描述】:

我正在尝试使用单个表将数据插入到不同的表中,并且我要插入的表具有主键。

谁能指导我如何修复错误?

INSERT
ALL
WHEN TO_CHAR(L_SHIPDATE,'YYYY') = '1995' THEN
 INTO YEAR1995
  VALUES (L_PARTKEY, L_EXTENDEDPRICE - 0.1*L_EXTENDEDPRICE)
WHEN TO_CHAR(L_SHIPDATE,'YYYY') = '1996' THEN
 INTO YEAR1996
  VALUES (L_PARTKEY, L_EXTENDEDPRICE - 0.1*L_EXTENDEDPRICE)
WHEN TO_CHAR(L_SHIPDATE,'YYYY') = '1997' THEN
 INTO YEAR1997
  VALUES (L_PARTKEY, L_EXTENDEDPRICE - 0.1*L_EXTENDEDPRICE)


SELECT distinct L_PARTKEY, L_EXTENDEDPRICE, L_SHIPDATE 
FROM LINEITEM;

第 1 行出现错误:ORA-00001:违反了唯一约束 (TPCHR.YEAR95_PKEY)

这是表定义

CREATE TABLE YEAR1995
(
    Y95_PARTKEY NUMBER(12) NOT NULL,
    Y95_PRICE   NUMBER(12) NOT NULL,
    CONSTRAINT YEAR95_PKEY PRIMARY KEY (Y95_PARTKEY, Y95_PRICE)  
);

【问题讨论】:

  • PRIMARY KEY (Y95_PARTKEY, Y95_PRICE) ,你真的在​​ Price 字段上添加了约束吗?

标签: sql oracle


【解决方案1】:

正如this article 建议的那样,您可以尝试以下方法:

exec dbms_errlog.create_error_log ('myInsertErrors');

INSERT
ALL
WHEN TO_CHAR(L_SHIPDATE,'YYYY') = '1995' THEN
 INTO YEAR1995
  VALUES (L_PARTKEY, L_EXTENDEDPRICE - 0.1*L_EXTENDEDPRICE)
WHEN TO_CHAR(L_SHIPDATE,'YYYY') = '1996' THEN
 INTO YEAR1996
  VALUES (L_PARTKEY, L_EXTENDEDPRICE - 0.1*L_EXTENDEDPRICE)
WHEN TO_CHAR(L_SHIPDATE,'YYYY') = '1997' THEN
 INTO YEAR1997
  VALUES (L_PARTKEY, L_EXTENDEDPRICE - 0.1*L_EXTENDEDPRICE)


SELECT distinct L_PARTKEY, L_EXTENDEDPRICE, L_SHIPDATE 
FROM LINEITEM

LOG ERRORS INTO err$_myInsertErrors REJECT LIMIT UNLIMITED;

这样你所有的插入异常(即重复数据)都将存储在err$_myInsertErrors表中,并且插入语句将完成

【讨论】:

  • 感谢您的建议。我找到了解决问题的方法,而无需忽略任何数据。
【解决方案2】:

您的l_shipdate 不是唯一的,因此您的查询会在同一年内获得多个结果。您可以将年份提取移动到查询中:

INSERT
ALL
WHEN T_YEAR = 1995 THEN
 INTO YEAR1995
  VALUES (L_PARTKEY, L_EXTENDEDPRICE - 0.1*L_EXTENDEDPRICE)
WHEN T_YEAR = 1996 THEN
 INTO YEAR1996
  VALUES (L_PARTKEY, L_EXTENDEDPRICE - 0.1*L_EXTENDEDPRICE)
WHEN T_YEAR = 1997 THEN
 INTO YEAR1997
  VALUES (L_PARTKEY, L_EXTENDEDPRICE - 0.1*L_EXTENDEDPRICE)


SELECT distinct extraxt(YEAR from L_SHIPDATE) AS T_YEAR, L_PARTKEY, L_EXTENDEDPRICE
FROM LINEITEM;

由于每个价格的计算都是相同的,您也可以在查询中执行此操作:

INSERT
ALL
WHEN T_YEAR = 1995 THEN
 INTO YEAR1995
  VALUES (L_PARTKEY, T_EXTENDEDPRICE)
WHEN T_YEAR = 1996 THEN
 INTO YEAR1996
  VALUES (L_PARTKEY, T_EXTENDEDPRICE)
WHEN T_YEAR = 1997 THEN
 INTO YEAR1997
  VALUES (L_PARTKEY, T_EXTENDEDPRICE)


SELECT distinct extraxt(YEAR from L_SHIPDATE) AS T_YEAR,
  L_PARTKEY,
  0.9 * L_EXTENDEDPRICE AS T_PRICE
FROM LINEITEM;

我建议您在语句中也包含目标表的列名:

INSERT
ALL
WHEN T_YEAR = 1995 THEN
 INTO YEAR1995 (Y95_PARTKEY, Y95_PRICE)
  VALUES (L_PARTKEY, T_EXTENDEDPRICE)
...

【讨论】:

  • 谢谢,这正是我所需要的!代码现在可以工作了。
【解决方案3】:

您还真的需要了解重复键是什么才能理解此错误:

$ oerr ora 0001
00001, 00000, "unique constraint (%s.%s) violated"
// *Cause: An UPDATE or INSERT statement attempted to insert a duplicate key.
//         For Trusted Oracle configured in DBMS MAC mode, you may see
//         this message if a duplicate entry exists at a different level.
// *Action: Either remove the unique restriction or do not insert the key.
$

what the Oracle Database Concepts Guide says about unique constraints

【讨论】:

    猜你喜欢
    • 2019-01-14
    • 2014-12-26
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    相关资源
    最近更新 更多