Ошибка, триггер вместо недействителен и не прошел повторную проверку - PullRequest
0 голосов
/ 01 декабря 2018

Я пытаюсь создать вместо триггера.Его цель - вставить в 3 таблицы вместо того, чтобы у меня было представление, но у меня есть ряд проблем.

Create or replace trigger trigg_view
Instead of Insert ON Carti_Beletristica
for each row

Begin

dbms_output.put_line('i dont know');

End;

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

ORA-04098: trigger 'RO_A372_SQL_S20.INSERT_VIEW_TRIGG' is invalid and failed re-validation

Это очень расстраивает, потому что это очень простой триггер, и я не могу продолжить... После этого, как я буду генерировать де первичные ключи?Потому что, по моему мнению, у меня нет чего-то подобного.Моя идея состояла в том, чтобы выбрать максимум из первичных ключей в таблице, затем добавить один, затем использовать это значение, но я получаю много ошибок.

CREATE VIEW Carti_Beletristica AS
SELECT titlu, nr_pagini, nr_exemplare, nume AS autor, telefon
FROM Carte NATURAL JOIN Autor JOIN Persoana ON (id_pers = id_aut)
WHERE upper(gen) = 'BELETRISTICA'

Это представление.

Create table Persoana(
    id_pers number(10) not null,
    nume varchar2(100) not null,
    telefon varchar2(15) not null,

    Constraint persoana_id_pers_pk primary key(id_pers)
 );

Create table Carte(
    id_carte number(10) not null,
    titlu varchar2(100) not null,
    nr_pagini number(10) not null,
    nr_exemplare number(10) not null,
    gen varchar2(20) not null,

    Constraint carte_id_carte_pk primary key(id_carte)  
 );

Create table Autor(
    id_carte number(10) not null,
    id_aut number(10) not null,

    Constraint autor_pk primary key(id_carte,id_aut),

    Constraint autor_id_carte_fk foreign key(id_carte) references Carte(id_carte),
    Constraint autor_id_aut_fk foreign key(id_aut) references Persoana(id_pers)

);

Вы можете мне немного помочь?Вставка в представлении будет выглядеть так:

Insert into Carti_Beletristica(titlu,nr_pagini,nr_exemplare,autor,telefon)
values('tiltu',69,96,'otor','07phonenumber')

РЕДАКТИРОВАТЬ:

Это то, что я пытался для первичного ключа

Create or replace trigger trigg_view
Instead of Insert ON Carti_Beletristica
for each row
declare
    aux persoana.id_pers%type;
Begin

    select max(id_pers)+1 into aux from Persoana;

    dbms_output.put_line(aux);

End;

1 Ответ

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

Моя идея состояла в том, чтобы выбрать максимум из первичных ключей в таблице, затем добавить один, а затем использовать это значение,

Вы можете подумать "моя идея сработала" но это очень плохая практика:

select max(id_pers)+1 into aux from Persoana;

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

Правильное решение - использовать встроенные генераторы уникальных ключей Oracle.До 12с это означало последовательность.Для вашей таблицы persoana это будет означать создание последовательности с именем persoana_seq, на которую вы будете ссылаться в своем триггере:

aux := persoana_seq.nextval;

Последовательности являются наиболее эффективным механизмом для генерации серии гарантированных уникальных числа.

В Oracle 12c мы можем определить столбцы как столбцы IDENTITY.Это дает нам автоматически увеличивающийся столбец:

create table persoana (
       id generated always as identity primary key,
       ....

persoana.id будет автоматически заполнен уникальным значением при вставке без каких-либо дополнительных действий с нашей стороны.(Столбцы идентичности имеют связанные последовательности под обложками, просто нам не нужно беспокоиться о них.)

...