2011-01-10 146 views
4

這是我的SP存儲過程將不會返回0

CREATE PROCEDURE DeteleTitle 
(
@TitleID int 
) 
AS 
BEGIN 
IF EXISTS(Select TitleID from Titles WHERE [email protected]) 
BEGIN 
DELETE FROM Titles WHERE [email protected] 
SELECT @TitleID 
END 
ELSE 
BEGIN 
SELECT 0 
END 
END 

方法,其中我打電話是: -

public Int32 DeleteTitle(Int32 TitleID) 
{ 
try 
{ 
int ds=0; 
SqlParameter[] sqlparam=new SqlParameter[1]; 
sqlparam[0]=(@TitleID,TitleID); 
ds=Convert.ToInt32(SqlHelper.ExecuteScalar(ConfigurationManager.ConnectionStrings["con"].ConnectionString,CommandType.StoredProcedure,"DeleteTitle",sqlparam).Tables[0]); 
return ds; 
} 

catch(Exception ex) 
{ 
return 0; 
} 
} 

現在TitleID在許多表的外鍵。如果一些Table的記錄正在使用TitleID,那麼它會拋出這個異常,說「外鍵違規n東西」。在我上面的存儲過程中,如果delete不成功,我在else塊中選擇零。當刪除成功時,它會返回TitleID的值,如50,99或其他。現在發生的是,當刪除不成功時,它不返回零。我想根據刪除存儲過程返回的零值顯示一條消息,但是當它沒有返回任何值時(刪除失敗時),我在DeleteTitle()方法的catch塊中返回零。

現在我有兩個問題: -

  1. 爲什麼存儲過程不返回爲零時刪除失敗了嗎?
  2. 在catch塊中返回零,就像我在正確的方式之上做的那樣?我不知道如何檢索外鍵異常數量和東西,所以我只是在catch塊中返回零。
+0

你應該至少抓住一個sqlexception(我相信這是正確的,如果不查找它)。目前你在這裏可能會捕捉所有不相關的異常,並忽略它們。您應該確實捕獲特定的異常,以便任何意外的異常可以冒泡到應用程序級別的錯誤處理程序,以適當處理和記錄以及其他任何內容。 – Chris 2011-01-10 18:42:17

回答

3

你想在你的程序中使用TRY...CATCH,而不是IF ... ELSE。

如果您仔細考慮過,當DELETE失敗且外鍵違規時,您已經在語句的IF部分。你的代碼如何可能跳轉到ELSE塊?

3

問題是,如果if語句失敗且出現異常,您的if語句將不會執行ELSE語句。你的IF語句也顯示不正確 - 不應該是IF EXISTS,[然後刪除記錄?]現在寫的方式,如果記錄存在,它不會被刪除。

擴展的問題是,依賴於異常(以C#,SQL或任何其他語言)作爲流控制的方法被認爲是不好的做法。

您最好通過對每個相關表使用EXISTS語句來顯式檢查相關記錄。

+0

你是對的..它是如果只存在..是一個錯字..我糾正它。一個問題 - 許多使用該TitleID作爲外鍵的表有什麼方法?仍在所有這些表中明確檢查?請回答..thnx – Serenity 2011-01-10 18:51:04

2

如果Tables是表的集合,那麼對於第一個表的第一列,您需要另一個[0]

+0

在我看來,表格實際上是由Execute Scalar方法返回的「對象」。我期望它會拋出一個異常(或可能不實際編譯),因爲在返回的對象上不會有名爲「Table」的屬性或方法。但我可能是錯的。 :) – Chris 2011-01-10 18:39:35

2

使用本:

CREATE PROCEDURE DeteleTitle 
(
@TitleID int 
) 
AS 
BEGIN TRY 
    DELETE FROM Titles WHERE [email protected] 
    SELECT CASE 
       WHEN @@ROWCOUNT>0 THEN @TitleID 
       ELSE 0 --row did not exist 
      END 
END TRY 
BEGIN CATCH 
    SELECT 0 --delete failed 
END CATCH 
go 

當多個表「鏈接」通過外鍵和刪除像你報告,你得到一個錯誤父行,因爲沒有父母可以不存在的子數據。您可能想要查看級聯刪除,或者在此過程中添加代碼以通過外鍵從與標題關聯的表中刪除。在DELETE FROM Titles之前添加這些刪除。這樣做:

CREATE PROCEDURE DeteleTitle 
(
@TitleID int 
) 
AS 
BEGIN TRY 
    BEGIN TRANSACTION 

    DELETE FROM YourOtherTablesA WHERE [email protected] 
    DELETE FROM YourOtherTablesB WHERE [email protected] 

    DELETE FROM Titles WHERE [email protected] 
    SELECT CASE 
       WHEN @@ROWCOUNT>0 THEN @TitleID 
       ELSE 0 --row did not exist 
      END 
    COMMIT 
END TRY 
BEGIN CATCH 
    IF XACT_STATE()!=0 
    BEGIN 
     ROLLBACK TRANSACTION 
    END 
    SELECT 0 --delete failed 
END CATCH 
go 
0

您可以使用@@ ERROR作爲輸出結果。 @@ ERROR = 0意味着成功,否則不成功的操作

CREATE PROCEDURE DeteleTitle 
(
    @TitleID int 
) 
AS 

BEGIN 
    IF EXISTS(Select TitleID from Titles WHERE [email protected]) 
    BEGIN 
     DELETE FROM Titles WHERE [email protected]  
    END 

    Select @@ERROR 

END