Вставка нескольких строк с последовательностью в 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;

4 ответа

Решение

Ограничения на множественные вставки включают в себя:

  • Вы не можете указать последовательность ни в одной части многострочного оператора вставки. Множественная вставка считается одним оператором 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/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: порядковый номер здесь не разрешен".

Я бы использовал триггер перед вставкой, чтобы заполнить ключевой столбец (если никакое значение не было предоставлено вставкой) вместо этого метода. Последовательности плохо работают с многостоловой вставкой.

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;

Попробуйте вставить эту несколько строк в базу данных оракула

INTO POSTAL_CODE (postal_code,desc)
VALUES(&postal_code,&desc) SELECT * FROM DUAL;
Другие вопросы по тегам