2016-02-25 4 views
2

Я пытаюсь создать триггер Oracle, который устанавливает значения столбца в таблице B на основе оператора select, запускаемого в триггере.Oracle Trigger - таблица обновлений B на основе условия таблицы A

Я хочу иметь возможность устанавливать значения столбца 'is_active' в таблице B в 'N' на основе оператора select после того, как была выполнена вставка в таблице A.

Мой запрос выглядит следующим образом:

CREATE OR REPLACE TRIGGER INACTIVE_STATE 
AFTER INSERT ON 
COMMENTS 
FOR EACH ROW 
DECLARE 
    inactive_id number; 
BEGIN 
    SELECT distinct b.id 
    into inactive_id 
    from comments a, 
      modules b 
    where a.module_name=b.name 
    and  a.type_id='FUNCTIONAL' 
    and  a.module_id=b.id; 
update modules 
set is_active='N' 
where ID=:inactive_id 
END INACTIVE_STATE; 
/

Когда я пробую и complpile курок, я получаю следующие ошибки:

Error(15,1): PL/SQL: SQL Statement ignored 
Error(17,10): PLS-00049: bad bind variable 'INACTIVE_ID' 
Error(17,15): PL/SQL: ORA-00933: SQL command not properly ended 
Error(19,1): PLS-00103: Encountered the symbol "/" when expecting one of the following:  (begin case declare end exception exit for goto if loop mod null pragma raise return select update while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge 

Это кажется, что это не нравится обновление заявление, или переменная связывания не анализируется в этом процессе.

Если я разделяю эти утверждения на 2 команды (используя var для обработки переменной привязки: inactive_id), она работает так, как ожидалось.

VAR INACTIVE_ID number 
begin 
    select distinct b.id into :INACTIVE_ID 
    from comments a, 
      modules b 
    where a.module_name=b.name 
    and  a.type_id='FUNCTIONAL' 
    and  a.module_id=b.id; 
    end; 
    /

PL/SQL procedure successfully completed. 

SQL> 
SQL> update modules 
    set is_active='N' 
    where ID=:INACTIVE_ID 
    /

    1 row updated. 

Любые идеи, что я мог бы игнорировать?

+4

Триггер, где положение должно быть 'где ID = inactive_id' - не двоеточие. –

+0

Спасибо Тони, тигр скомпилирован успешно! Однако при выполнении моего оператора обновления я получаю следующее: таблица КОММЕНТАРИИ мутирует, триггер/функция может ее не видеть - какие-либо идеи, как я с этим справляюсь? – Huskie69

+2

Прежде всего, какова цель оператора select? Должен ли он действительно смотреть на ВСЕ комментарии или этот конкретный комментарий, который вы только что вставили? Если все комментарии вам удастся удалить 'FOR EACH ROW' и избежать мутирующей проблемы. –

ответ

1

Как Тони Эндрюс отметил в комментариях оригинальный пост, я был неправильно используя двоеточие перед «inactive_id» переменной в выражении WHERE.

Правильный код должен быть:

CREATE OR REPLACE TRIGGER INACTIVE_STATE 
AFTER INSERT ON 
COMMENTS 
DECLARE 
    inactive_id number; 
BEGIN 
    SELECT distinct b.id 
    into inactive_id 
    from comments a, 
      modules b 
    where a.module_name=b.name 
    and  a.type_id='FUNCTIONAL' 
    and  a.module_id=b.id; 
update modules 
set is_active='N' 
where ID=inactive_id 
END INACTIVE_STATE; 
/
-2

Попробуйте использовать

PRAGMA AUTONOMOUS_TRANSACTION; 

, прежде чем начать

+0

Никогда не делайте этого !! –

+0

Если триггер имеет оператор DML и вы хотите совершить транзакцию; то без установки прагмы автономно, это не позволит вам это сделать. В принципе, нет жесткого правила. использовать ли прагму автономно или не полностью зависит от требования. –

+0

ОК, «99% времени, не делай этого»! Единственным допустимым случаем, о котором я могу думать, является то, что вы по какой-то причине хотите зарегистрировать действие, которое запускает триггер, даже если вы откатите основную транзакцию, и это на самом деле не происходит. В 99% случаев вы просто потенциально повредили бы базу данных, если бы сделали это. –

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