2011-08-29 206 views
0

這可能更像是一個「最佳實踐」問題,而不是真正的代碼問題。在另一個存儲過程中獲取存儲過程的參數。

我有一個存儲過程來更新表,但需要從另一個表中的幾個值。

前兩個選項從表中獲取值,然後用於更新語句中。

的選擇statments:

Select @iStatusDropDownValueID = iDropDownValueID 
     From DropDownValue 
     Inner Join DropDownValueType On DropDownValue.iDropDownValueTypeID = DropDownValueType.iDropDownValueTypeID 
     Where DropDownValueType.vchDropDownValueTypeName = 'Status' 
     AND DropDownValue.vchDropDownValueName = 'Scheduled' 
     AND DropDownValue.tiRecordStatus = 1 
     And DropDownValueType.tiRecordStatus = 1 

Select @iLastStatusDropDownValueID = iDropDownValueID 
     From DropDownValue 
     Inner Join DropDownValueType On DropDownValue.iDropDownValueTypeID = DropDownValueType.iDropDownValueTypeID 
     Where DropDownValueType.vchDropDownValueTypeName = 'Status' 
     AND DropDownValue.vchDropDownValueName = 'CriticalErrorOccurred' 
     AND DropDownValue.tiRecordStatus = 1 
     And DropDownValueType.tiRecordStatus = 1 

UPDATE語句:

Update Schedule 
    Set 
     iStatusDropDownValueID = @iStatusDropDownValueID, 
     iLastStatusDropDownValueID = @iLastStatusDropDownValueID, 
     iCurrentLogID = @iCurrentLogID, 
     dtNextDate = @dtNextDate, 
     dtLastDate = @dtLastDate, 
     iRetryCount = @iRetryCount, 
     iFailedCount = @iFailedCount, 
     iBusyRetryCount = @iBusyRetryCount, 
     vchUpdateBy = @vchUpdateBy, 
     dtUpdateDate = @dtLastDate 
    WHERE 
     iScheduleID = @iScheduleID 

首先,由前兩個select語句檢索的值總是相同的。所以他們可以通過代碼本身傳入。我不知道這會加快速度,只是讓整個存儲過程更好,更易於閱讀。其次,如果「數值名稱」應該改變,這個存儲過程將會中斷(這是可能的,但不經常)。

我在尋找任何有關這種情況的最佳做法的見解。

回答

1

我個人總是聲明我的變量,不要使用@vars。
@vars就像變種,他們不保護你免受錯別字。
如果你使用明確聲明的變量,MySQL會警告你反對錯別字,你的變量將被打字,使你的意圖更清晰,你的代碼稍快。

CREATE PROCEDURE (IN a INTEGER) 
BEGIN 
    DECLARE var1 INTEGER; 
    DECLARE var2 INTEGER; 
    DECLARE initialized_var INTEGER DEFAULT 0; 

    SET var = 1; //to just set a var. 
    SELECT myfield INTO var2 FROM atable WHERE a <> atable.b ORDER BY b LIMIT 1; 
    //Always use `limit 1` here. 
    //use `select into ...order by .. limit 1` to make you queries repeatable. 
    //The limit 1 also speeds up things a bit. 
    //make sure to test SELECT INTO vars against `null` 
    IF var2 IS NULL THEN ..... 

如果你需要使用一個存儲過程的結果,爲什麼不做一個存儲函數。

CREATE FUNCTION pi RETURNS float 
BEGIN 
    RETURN 3.14; 
END $$ 

然後,你可以只寫像查詢:

INSERT INTO atable (math_constants) VALUES (pi()); 
+0

你提出了一些我不知道你可以做的事情。太棒了!我看到使用函數的唯一問題是,如果名稱更改,函數仍然會中斷。 –

+0

@Andy,爲什麼函數會中斷?只要在失敗時返回null,然後在函數中測試它。 – Johan

+0

你是對的,他們不會失敗。我在想,如果價值因任何原因而改變。但在這種情況下,該值永遠不會改變下拉列表名稱。 –

0

也許我失去了一些東西,但如果檢索的值是真正不變的,爲什麼在通過他們或檢索它們在所有?您可以簡單地將它們硬編碼。

在這種情況下,我傾向於這樣做,因爲它不僅消除了檢索查詢的開銷,還消除了潛在的故障點(您提到的「值名稱」更改問題)。

+0

失敗正是發生的事情。代碼爲這兩個值傳遞一個0值,然後有一個額外的條件語句來獲取這些值(如果需要的話)。條件不正確,因此值始終爲0,導致外鍵異常。 –

相關問題