2014-02-20 27 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; 
} 

或者您可以将您的服务器端设置为空,并且根本不传递参数。

相关问题