2017-04-06 65 views
0

所以我試圖創建一個小的Oracle APEX應用程序,允許人們在診所進行預約。我制定了一個負責預約的程序。該應用程序有一個表格,用於保存關於約會人員和約會表格的數據。該過程檢查用戶是否已經在患者表中,如果他在那裏,它應該只在約會表中添加一行,否則它也將它們添加到患者表中。Oracle SQL,插入語句如果沒有運行

select COUNT(p.name) INTO da FROM patients p where p.cnp = cnp; 
IF (da = 0) then 
    insert into patients values(cnp,name,surname,sex,birth_date,phone_no,email); 
end if; 
insert into appointments values(appointment_sequence.nextval,cnp,id_medic,date,time); 

問題是它永遠不會運行if子句內的插入。即使患者不在數據庫中,也會跳到第二個插入,並且由於尚未創建預約的約會表(cnp)密鑰,因此會生成錯誤。

回答

1

問題很可能歸結爲標識符範圍;我猜你的程序中有一個參數(cnp),它與患者表中的列名稱相同。由於您沒有在查詢中限定參數引用(即where p.cnp = procedure_name.cnp),因此Oracle認爲您在該列等於該列的行之後(即where p.cnp = p.cnp),這意味着您將永遠不會得到0的計數,除非其中沒有行表。

爲了避免這個問題,您可以在引用該參數時限定參數(您可以建議您使用PL/SQL的產品經理Bryn Llewellyn),也可以更改參數的名稱(例如p_cnp)。

說了這麼多,只是爲了確定是否需要插入或插入而做點算是浪費。爲什麼僅僅在插入記錄並捕獲dup_val_on_index錯誤(假設您已定義主鍵/唯一鍵!您有,對嗎?)或者使用合併語句來查詢表時才執行插入操作?您應該儘可能地減少工作量,以便構建高性能代碼。

我可能會與合併去,是這樣的:

merge into patients tgt 
    using (select procedure_name.cnp from dual) src 
    on tgt.cnp = src.cnp 
when not matched then 
    insert (tgt.cnp, tgt.name, ....) 
    values (src.cnp, procedure_name.name, ....); 
+0

非常感謝您!它與標識符範圍有關。 – drusk