如何确定参数值是否已传递给存储过程

时间:2011-08-12 17:02:43

标签: sql-server-2008 stored-procedures dbnull

我想创建一个存储过程(在SQL Server 2008 R2中),它将根据表的PK更新表中的记录。

存储过程将具有例如四个参数:

@ID int,
@Name nvarchar(50),
@Email nvarchar(80),
@Phone nvarchar(20)

如果调用者没有为一个(或多个)参数传递任何内容,我如何确定存储过程的调用者是否为一个(或多个)参数传递NULL值?

C#来电示例:

来电者为NULL指定@Phone

using (SqlCommand cmd = new SqlCommand())
{
  cmd.CommandType = System.Data.CommandType.StoredProcedure;
  cmd.CommandText = "EditPerson";
  cmd.Parameters.AddWithValue("@ID", id);
  cmd.Parameters.AddWithValue("@Name", 'Frank');
  cmd.Parameters.AddWithValue("@Email", 'frank@frank.com');
  cmd.Parameters.AddWithValue("@Phone", DBNull.Value);
  DatabaseManager.instance.ExecuteScalarQuery(cmd);
}

来电者忽略@Phone参数:

using (SqlCommand cmd = new SqlCommand())
{
   cmd.CommandType = System.Data.CommandType.StoredProcedure;
   cmd.CommandText = "EditPerson";
   cmd.Parameters.AddWithValue("@ID", id);
   cmd.Parameters.AddWithValue("@Name", 'Frank');
   cmd.Parameters.AddWithValue("@Email", 'frank@frank.com');
   DatabaseManager.instance.ExecuteScalarQuery(cmd);
}

我在这里要完成的是,如果调用者为参数显式指定NULL值,那么我将使用NULL值更新记录。但是,如果用户显式忽略传递参数,则UPDATE查询将保留已为特定记录设置的字段/列的值(即查询不会更新该特定列)。

我想我可以指定默认值,可以安全地假设调用者永远不会使用 - 如下所示:

@ID int,
@Name nvarchar(50) = 'NameIsUndefined',
@Email nvarchar(80) = 'EmailIsUndefined',
@Phone nvarchar(20) = 'PhoneIsUndefined'

然后,在存储过程中,我可以检查未定义的值 - 如果参数变量仍然设置为NameIsUndefinedEmailIsUndefined和/或PhoneIsUndefined值,则我可以放心地假设调用者没有明确定义这些参数的值。这是实现目标的唯一途径吗?

2 个答案:

答案 0 :(得分:6)

如果你声明你的参数(没有默认值),那么存储过程将需要它们全部四个,如果它们中的任何一个都不会被传递给提供者组成的EXEC语句,那么它将失败。

您可以声明一些可选的参数,如下所示:

@Phone nvarchar(20) = NULL

但是,如果省略或明确设置为NULL,将无法在sproc内部进行判断。

答案 1 :(得分:1)

在SQL Server,AFAIK中无法区分NULL和NULL。

在你的C#代码中,我会A)传递另一个值,就像一个空字符串,表示传递了一个空值,然后在SQL中处理该值,如果值被传递则将NULL写入数据库,或保留前一个值如果变量为NULL,则为值,或者B)不传递DBNull.Value,而是传递从DB读取的先前值。