Oracle SQL Developer - последовательный триггер все еще увеличивается при вставке ошибки вывода - PullRequest
0 голосов
/ 30 декабря 2018

Я создаю базу данных, и в этой таблице Utilizador я хочу, чтобы поле codUtilizador, то есть PK, было последовательным, вставка после вставки.

Я создал триггер с помощью редактирования таблицы, не надоЯ не знаю много о триггерах кодирования, но я опишу код ниже.

Что происходит, когда вставка выводит ошибку, она все равно учитывается в триггере, а следующая, которая вставляет успешно, имеет значениеотличается от того, что должно было быть.(Это то, что я предполагаю)

Вот код, если он помогает.
Таблицы:

CREATE TABLE TipoUtilizador (
CodTipoUtilizador Number(1) Primary key 
check (CodTipoUtilizador in ('0','1')),
desc_TipoUtilizador VARCHAR2(20) not null
); 


CREATE TABLE CPostal (
CodPostal VARCHAR2(8) Primary key
check (CodPostal like '____-___'),
desc_CodPostal VARCHAR2(30) not null
);

CREATE TABLE Utilizador ( 
CodUtilizador Number(10) Primary key,
username VARCHAR2(15) Unique not null, 
password VARCHAR2(15) not null,
nCC Number(8) Unique not null,
nif Number(9) Unique not null,
nTelefone Number(9) Unique not null,
rua VARCHAR2(50) not null,
nPorta Number(3) not null,
CodPostal VARCHAR2(8) not null references CPostal(CodPostal), 
CodTipoUtilizador Number(1) not null references TipoUtilizador(CodTipoUtilizador)
);

Вставка:

INSERT INTO Utilizador(username, password, nCC, nif, nTelefone, rua, nPorta, CodPostal, CodTipoUtilizador)
    VALUES ('lcva2', 'lcva123', '87654321', '222222222', '999999999', 'Rua Alberto Campos', '13', '4600-102', '0');

Вывод сценария (Iвставил 2-й неправильно, чтобы я мог показать вам проблему):

1 row inserted.


Error starting at line : 39 in command -
INSERT INTO Utilizador(username, password, nCC, nif, nTelefone, rua, nPorta, CodPostal, CodTipoUtilizador) VALUES ('lcva', 'lcva123', '12345678', '111111111', '913748456', 'Rua Alberto Campos', '13', '4600-102', '1')
Error report -
ORA-00001: unique constraint (LUIS.SYS_C007911) violated


1 row inserted.

Триггер:

create or replace TRIGGER UTILIZADOR_TRG 
BEFORE INSERT ON UTILIZADOR 
FOR EACH ROW 
BEGIN
  <<COLUMN_SEQUENCES>>
  BEGIN
    IF INSERTING AND :NEW.CODUTILIZADOR IS NULL THEN
      SELECT UTILIZADOR_SEQ.NEXTVAL INTO :NEW.CODUTILIZADOR FROM SYS.DUAL;
    END IF;
  END COLUMN_SEQUENCES;
END;

This is how i added the trigger

Результат:

On row 2, the codUtilizador field should be 2, not 3

1 Ответ

0 голосов
/ 30 декабря 2018

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

Причина выполнения проверки после триггера проста: триггер может изменить значения в строке, и они должны соответствоватьограничения.

Это объясняется в документации .Соответствующая часть:

Цикл для каждой строки, затронутой оператором SQL.

a.Запустите все триггеры строки BEFORE, которые применяются к оператору.

b.Блокировка и изменение строки, а также проверка целостности.(Блокировка не снимается, пока транзакция не будет совершена.)

c.Запустите все триггеры строки AFTER, которые применяются к оператору.

Последовательности не заблокированы транзакцией.Блокировка их может серьезно повлиять на производительность, если одновременно происходит несколько вставок / обновлений.

...