2015-02-14 7 views
0

Мне нужна помощь в устранении триггера, который я пытаюсь создать/использовать для регистрации обновлений и вставок в таблицу. Я использую таблицу customers_history для отслеживания всех изменений, внесенных в таблицу клиентов.sql error 04098 invalid trigger

CREATE TABLE customers (
custID INTEGER PRIMARY KEY, 
custFName VARCHAR2(30), 
custLName VARCHAR2(30), 
custState CHAR(20), 
custZip NUMBER(5) 
); 
-- log inserts and updates on customers table 
CREATE TABLE customers_history (
histID INTEGER PRIMARY KEY, 
cID INTEGER, 
cFName VARCHAR2(30), 
cLName VARCHAR2(30), 
cState CHAR(20), 
cZip NUMBER(5) 
); 

Кроме того, для histID я использую последовательность для автоматического приращения histID на customers_history таблице.

CREATE SEQUENCE ch_seq 
MINVALUE 1 
START WITH 1 
INCREMENT BY 1; 

CREATE OR REPLACE TRIGGER audit_customers 
BEFORE UPDATE 
OR INSERT ON customers 
FOR EACH ROW 
BEGIN 
INSERT INTO customers_history(histID,cID,cFName,cLName,cState,cZip) 
VALUES(ch_seq.nextval,:NEW.custID,:NEW.custFName,:NEW.custLName, 
:NEW.custState,:NEW.custZip); 
END; 
/

Я вставлял две строки на клиентов до создания триггера, и они работают нормально. После создания триггера он не позволит мне вставлять больше строк на клиентов, а также выдает сообщение об ошибке ORA-04098: trigger 'SYSTEM.AUDIT_CUSTOMERS' is invalid and failed re-validation 04098. 00000 - "trigger '%s.%s' is invalid and failed re-validation".

Я попытался выяснить, есть ли какие-либо ошибки кода, используя select * from user_errors where type = 'TRIGGER' and name = 'audit_customers';, и он не возвращал строк. Не уверен, что это помогает или нет. Благодарю.

+0

Почему триггер создается в схеме 'system'? Это кажется подозрительным. –

+0

@gordon linoff Я запускаю все это в oracle db developer vm для класса, поэтому все наши таблицы, триггеры и т. Д. Работают на имени пользователя системы. – JRW2252

+0

@ gordon linoff Кроме того, было бы очень глупо, если бы я просил совета ** на публичном сайте ** для кода со злым умыслом. Извините, что разочаровал вас. Ha ... – JRW2252

ответ

0

вы создали триггер для нескольких DML операций (Insert и Update), так что вы должны specipy в DML операции с использованием IF INSERTING THEN....END IF; и IF UPDATING THEN....END IF;, например:

CREATE OR REPLACE TRIGGER audit_customers 
BEFORE UPDATE 
OR INSERT ON customers 
FOR EACH ROW 
BEGIN 
IF INSERTING THEN 
INSERT INTO customers_history(histID,cID,cFName,cLName,cState,cZip) 
VALUES(ch_seq.nextval,:NEW.custID,:NEW.custFName,:NEW.custLName, 
:NEW.custState,:NEW.custZip); 
END IF; 
END; 
/
+1

Зачем это необходимо, если один и тот же код запускается для обеих операций? –

+0

@GordonLinoff Я думаю, что если он использует ': OLD', он должен указать операцию, потому что, как вы знаете, операция Insert не имеет': OLD' – jfun

+1

Я собирался, если это возможно, регистрировать все вставки и обновления в одной и той же таблице. Я понял то же самое: new.object_type будет работать как для операций вставки, так и для обновления. Это неправильно? – JRW2252

0

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

CREATE TABLE customers (
custID INTEGER, 
custFName VARCHAR2(30), 
custLName VARCHAR2(30), 
custState CHAR(20), 
custZip NUMBER(5) 
); 
CREATE TABLE customers_history (
histID INTEGER, 
cID INTEGER, 
cFName VARCHAR2(30), 
cLName VARCHAR2(30), 
cState CHAR(20), 
cZip NUMBER(5) 
); 
CREATE OR REPLACE TRIGGER audit_customers 
BEFORE UPDATE 
OR INSERT ON customers 
FOR EACH ROW 
BEGIN 
INSERT INTO customers_history(
histID, 
cID, 
cFName, 
cLName, 
cState, 
cZip 
) 
VALUES(
ch_seq.nextval, 
:new.custID, 
:new.custFName, 
:new.custLName, 
:new.custState, 
:new.custZip 
); 
END; 
/

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

ALTER TABLE customers ADD PRIMARY KEY(custID); ALTER TABLE customers_history ADD PRIMARY KEY(histID);

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

Смежные вопросы