2013-12-09 37 views
0

我想在oracle中創建一個觸發器,它將檢測重複的已插入主鍵並通過添加前綴字符例如'P_'來重命名新鍵。 如果有人知道這個問題的優雅解決方案,我會很高興看到答案:)。在插入cmd之前在oracle中創建防止重複鍵的觸發器

我開始寫水木清華這樣的:

create or replace 
TRIGGER t1_trigger 
BEFORE INSERT 
ON T1 
DECLARE selected_id varchar2(10); 
BEGIN 
    SELECT id INTO selected_id FROM T1 WHERE id = :new.id; 
    IF (selected_id NOT NULL) 
    THEN INSERT INTO T1 VALUES('p_'); 
    END IF; 
END; 
+2

如果你已經有記錄'id = 200'和'id = p_200'並且試圖用'id = 200'插入新記錄,你會怎麼做? –

+0

我已經考慮過這個問題了,我只是想讓這個問題變得簡單,並且不考慮這個問題,這是一個大學任務,所以我在實施中有一個限制。 – Ataman

回答

1

優雅的方法是使用一個自動遞增序列作爲主鍵。欲瞭解更多信息,請查看herehere

另一種方法是使用MERGE -statement。通過這種方式,您可以檢查是否存在重複鍵,如果存在,請將舊鍵重命名爲其他名稱或調整相應插入的鍵。

理論上你也可以做到以下幾點,但它確實不是一個好主意:

create or replace 
TRIGGER t1_trigger 
BEFORE INSERT 
ON T1 
FOR EACH ROW 
DECLARE 
cursor c1 is select id from t1 where id = :new.id; 
BEGIN 
    for i in c1 loop 
     :new.id := 'p_' || :new.id; 
    end loop; 
END; 

對於clearification:你只會追加一個以上的「P_」你的鑰匙,如果你只有多您的密鑰已經存在。遊標僅用於您的select語句將返回零或超過1行的情況。

+0

你會得到一個沒有數據發現的異常,而不是一個空值;但我想你也會從試圖從正在插入的表中進行選擇時遇到變異表錯誤。 (如果在觸發器甚至觸發之前PK會報告違反約束的情況,我不能確定),我可能會試着去測試它。 –

+0

TBH我沒有檢查功能的查詢,因爲我有點期待一個工作解決方案。我認爲Ataman只是在尋找一些改進。你是對的,它不會那樣工作。我會刪除我的答案的那部分。但我不認爲你會得到一個變異的表錯誤,因爲你沒有插入表中,只調整將要插入的值。但不知道。 – Armunin

+1

謝謝:)。我明白這可能是一個很好的解決方案,可以使用自動創建序列作爲主鍵。 – Ataman