2016-02-05 4 views
0

Я хочу запустить триггер по Oracle для обновления нескольких полей таблицы данными из другой таблицы после события обновления. Я хочу использовать динамические операторы SQL. Обе таблицы имеют много общих полей, разные по префиксу. Использование «выполнить немедленное» работает только в том случае, если поле, которое я обновляю, является явным. Как только я использую переменную для имени поля, она не работает. Есть идеи?Динамический оператор в триггере

Here is the code : 
create or replace TRIGGER AF_UPDATE_PRODUCT_REQUEST 
AFTER UPDATE ON PRODUCT_REQUEST 
REFERENCING OLD AS OLD NEW AS NEW 
FOR EACH ROW 
WHEN (old.PREQCOMPLETE=1) 

DECLARE 


product_fieldname varchar2(100); 
counter number(1); 
tata number(3); 
old_value VARCHAR2(500); 
new_value VARCHAR2(500); 

BEGIN 
tata:=0; 
    FOR c1 in (SELECT column_name from user_tab_columns WHERE  table_name='PRODUCT_REQUEST') 
    LOOP 
    old_value:=to_char(:old.PREQDESC2); 
    new_value:=to_char(:new.PREQDESC2); 
    IF old_value<>new_value THEN 
     product_fieldname:=replace(c1.column_name,'PREQ','PU'); 
     select count(*) into counter from user_tab_columns WHERE  table_name='PRODUCT' and column_name=product_fieldname; 
     IF counter=1 THEN 
     tata:=tata+1; 
     /*execute immediate 'update product set '|| product_fieldname ||'=:new.'|| c1.column_name ||' where pupname=:old.preqpname';*/ 
     /*execute immediate 'update product set pushelflife=16 where pupname=:d3' using :old.preqpname;*/ 
     IF product_fieldname='PUSHELFLIFE' THEN 
      /*execute immediate 'update product set pushelflife=:d2 where pupname=:d3' using 15,:old.preqpname;*/ 
      execute immediate 'update product set :d1=:d2 where pupname=:d3' using product_fieldname,15,:old.preqpname; 
     END IF; 
     END IF; 
    END IF; 
    END LOOP; 
EXCEPTION 
WHEN OTHERS THEN NULL; 
END; 
+0

Что означает «не работает»? – OldProgrammer

ответ

0

Вы не можете передавать имена объектов или столбцов в качестве переменных привязки в динамическую инструкцию SQL. Вам нужно будет построить динамический оператор SQL, используя эти имена столбцов. Что-то вроде

execute immediate 'update product ' || 
        ' set ' || product_fieldname || ' = :val ' 
        ' where pupname = :key' 
      using 15, :old.preqpname 
+0

Я пробовал это, но он терпит неудачу. Читая больше об этом, кажется невозможным сделать внутри триггера. Может быть, функция может сделать трюк. Моя цель такова: у меня есть 180 полей в таблице запросов продукта, вместе с 180 полями в файле продукта. Я хотел бы найти простой способ обновить поля в файле продукта, если соответствующая запись таблицы запросов продукта будет обновлена ​​после завершения создания продукта. – David

+0

Определите «это не удается». Почему вы сохраняете одни и те же данные в двух разных таблицах, если хотите, чтобы данные совпадали в первую очередь? Если вы действительно настроены нарушить нормализацию, вам лучше писать динамический SQL для генерации кода запуска и использования статического SQL в сгенерированном триггере. По-прежнему можно использовать динамический SQL внутри триггера, но вы не можете динамически ссылаться на атрибуты псевдослучайных ': old' и': new', так что это не особенно полезно. –

+0

Я согласен с тем, что структура наших таблиц не была разумной. PRODUCT_REQUEST и PRODUCT должны были быть одной таблицей с флагом, говорящим, что продукт доступен (PRODUCT) или нет (PRODUCT_REQUEST). В принципе, мне не удается заставить обновление работать, если имя поля, которое я пытаюсь обновить, является переменной и не является допустимым именем поля для этой таблицы. PRODUCT_REQUEST не имеет точно таких же полей, кроме PRODUCT, но имеет много общего. Я пытаюсь создать триггер для обновления общих полей из одной таблицы в другую, если пользователь изменяет эти поля после создания продукта в PRODUCT. – David

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