Переменная связывания PL / SQL в операторе вставки, - PullRequest
0 голосов
/ 11 июня 2019
VARIABLE dept_id NUMBER

SET AUTOPRINT ON

DECLARE
max_dept departments.department_id%TYPE; 
dept_name departments.department_name%TYPE := 'Revenue';

BEGIN

SELECT MAX(department_id) 
INTO max_dept 
FROM departments; 

:dept_id := max_dept +10;

INSERT INTO departments (department_id,department_name,location_id)
VALUES(:dept_id,dept_name,NULL); 



END;

Возвращает ошибку

Отчет об ошибке: ORA-01400: невозможно вставить NULL в ("HR". "DEPARTMENTS". "DEPARTMENT_ID") ORA-06512: в строке 13 01400. 00000 - "невозможно вставить NULL в (% s)" * Причина:

1 Ответ

5 голосов
/ 11 июня 2019

Я собираюсь предложить что-то совершенно другое здесь. Такой подход обречен на провал, как только ваше приложение выходит «в дикую природу».

Допустим, ваше приложение пользуется огромным успехом, и теперь у вас есть десятки людей, которые используют его одновременно, и давайте предположим, что в настоящее время 1000 - это самый высокий номер отдела.

Теперь у нас примерно 20 человек, которые в одно и то же время делают:

SELECT MAX(department_id) 
INTO max_dept 
FROM departments; 

Они получат все в результате 1000, они все затем попытаются вставить 1010 в таблицу. Тогда произойдет одна из двух вещей

a) все, кроме одного, получат ошибку из-за нарушения первичного ключа, б) у вас будет несколько строк, все с dept = 1010

Любой из них, очевидно, не велик. Вот почему у нас есть вещь, называемая последовательностью, которая может гарантировать вам уникальные значения. Вы просто делаете:

create sequence DEPT_SEQ;

и затем вставьте:

INSERT INTO departments (department_id,department_name,location_id)
VALUES(dept_seq.nextval,dept_name,NULL); 

Существуют еще более простые механизмы (в Google это означает «колонка идентификации оракула»), но это безропотно объясняет путь вперед и избавит вас от проблем с вашим текущим подходом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...