2014-02-20 31 views
11

問題
當值被提供給下面的腳本然後使用C#的設置像下面執行(或在SQL Server環境)的值不更新數據庫中。SQL Server存儲過程可爲空的參數

存儲過程:

-- Updates the Value of any type of PropertyValue 
-- (Type meaining simple Value, UnitValue, or DropDown) 
CREATE PROCEDURE [dbo].[usp_UpdatePropertyValue] 
    @PropertyValueID int, 
    @Value varchar(max) = NULL, 
    @UnitValue float = NULL, 
    @UnitOfMeasureID int = NULL, 
    @DropDownOptionID int = NULL 
AS 
BEGIN 
    -- If the Property has a @Value, Update it. 
    IF @Value IS NOT NULL 
    BEGIN 
     UPDATE [dbo].[PropertyValue] 
     SET 
      Value = @Value 
     WHERE 
      [dbo].[PropertyValue].[ID] = @PropertyValueID 
    END 
    -- Else check if it has a @UnitValue & UnitOfMeasureID 
    ELSE IF @UnitValue IS NOT NULL AND @UnitOfMeasureID IS NOT NULL 
    BEGIN 
     UPDATE [dbo].[UnitValue] 
     SET 
      UnitValue = @UnitValue, 
      UnitOfMeasureID = @UnitOfMeasureID 
     WHERE 
      [dbo].[UnitValue].[PropertyValueID] = @PropertyValueID   
    END 
    -- Else check if it has just a @UnitValue 
    ELSE IF @UnitValue IS NOT NULL AND @UnitOfMeasureID IS NULL 
    BEGIN 
     UPDATE [dbo].[UnitValue] 
     SET 
      UnitValue = @UnitValue 
     WHERE 
      [dbo].[UnitValue].[PropertyValueID] = @PropertyValueID 
    END 
    -- Else check if it has a @DropDownSelection to update. 
    ELSE IF @DropDownOptionID IS NULL 
    BEGIN 
     UPDATE [dbo].[DropDownSelection] 
     SET 
      SelectedOptionID = @DropDownOptionID 
     WHERE 
      [dbo].[DropDownSelection].[PropertyValueID] = @PropertyValueID 
    END 
END 

當我做這個腳本的執行,如下面,它不會更新任何值。

實施例執行:

String QueryString = "EXEC [dbo].[usp_UpdatePropertyValue] @PropertyValueID, @Value, @UnitValue, @UnitOfMeasureID, @DropDownOptionID"; 
SqlCommand Cmd = new SqlCommand(QueryString, this._DbConn); 

Cmd.Parameters.Add(new SqlParameter("@PropertyValueID", System.Data.SqlDbType.Int)); 
Cmd.Parameters.Add(new SqlParameter("@Value", System.Data.SqlDbType.Int)); 
Cmd.Parameters.Add(new SqlParameter("@UnitValue", System.Data.SqlDbType.Int)); 
Cmd.Parameters.Add(new SqlParameter("@UnitOfMeasureID", System.Data.SqlDbType.Int)); 
Cmd.Parameters.Add(new SqlParameter("@DropDownOptionID", System.Data.SqlDbType.Int)); 

Cmd.Parameters["@PropertyValueID"].Value = Property.Value.ID; // 1 
Cmd.Parameters["@Value"].IsNullable = true; 
Cmd.Parameters["@Value"].Value = DBNull.Value; 
Cmd.Parameters["@UnitValue"].IsNullable = true; 
Cmd.Parameters["@UnitValue"].Value = DBNull.Value; 
Cmd.Parameters["@UnitOfMeasureID"].IsNullable = true; 
Cmd.Parameters["@UnitOfMeasureID"].Value = DBNull.Value; 
Cmd.Parameters["@DropDownOptionID"].IsNullable = true; 
Cmd.Parameters["@DropDownOptionID"].Value = 2; // Current Value in DB: 3 

詳細說明:

運行的執行(通過C#代碼或SQL Server環境)後它不更新dbo.DropDownSelection.SelectedOptionID。我猜測這可能是因爲dbo.DropDownSelection.SelectedOptionID是不可空的,我用來設置它的參數是可以爲空的(儘管設置時它不應該爲空)。在執行時,返回值爲0.如果我在程序之外運行其中一個更新程序,它們完美地工作,因此我懷疑它與無效類型有關。

問題(S):

難道這是因爲參數存儲過程可以爲空,我設置的字段都沒有?

如果不是,它會是什麼?

+1

如果將這些插入和更新更改爲選擇,是否返回提供的參數的數據? – TTeeple

+0

是的。我更新了我的問題,並補充道:「如果我在程序之外運行其中一個更新程序,那麼它們完美地工作,因此我懷疑它與無效類型有關。」 – Shelby115

+0

1)我澄清了我的問題。我不想做輸出參數。 2)存儲過程表示它執行並返回0,但值永遠不會更新。我不確定你的意思是「通過SQL塊」。 – Shelby115

回答

8

它看起來像你傳遞NULL爲每個參數,除了PropertyValueID和DropDownOptionID,對吧?如果只有這兩個值不爲空,我認爲你的任何IF語句都不會觸發。總之,我認爲你有一個邏輯錯誤。

除此之外,我建議兩件事情......

第一,而不是測試NULL,使用這種語法在你的if語句(它的安全)......

ELSE IF ISNULL(@UnitValue, 0) != 0 AND ISNULL(@UnitOfMeasureID, 0) = 0 

其次,在每個UPDATE之前添加一個有意義的PRINT語句。這樣,當你在MSSQL中運行這個存儲過程時,你可以看看這些消息,看看它到底有多遠。

+0

哇,我感到啞巴。它應該是'ELSE IF @DropDownOptionID不是NULL',就像其他人一樣:/謝謝。 – Shelby115

+10

如何使用'ISNULL(...'比'... IS NULL'更安全?看起來你的建議*少*安全,因爲至少有一個原因,現在你有一個魔術值(零),即視爲等價於'NULL',如果要使用或允許使用空值,則測試'NULL'和'NULL'是最安全的事情。 –

0

你可以/應該設置你的參數值爲DBNull.Value;

if (variable == "") 
{ 
    cmd.Parameters.Add("@Param", SqlDbType.VarChar, 500).Value = DBNull.Value; 
} 
else 
{ 
    cmd.Parameters.Add("@Param", SqlDbType.VarChar, 500).Value = variable; 
} 

或者您可以將您的服務器端設置爲空,並且根本不傳遞參數。

相關問題