想在做update時,查看此表之前是否已經有同樣的記錄存在(存在就不觸發直接保存...):
Trigger對被觸發的表是不是不能做Select?所有數據被鎖定?像下面的寫法就編譯可以通過,但是不能執行:
CREATE OR REPLACE TRIGGER xxwsh_new_deliveries_bri1_4
  after update of Delivery_Id
  on WSH_DELIVERY_ASSIGNMENTS
  for each row
DECLARE
  l_qty number:=100;
BEGIN
  select count(1) into l_qty
  from WSH_DELIVERY_ASSIGNMENTS wda
  where wda.delivery_id=:new.delivery_id;
  --and wda.rowid !=:new.rowid; --這句是排除被觸發行的,但是加上也不行
  ...
EXCEPTION
  ...  
END Xxwsh_New_Deliveries_Bri1_4;
/

解决方案 »

  1.   

    你用after即更新后触发器,做你想做到的工作不对!
    以你的需求,应该用before。这样逻辑才正确。
      

  2.   

    我省略的部分需要用after,用Before會失敗
    樓上的可否解釋一下原因
      

  3.   

    以我的理解
    行级后触发器,如果没有符合update的对象数据存在,不触发这个触发器的。
    那么你这个判断岂不是没有作用了?
    所以,要么使用语句级触发器,要么再update之前调用。
    至于锁,我看不是!
    在触发器里好像不可一使用数据查询语言,查询它所控制的表。
      

  4.   

    有话没说完
    要么再update之前调用。 = 要么再update之前调用一个select count(*) into cnt。来获得符合条件的记录数目。
      

  5.   

    To doer_ljy(可战):謝謝您的回答!
    "行级后触发器,如果没有符合update的对象数据存在,不触发这个触发器的。
    那么你这个判断岂不是没有作用了?"--我的判斷只針對有對象數據的情況,沒有的時候可以忽略。
    如果真的是“不可一使用数据查询语言,查询它所控制的表”的話,就只有看其他方法了。
    我試試before update可以做到哪個程度
      

  6.   

    To dobetterthatnthink:
    執行就會報錯,不能執行哦
      

  7.   

    把 for each row去掉试试!
      

  8.   

    FOR each row去掉的話就不能用:new.value, 而需要用到這些。  
    select count(1) into l_qty
      from WSH_DELIVERY_ASSIGNMENTS wda
      where wda.delivery_id=:new.delivery_id;
    我想最壞情況的做法是另建一個table,內容就是和被觸發表的類似,每次從此表獲得信息,最後update此表,做為被觸發表的同步表了
      

  9.   

    問題已解!
    沒有對本表做Select,也沒有再建立一個表。
    對後面的處理邏輯多做了一些思考,發現原來不用這麼復雜
    還是謝謝大家!