在 Oracle 中按顺序插入多行

Inserting multiple rows with sequence in Oracle

这是我用于在 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;

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

INTO POSTAL_CODE (postal_code,desc)
VALUES(&postal_code,&desc) SELECT * FROM DUAL;

将所有内容插入 POSTAL_CODE(postal_code,desc) 值(postal_code.NEXTVAL,&desc) 插入 POSTAL_CODE (postal_code,desc) 值(postal_code.NEXTVAL,&desc) SELECT * 来自 DUAL;

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

restrictions on multitable inserts包括:

  • You cannot specify a sequence in any part of a multitable insert statement. A multitable insert is considered a single SQL statement. Therefore, the first reference to NEXTVAL generates the next number, and all subsequent references in the statement return the same number.

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

如果您想继续使用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              

但这有点尴尬。您可能最好使用单独的插入语句 - 使用 multitable 插入到单个 table 中并没有真正让你受益匪浅 - 或者使用触发器来设置序列中的唯一列,或者CTE/inline 视图以生成要插入的值。

无需修改数据库对象,您只需将多表 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: sequence number not allowed here".