2011-10-07 36 views
1

我有一張表格表示校園中的位置。我在網絡程序中爲用戶顯示這些位置,並且我想讓他們能夠更改位置顯示的順序。我爲此列出了一個名爲ord的列。我現在想爲用戶創建了一個方法來更新該列,並確保
1)沒有ord複製
2)所有ord值> = 0 & & <行數(表) 。使用列來確定oracle表格的顯示順序

我想我應該用觸發器做到這一點。首先,在我進行更新之前,我使用代碼來確保表格的行數大於或等於0.& <。然後,一旦插入了該值,我需要修復它創建的副本。我想要做的只是切換值。不過,我得到了可怕的預言變異表錯誤,當我嘗試這個觸發:

create or replace 
trigger plantry_campus_edit_after 
after update on plantry_campus 
for each row 
declare 
    v_pkid number; 
begin 
    SELECT pkid INTO v_pkid FROM plantry_campus WHERE ord = :new.ord && pkid != :new.pkid; 
    UPDATE plantry_campus SET ord = :old.ord WHERE pkid = v_pkid; 
end; 

我寧願做在數據庫中,而不是在代碼中。有關我如何完成此任務的任何建議?

回答

1

我會改變你的web界面,使他們能夠重新排列在屏幕上他們,然後當他們保存,只是簡單地覆蓋每行中的ord列的順序,他們現在出現在屏幕上。

0

如果要執行此操作,請嘗試使用帶有plsql表類型的包變量。在行觸發器中填充plsql表,然後在語句觸發器中執行更新。這將繞過突變表問題,因爲語句級觸發器在這種情況下不受影響。

與此類似。

problem with trigger in oracle

記住,包變量持續整個會話,因此觸發前的初始化。

0

您可以使用視圖輕鬆解決突變表問題;雖然它不漂亮。更新視圖並觸發該視圖:

您需要展開觸發器以包含要更新的所有列。

create or replace view v_plantry_campus_edit as select * from plantry_campus; 


create or replace 
trigger plantry_campus_edit_after 
after update on v_plantry_campus 
for each row 
declare 
    v_pkid number; 
begin 
    SELECT pkid INTO v_pkid FROM plantry_campus WHERE ord = :new.ord && pkid != :new.pkid; 
    UPDATE plantry_campus 
    SET ord = :old.ord 
     -- etc 
     , col1 = :new.col1 
    WHERE pkid = v_pkid; 
end; 
0

恕我直言,在這種情況下使用觸發器不是一個好主意,正如@Ben所說。我會重新排序表中的應用端這樣的:

明顯:

UPDATE plantry_campus SET 
    ord = :new_order 
where pkid = :pkid 

而重新排序更新:

If (:new_order > :old_order) then  
    UPDATE plantry_campus SET 
    ord = ord + 1 
    where pkid != :pkid 
    and ord >= :new_order 
    and ord < :old_order; 
elsif (:new_order < :old_order) then 
    UPDATE plantry_campus SET 
    ord = ord - 1 
    where pkid != :pkid 
    and ord > :old_order 
    and ord <= :new_order; 
end if; 

如果你不希望這樣做的應用程序,只需將PL/SQL函數放入包中。

相關問題