|
Программирование >> Oracle
1426 Глава 20 2. зменять в таблице ЕМР каждую запись, значение столбца EMPNO которой входит во множество значений EMPNO, соответствующие :NEW-записи котор1х отличаются от :OLD-записей. Это множество легко найти с помощью оператора MINUS. 3. Вставлять в таблицу ЕМР все записи :NEW, значение :NEW.EMPNO котор1х не находится во множестве значений EMPNO :OLD-записи. Вот как это реализуется: scott@TKYTE816> create or replace trigger DEPT OR IO UPDATE 10 11 12 13 14 15 16 17 18 19 instead of update on dept or begin if (:ne.deptno = :old.deptno) then if updating(DNAME) or updating(LOC) then update dept set dname = :new.dname, loc = :new.loc where deptno = :new.deptno; end if; if (updating(EMPS)) then delete from emp where empno in (select empno from TABLE(cast(:old.emps MINUS select empno from TABLE(cast(:new.emps as emp tab type)) dbms output.put line(удалено s emp tab type)) sql%rowcount); Первый оператор MINUS возвращает множество значений EMPNO, которые Еы в наборе :OLD, но отсутствуют в наборе :NEW. Эти записи надо удалить из таблицу: ЕМР, поскольку в наборе их больше нет. Изменим те записи набора, которые обновлены: 24 25 26 27 28 30 31 32 34 35 36 37 38 update emp E set (deptno, ename, job, mgr, hiredate, sal, co) = (select :new.deptno, ename, job, mgr, hiredate, sal, con from TABLE(cast(:new.emps as emp tab type)) T where T.empno = E.empno where empno in (select empno from (select * from TLE(cast(:new.emps as emp tab type)) MINUS select * Использование объектно-реляционных средств 1427 39 40 41 from TABLE(cast(:old.emps as emp tab type)) dbms output.put line(M3MeHeH0 sql%rowcount); MINOS select empno from TABLE(cast(:old.emps Этот оператор MINUS возвращает все значения из :NEW, кроме совпадающих со значениями из :OLD; это дает множество измененных записей. Оно используется в подзапросе для получения множества значений EMPNO, соответствующие записи для котор1х в таблице ЕМР надо изменить, после чего эти значения определяются с помощью коррелированного подзапроса. Наконец, добавляем новые записи: 44 insert into emp 45 (deptno, empno, ename, job, mgr, hiredate, sal, comm) 46 select :new.deptno,empno,ename,job,mgr,hiredate,sal,comm 47 from (select * 48 from TABLE(cast(:new.emps as emp tab type)) 49 where empno in 50 (select empno 51 from TABLE(cast(:new.emps as -> emp tab type)) -> emp tab type)) 55 ) 56 ) ; 57 dbms output.put line(BCTaBneH0 58 else 5 9 dbms output.put line(o6pa6oTKa -> пропущена); 60 end if; 61 else 62 raise application error(-20001,3Ha4eHMe deptno изменять -> нeльзя); 63 end if; 64 end; 65 / Trigger created. Оператор MINUS генерирует множество значений EMPNO из набора :NEW, отсутствующих в наборе :OLD; оно представляет список строк, которые надо добавить в таблицу ЕМР. Триггер кажется огромным, но на самом деле он простой. Вначале он проверяет, не изменены ли скалярные столбцы представления DEPT OR. Если - да, выполняются соответствующие изменения в таблице DEPT. Затем, если был изменен столбец вложенной таблицы (заменены все ее значения), эти изменения вносятся в таблицу ЕМР. Чтобы внести все необходимые изменения, надо: 1. удалить из таблицы ЕМР записи, которые были удалены из столбца вложенной таблицы EMPS; sql%rowcount) ; влoжeннoй таблицы 1428 Глава 20 2. изменить в таблице ЕМР те записи, значения котор1х б1ли изменены в столбце вложенной таблицы EMPS; 3. вставить в таблицу ЕМР записи, добавленные в столбец вложенной таблицы EMPS. К счастью, SQL-оператор MINUS и возможность преобразовать столбец типа воженной таблицы в реальную таблицу упрощает реализацию триггера. Теперь мы мом обрабатывать данные так: scott@TKYTE816> declare 10 11 12 13 14 15 16 17 l emps emp tab type; begin select p.emps into l emps from dept or p where deptno = 10; in 1 l emps.count for i loop l emps(i).ename : = lower(l emps(i).ename) ; end loop; update dept or set emps = l emps where deptno = 10; end; удалено 0 изменено З вставлено 0 PL/SQL procedure successfully completed. scott@TKYTE816> 10 11 12 13 14 15 16 17 18 19 20 21 declare emp tab type; l emps begin select p.emps into from dept or p where deptno = 10; l emps for i in 1 .. l emps.count loop if (l emps(i).ename = then l emps.delete(i); else l emps(i).ename : = end if; end loop; miller) initcap(l emps(i).ename); l emps.extend; l emps(l emps.count) : = emptype(1234, Tom, Boss,
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |