我的表中的这个列可以为空,当我执行一个通过SQL Server管理器执行插入的存储过程时,我对该列的参数有一个空值,它不会抱怨和工作
EXEC @return_value = my_store_proc
@my_last_name = NULL, ...
但在我的C#代码中,我正在构建它所抱怨的参数
System.Data.SqlClient.SqlException : Procedure or function 'my_store_proc' expects
parameter ' @my_last_name', which was not supplied.
这是我的C#代码
command.Parameters.AddWithValue("@my_last_name ", null);
但是当我用空字符串替换null时,它完全正常。我不知道为什么它不喜欢这里的null。此外,我尝试使用DbNull.value
代替null,但在尝试添加引用时似乎无法找到System.DBNull
,因此我正在寻找其他替代方法。
答案 0 :(得分:1)
在这种情况下,您必须使用System.DBNull.Value。否则,该参数假定您未传递参数,而不是传递空值。
System.DBNull基本上始终可用,如果你找不到它,那么可能会发布错误信息。
答案 1 :(得分:0)
您可以更改存储过程的签名以使参数具有默认的空值,然后只是不将该参数附加到您的命令。 ADO.NET不够智能,无法区分显式传递空参数值或仅传递必需参数。
答案 2 :(得分:0)
首先,不要使用.AddWithValue()
方法。它使得.Net猜测用于参数的类型,有时.Net会弄错。通常当发生这种情况时代码仍然可以工作,但它会强制Sql Server做一些额外的工作来执行额外的转换。有时当发生这种情况时,它会破坏Sql Server使用索引的能力,这会导致非常大的性能损失。使用您提供特定类型的.Add()
重载之一。
所以你可以这样编写代码:
//The "50" here is a guess. Replace it with the actual column length
command.Parameters.Add("@my_last_name ", SqlDbType.NVarChar, 50).Value = DBNull.Value;
如果你有很多参数,其中几个可以是null
,我喜欢这样做:
command.Parameters.Add("@my_last_name ", SqlDbType.NVarChar, 50).Value = someVariableThatCouldBeNull;
// Other parameter
// Third Parameter
// fourth
// etc
foreach (var p in command.Parameters.Where(p => p.Value == null))
{ p.Value = DBNull.Value;}
DBNull
是System
命名空间的一部分,它包含在提供int
和string
等核心类型的同一个程序集中,因此不应该有任何内容额外需要使用它。