2012-01-12 32 views
3

我有一個存儲過程,它基於一個id(足夠簡單)選擇一行,但只返回實際結果,如果數據滿足一些條件,否則返回特定的錯誤代碼。這樣做嵌套檢查時,該代碼將類同此:基於選定的數據返回不同的值

CREATE PROCEDURE GetStuffById 
@StuffId int 
AS 
BEGIN 
IF EXISTS (SELECT TOP 1 * FROM [Stuff] WHERE StuffId = @StuffId) 
    BEGIN 
    DECLARE @IsValid bit 
    SET @IsValid = (SELECT IsValid FROM [Stuff] WHERE StuffId = @StuffId) 
    IF @IsValid = 1 
     BEGIN 
     --More nested checks may occur here 
     SELECT * FROM [Stuff] WHERE StuffId = @StuffId 
     END 
    ELSE 
     BEGIN 
     RETURN -2 
     END 
    END 
ELSE 
    BEGIN 
    RETURN -1 
    END 
END 

在這種方法我已經在同一個表,這似乎是多餘和低效和3個選擇其他檢查將意味着另一個選擇等是否有一個更好的模式來做到這一點(例如臨時表)?

UPDATE:編輯首先檢查

+0

爲什麼你需要區分空表和沒有匹配的行?其他檢查是否都使用該行的值? – 2012-01-12 12:08:29

+0

您可以在一個查詢中使用sql「CASE ..... END CASE」語句,但這取決於.. – VS1 2012-01-12 12:09:00

+0

@MartinSmith我的壞,遺漏了where子句,現在修復。是的,所有檢查應該在同一行上運行(只要它存在),但是每次檢查都應該返回一個不同的錯誤代碼。 – 2012-01-12 12:14:11

回答

4

可以分配給多個變量在一個單一的選擇和使用@@ROWCOUNT檢測行是否被發現。

DECLARE @IsValid BIT, 
     @Foo  INT 

SELECT @IsValid = IsValid, 
     @Foo = Foo 
FROM [Stuff] 
WHERE StuffId = @StuffId 

/*This must be tested immediately after the assignment statement*/ 
IF @@ROWCOUNT = 0 
    RETURN -1 

IF ISNULL(@IsValid, 0) = 0 
    RETURN -2 

SELECT @IsValid AS IsValid, 
     @Foo  AS Foo 
+0

確實這是一個更好的方法,謝謝! – 2012-01-12 12:26:09

+0

+1我只是在輸入相同的解決方案。 – Mack 2012-01-12 12:31:23