繼續以delete_dept爲例。
作爲存儲過程,當“如果dept內有對應的person,那麼提示用戶不能刪除”這個需求提出的時候,delete_dept是無法在運行時提醒用戶的,因此它必須和UI代碼達成協議:當delete_dept返回-1的時候,就是不能刪除的意思,然後由UI代碼提示用戶“不能刪除”。
就是說,檢查部分在存儲過程,而檢查後的結果有UI來執行。兩者通過return的負數來決定給用戶怎樣的提示。
確實如此:我們有不少代碼都是通過存儲過程返回負值來說明錯誤的類型,然後有UI解釋這個錯誤,決定如何告訴用戶。
既然如此,爲什麼不直接由存儲過程來決定提示內容呢?儘管return不能返回文本內容,但是raiserror可以(要求 sql2005):
CREATE PROCEDURE [dbo].[delete_dept]
@id int
AS
if exists (select * from person where dept_id = @id)begin
raiserror(16,1,"不能刪除")
return
end
delete from dept where id=@id
RETURN 0
客戶端代碼:
void delete_dept(int id)
{
try{
RunProc("delete_dept",id);
}catch(Excetion ex ){
MessageBox.Show(ex.message);
}
}
這樣的做法,好處在於判斷和消息反饋都在一起。而不是如同以往的做法那樣分離開來。本來就是兩個相關的功能工作,應該放到一個代碼塊內,從而讓代碼的職責更加清晰。現在sql2005和以後的版本都已經支持了這個做法。