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