2013-04-05 213 views
4

我在SQL Server 2012中有存儲過程,比如說spXample和一個定標器函數fXample。 我從spXample調用函數fXample。 我可以在函數中拋出一個異常,並在存儲過程的Catch塊中捕獲它並重新引發到調用C#代碼?從SQL Server函數向存儲過程拋出異常

更新:

我寫的功能等:

CREATE FUNCTION dbo.fXample(@i INT) 
RETURNS TINYINT 
AS 
BEGIN 
    RETURN (SELECT CASE WHEN @i < 10 
    THEN THROW 51000,'Xample Exception',1; 
    ELSE (SELECT @i) 
    END); 
END 
GO 

我收到錯誤

Msg 443, Level 16, State 14, Procedure fXample, Line 46 Invalid use of a side-effecting operator 'THROW' within a function.

我怎樣寫替代代碼來實現上述功能?

+0

拋出一個異常的功能基礎上什麼樣的條件?什麼類型的函數,標量,TVF,多語句TVF? – 2013-04-05 14:41:41

+0

嘗試RAISERROR:http://msdn.microsoft.com/en-us/library/ms178592.aspx。如果你給它一個較低的嚴重性,它可以被CATCH捕獲。從那裏,你可以稱它爲「嚴重」的嚴重性(我認爲11+;頁面上有例子),它會停止SP的執行並將它踢回到你的應用程序。 – valverij 2013-04-05 14:42:30

+0

Aaron的Scaler價值,異常將基於驗證。 – MaxRecursion 2013-04-05 14:45:42

回答

9

您可以通過在驗證失敗時強制出現錯誤條件來做到這一點,前提是這不是自然可能發生的錯誤。當你知道某個錯誤只能發生在驗證失敗時,你可以通過檢查你的catch塊中的error_number以自定義的方式處理。例如在tempdb:

USE tempdb; 
GO 

CREATE FUNCTION dbo.fXample(@i INT) 
RETURNS TINYINT 
AS 
BEGIN 
    RETURN (SELECT CASE WHEN @i < 10 -- change this to your "validation failed" condition 
    THEN 1/0   -- something that will generate an error 
    ELSE (SELECT @i) -- (you'd have your actual retrieval code here) 
    END); 
END 
GO 

CREATE PROCEDURE dbo.spXample 
    @i INT 
AS 
BEGIN 
    SET NOCOUNT ON; 
    BEGIN TRY 
    SELECT dbo.fXample(@i); 
    END TRY 
    BEGIN CATCH 
    IF ERROR_NUMBER() = 8134 -- divide by zero 
    BEGIN 
     THROW 50001, 'Your custom error message.', 1; 
     -- you can throw any number > 50000 here 
    END 
    ELSE -- something else went wrong 
    BEGIN 
     THROW; -- throw original error 
    END 
    END CATCH 
END 
GO 

現在嘗試一下:

EXEC dbo.spXample @i = 10; -- works fine 
EXEC dbo.spXample @i = 6; -- fails validation 
EXEC dbo.spXample @i = 256; -- passes validation but overflows return 

結果:

---- 
10 

Msg 50001, Level 16, State 1, Procedure spXample, Line 12
Your custom error message.

Msg 220, Level 16, State 2, Procedure spXample, Line 7
Arithmetic overflow error for data type tinyint, value = 256.

+2

謝謝,但是我們必須跳過什麼荒謬的箍來做些什麼是很簡單! 只是表明SQL是一種過去的語言,根本就不是在繼續。 :( – NickG 2013-08-09 12:53:19

+1

我只想添加THROW來自Sql Server 2012 – 2015-03-06 12:09:43

+0

@NickG,你可以使用存儲過程來代替,函數實際上是一種很好的方式來表示它們沒有副作用,當然,它們仍然因爲你可以拋出一個內置的錯誤 - 所以它不是完全沒有副作用,它是一種在語言中具有純函數的優雅方式,SQL是一種遠遠超過其時間的語言,並且非常令人印象深刻考慮它的年齡,它基本上是基於數據集的DSL,非常棒! – Jon49 2017-03-22 16:15:56