PL / SQL Trigger не работает должным образом - PullRequest
2 голосов
/ 23 ноября 2011

У меня проблема с триггером.После создания триггера мне выдается сообщение

BD1.UTILIZADOR находится в мутации, триггер не может прочитать или выполнить

У меня есть эта таблица

    create table UTILIZADOR 
    (
       U_ID                 NUMBER(6)            not null,
       U_NOME               VARCHAR2(60)         not null,
       U_SEXO               VARCHAR2(10)         not null,
       U_IDADE              NUMBER(3)            not null,
       U_ALTURA             NUMBER(3)            not null,
       U_PESO               NUMBER(6)            not null,
       U_IMC                NUMBER(2,2),
       U_PRIVILEGIOS        NUMBER(1)            not null,
       U_PASSWORD           VARCHAR2(10)         not null,
       constraint PK_UTILIZADOR primary key (U_ID)
    );

и если я сделаю это:

INSERT INTO UTILIZADOR (U_ID,U_NOME,U_SEXO,U_IDADE,U_ALTURA,U_PESO,U_PRIVILEGIOS,U_PASSWORD) VALUES (1,'my name','Male',32,174,74000,0,'password');

, а затем

SELECT * FROM UTILIZADOR;

Я могу видеть, что все как ожидалось.

То, что я хочу сделать, этопри вставке или обновлении U_ALTURA или U_PESO поле U_IMC автоматически обновляется / вставляется.

Вот что, если сделано:

CREATE OR REPLACE TRIGGER CALCULA_IMC
AFTER INSERT OR UPDATE OF U_ALTURA, U_PESO ON UTILIZADOR
FOR EACH ROW
BEGIN
    UPDATE UTILIZADOR
        SET U_IMC = (U_PESO / 1000) /  (POWER(U_ALTURA / 100,2));
END;
/

Может кто-нибудь сказать, что я делаю неправильно?

Ответы [ 3 ]

5 голосов
/ 24 ноября 2011

Ваш код триггера обновляет каждую запись в таблице UTILIZADOR, это будет включать запись, только что вставленную вашим оператором INSERT, я предполагаю, что вы не хотите, чтобы каждая запись в вашей таблице обновлялась всякий раз, когда вы вставляете новуюсделайте запись в него.

Когда вы запускаете огонь после вставки или обновления, он фактически будет рекурсивно вызывать себя бесконечно, и вы действительно этого не хотите.

Вам нужно немного больше понятьтриггеры, прежде чем вы сможете эффективно делать то, что вы хотите сделать.

http://docs.oracle.com/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm

http://www.techonthenet.com/oracle/triggers/

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

http://www.oracle -base.com / Articles / 9i / MutatingTableExceptions.php

Возможно, есть лучший способ достичь ваших целей,Например, вы можете использовать триггер BEFORE INSERT OR UPDATE и назначать обновления значениям :NEW вместо ввода нового UPDATE в теле триггера и т. д.

Триггер уровня строки можетне читайте и не пишите таблицу, из которой она уволена.Однако триггер уровня оператора может.

Надеюсь, это поможет ...

3 голосов
/ 25 ноября 2011

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

CREATE OR REPLACE TRIGGER CALCULA_IMC
AFTER INSERT OR UPDATE OF U_ALTURA, U_PESO ON UTILIZADOR
FOR EACH ROW
BEGIN
    :NEW.U_IMC = (:NEW.U_PESO / 1000) /  (POWER(:NEW.U_ALTURA / 100,2));
END;
/
1 голос
/ 24 ноября 2011

Ваш триггер пытается обновить строку, которая уже обновляется, подумайте об этом, в триггере пост-обновления вы пытаетесь сделать другое обновление, которое снова запустит триггер, вызывая другое обновление, которое затем вызовет триггер снова.......

Oracle не любит пытаться изменить или изучить что-то, что уже изменяется.

Попробуйте установить u_imc непосредственно в ваших операторах вставки / обновления.

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