11

这是我用于在 oracle 数据库中插入多行的查询。但是当我在其中使用序列时,它会引发错误,如 ORA-00001:唯一约束。怎么做。

INSERT ALL
  INTO POSTAL_CODE( postal_code,desc)
    VALUES(postal_code.NEXTVAL,'Coimbatore')
  INTO POSTAL_CODE (postal_code,desc)
    VALUES(postal_code.NEXTVAL,'Mumbai') SELECT * FROM DUAL;
4

5 回答 5

22

对多表插入的限制包括:

  • 您不能在多表插入语句的任何部分指定序列。多表插入被视为单个 SQL 语句。因此,对 NEXTVAL 的第一次引用会生成下一个数字,并且语句中的所有后续引用都返回相同的数字。

这并不完全正确 - 您可以使用一个序列,它总是获得相同的值,因此通过引用相同的序列一次性创建父记录和子记录可能很有用。

如果您想继续使用insert all,您可以通过使用获取序列值的非确定性函数来解决这个问题:

CREATE FUNCTION get_seq RETURN NUMBER IS
BEGIN
  RETURN postal_code_seq.nextval;
END;
/

INSERT ALL
  INTO POSTAL_CODE( postal_code,description)
    VALUES(get_seq,'Coimbatore')
  INTO POSTAL_CODE (postal_code,description)
    VALUES(get_seq,'Mumbai') SELECT * FROM DUAL;

2 rows inserted.

SELECT * FROM postal_code;

                            POSTAL_CODE DESCRIPTION        
--------------------------------------- --------------------
                                      1 Coimbatore          
                                      2 Mumbai              

但这有点尴尬。您可能最好使用单独的插入语句 - 使用多表插入到单个表中并没有真正让您获得太多 - 或者从序列中设置唯一列的触发器,或者 CTE/内联视图来生成值插入。

于 2015-08-12T15:16:22.403 回答
4

而不是修改您的数据库对象,您可以简单地将多表重写INSERT ALL为一个INSERT多行连接的单个UNION ALL

INSERT INTO postal_code
SELECT postal_code_seq.NEXTVAL, description
FROM
(
    SELECT 'Coimbatore' description FROM dual UNION ALL
    SELECT 'Mumbai'     description FROM dual
);

请注意,必须在外部查询中调用该序列。在内部查询中使用序列看起来可以简化代码,但会引发错误“ORA-02287:此处不允许序列号”。

于 2020-02-28T21:09:50.697 回答
3

我将使用插入前触发器来填充键列(如果插入未提供任何值)而不是此方法。序列不适用于多表插入。

于 2015-08-12T15:11:35.290 回答
-5

INSERT ALL INTO POSTAL_CODE(postal_code,desc) VALUES(postal_code.NEXTVAL,&desc) INTO POSTAL_CODE (postal_code,desc) VALUES(postal_code.NEXTVAL,&desc) SELECT * FROM DUAL;

于 2015-08-12T14:36:44.490 回答
-5

尝试在 oracle 数据库中插入多行

INTO POSTAL_CODE (postal_code,desc)
VALUES(&postal_code,&desc) SELECT * FROM DUAL;
于 2015-08-12T14:34:16.750 回答