2009-07-31 120 views
4

我試圖使一個長的存儲過程更容易管理,有一個存儲過程,調用其他存儲過程,例如我想要一個插入數據到表中並取決於類型插入該表類型的附加信息,如:是否有調用其他存儲過程的存儲過程不好?

BEGIN TRANSACTION 

     INSERT INTO dbo.ITSUsage (
      Customer_ID, 
      [Type], 
      Source 
     ) VALUES ( 
      @Customer_ID, 
      @Type, 
      @Source 
      ) 
    SET @ID = SCOPE_IDENTITY() 

    IF @Type = 1 
     BEGIN 
        exec usp_Type1_INS @ID, @UsageInfo 
      END 
     IF @TYPE = 2 
       BEGIN 
        exec usp_Type2_INS @ID, @UsageInfo 
      END 

    IF (@@ERROR <> 0) 
     ROLLBACK TRANSACTION 
    ELSE 
     COMMIT TRANSACTION  

或者這是我應該在我的應用程序中處理的東西?

+1

您可能想剔除@@ ERROR,並使用BEGIN TRY(try catch)和XACT_STATE() – 2009-07-31 21:09:30

+0

假設這是2k5或更高版本...... – Joe 2009-08-01 01:00:29

回答

12

我們始終調用其他procs的procs。否則,很難/不可能分割數據庫密集型(或僅數據庫)應用程序。

+2

同意,但請注意可能需要或可能需要的調用鏈中的特效如果父進程可能回滾,則進行提交。 – 2009-07-31 21:14:41

+0

是的。這可能會非常棘手 - 你基本上都在一個單一的沙箱中,所以你不得不擔心其他的過程會對共享環境做些什麼。 – Joe 2009-07-31 22:28:00

+0

也要小心INSERT EXEC語句不能嵌套。即,調用其他過程並將返回的記錄集存儲在臨時表中的過程。 – jandersson 2009-08-01 00:44:51

4

不,這是完全可以接受的。

3

只要它在同一個數據庫模式內,我認爲它是完全可以接受的。這是重複使用,總是有利於重複。這就像在某個應用程序層調用方法。

3

一點都沒有,我甚至會說,這是推薦你在你的代碼

9

創建方法從裏面另一個過程是完全可以接受的調用程序相同的原因。

但是,在Transact-SQL中依靠@@ ERROR很容易失敗。例如,您的代碼。它將無法檢測到插入失敗,以及被調用過程中產生的任何錯誤。這是因爲@@ ERROR在執行每個語句時被重置,並且只保留最後一條語句的結果。我有一個博客條目,顯示correct template of error handling in Transact-SQL和事務嵌套。另外Erland Sommarskog有一篇文章,現在很長一段時間,reference read on error handling in Transact-SQL

4

當然,沒有。

我已經看到了巨大的存儲過程做了20個不同的事情,將真正受益於重構成更小,單個目的。

2

不支持。它促進重用並允許功能組件化。

1

在我們的IT領域,我們使用存儲過程來鞏固共同的代碼存儲過程和觸發器(如適用)部分。這對於避免SQL源重複也是必不可少的。

1

這個問題的一般答案是,當然,不 - 這是編碼SQL存儲過程的正常甚至是首選的方式。

但它可能是在你的具體情況下,這不是一個好主意。

如果您在應用程序(Java,.Net等)中維護一組支持數據訪問層(DAO)的存儲過程)然後讓數據庫層(我們稱之爲存儲過程)流線型和相對較薄將有利於您的整體設計。因此,具有廣泛的存儲過程調用圖對於維護和支持此類應用程序中的整體數據訪問邏輯可能確實很糟糕。

我會傾向於在DAO和數據庫層之間更加統一的邏輯分佈,以便存儲過程代碼適合單個函數調用。

2

正如其他人指出的,這是完全可以接受的,也是避免重複功能所必需的。

但是,在Transact-SQL中請注意嵌套存儲過程調用中的事務:在發出rollback transaction之前,您需要檢查@@TRANCOUNT,因爲它會回滾所有嵌套的事務。請查看article瞭解詳情。

1

是的,這是不好的。儘管SQL Server不支持並允許一個存儲過程調用另一個存儲過程。如果可能的話,我通常會盡量避免這種設計。我的原因?

single responsibility principle

0

添加到其他海報的正確的意見,沒有什麼原則上錯誤,但你需要注意,以防出現程序由外部應用程序調用的實例執行時間這符合特定的超時

典型示例:如果您從Web應用程序調用存儲過程:當缺省超時啓動時,因爲執行鏈花費的時間較長,即使存儲過程正確提交,Web應用程序也會失敗。 如果您從外部服務呼叫,則會發生同樣的情況。 這可能會導致應用程序中的行爲不一致,從而觸發外部服務中的錯誤管理例程。

如果您處於類似情況,我所做的是打破調用鏈,將長執行子進程重定向到不同進程使用Service Broker