Oracle触发器:声明全局变量

时间:2011-02-17 06:19:41

标签: sql oracle triggers oracle10g

我有一张表,我已经写了一个触发器:

CREATE OR REPLACE TRIGGER EMPLOYEE_TRG 
AFTER INSERT OR DELETE OR UPDATE ON EMPLOYEE 

FOR EACH ROW

DECLARE
  TYPE arr IS TABLE OF VARCHAR2(32) INDEX BY PLS_INTEGER;
  v_array arr;

BEGIN
  IF UPDATING THEN
    DBMS_OUTPUT.PUT_LINE('NEW DATA: ' || :new.NAME || ', OLD DATA: ' || :old.NAME);
    DBMS_OUTPUT.PUT_LINE('ID: ' || :new.P_ID);
    v_array(:new.P_ID) := :new.NAME;
    DBMS_OUTPUT.PUT_LINE('COUNTER: ' || v_array.COUNT); -- DISPLAY COUNTER: 1
  END IF; 
END;

当我更新EMPLOYEE表触发器工作正常时。但v_array数组不是存储数据?有人可以帮忙吗?

2 个答案:

答案 0 :(得分:7)

如果要将其设置为全局(在会话中 - 每个会话将拥有自己的变量副本),则在包中声明v_array

CREATE OR REPLACE PACKAGE my_global_pkg IS

   TYPE arr IS TABLE OF VARCHAR2(32) INDEX BY PLS_INTEGER;
   g_array arr;

END my_global_pkg;

CREATE OR REPLACE TRIGGER EMPLOYEE_TRG 
   AFTER INSERT OR DELETE OR UPDATE ON EMPLOYEE 
   FOR EACH ROW
BEGIN
   IF UPDATING THEN
      DBMS_OUTPUT.PUT_LINE('NEW DATA: ' ||:new.NAME ||', OLD DATA: '||:old.NAME);
      DBMS_OUTPUT.PUT_LINE('ID: ' || :new.P_ID);
      my_global_pkg.g_array(:new.P_ID) := :new.NAME;
      DBMS_OUTPUT.PUT_LINE('COUNTER: ' || my_global_pkg.g_array.COUNT);
   END IF;
END;

对于多会话全局变量,请使用关系表(具有适当的多用户锁定)。

答案 1 :(得分:0)

你怎么知道它不能保存数据?您在触发器内声明了数组。所以它不是全球性的,而是本地的。每次触发器运行时,都会获得一个新阵列。您添加一个项目,显示其计数,然后再次释放它。该计数显示1,因此有效。

你的代码工作正常,虽然它没用。 :)你的意思是什么? 没有等待,计数属于不同的数组。您将项目放在本地数组中,并显示另一个(全局?)数组的计数。难怪它不会起作用。我认为你正在修改错误的数组。