System.Data.SqlClient.SqlParameter.IsNullable 的目的是啥?

Posted

技术标签:

【中文标题】System.Data.SqlClient.SqlParameter.IsNullable 的目的是啥?【英文标题】:What is the purpose of System.Data.SqlClient.SqlParameter.IsNullable?System.Data.SqlClient.SqlParameter.IsNullable 的目的是什么? 【发布时间】:2011-04-28 16:23:30 【问题描述】:

我目前正在尝试为数据库中的所有存储过程编写一个简单的 C# 包装类。

在 C# 中构建一些参数时,我注意到属性 SqlParameter.IsNullable 并想知道这是做什么用的。据我所知,不可能将存储过程参数声明为 NOT NULL,因此始终允许将 NULL 传递给任何参数。

通过测试,将IsNullable属性设置为false似乎没有效果,仍然允许SqlParameter.Value属性设置为null。

谁能解释一下这个属性的用途?

感谢收看。

寻找赏金的回答者应查看这些链接:

How to restrict NULL as parameter to stored procedure SQL Server?

SQL Parameter IsNullable

I assume SqlParameter.IsNullable only makes sense when…?

http://social.msdn.microsoft.com/forums/en-US/vblanguage/thread/b7a08616-58d1-4cdc-a3e9-9353e292667b

【问题讨论】:

@M.R.我不确定你所说的 null 指令是什么意思。您是否在谈论将默认值设置为 null 即:@MyInt int = null 您能否提供一个带有和不带有此“null 指令”的参数声明示例 恐怕你错了。默认值(或您称其为 null 指令)仅指示在未提供参数时将参数设置为什么值。它与参数将接受或不接受什么值无关。 Null 总是可以传递给任何参数。 '@MyInt int' 只是意味着您必须提供一个参数,但是您可以将参数设置为 Null。 尽管这被标记为 SQL Server 可能值得指出它来自System.Data.IDataParameter 接口,该接口也由System.Data.OracleClient.OracleParameter 实现,因此在SqlParameter 上下文中可能无效? @MartinSmith 是的,我认为您就在那儿,我认为这是不适用于 SqlServer 的界面遗留物。也许在与其他数据库提供者打交道时,这个属性有一些意义和相关性。 【参考方案1】:

SqlParameter类继承自抽象基类DbParameter,它定义了

    public abstract bool IsNullable get; set;

所以SqlParameter 需要公开实现IsNullable 属性。 DbParameter 类是 System.Data 中包含的所有数据库参数实现的基类。

我们必须假设还有其他 DBMS 显式允许或拒绝将过程或函数参数显式定义为可空或不可空,并且SqlParameter.IsNullable 仅存在是因为 SqlParameter 实现了更通用的通用数据库参数类和接口是其他 .NET 数据库交互类所共有的。

查看反射器,SqlParameter 类不使用IsNullable,除了在转换为“InstanceDescriptor”时传递值。我没有深入研究InstanceDescriptor 类的用途,但我确实查看了SqlCommand 类,尤其是BuildParamList 方法,该方法将SqlParameterCollection 转换为发送到数据库的SQL 参数字符串.

BuildParamList 方法循环通过SqlParameterCollection,并使用StringBuilder 构建参数字符串。 BuildParamList 不会在其实现的任何地方使用 IsNullable 属性或值。事实上,对 SqlParameter.IsNullable 的引用不会出现在 SqlCommand 类中的任何位置。

我可能在一些将SqlParameter 对象传递给不同类的内部/私有方法中错过了对它的引用,但如果BuildParamList 方法不使用它,那没关系,因为它是不影响发送到 SQL Server 的 SQL 字符串。

除了您执行的测试用例之外,检查SqlCommand 类的内容支持您可以放心地忽略SqlParameter.IsNullable 属性值的结论。

SQL Server 端正在处理中,我在 Internet 上进行了快速搜索,看看是否可以找到任何允许显式可为空/不可为空的过程或函数参数的 DBMS。当我遇到一个 DB2 引用时,我停下了脚步,该引用似乎需要在过程上设置特定属性以允许将空值传递给它。我不知道任何具有此功能的当代 RDBMS,而且我的搜索没有产生任何其他结果。

【讨论】:

感谢您的深入研究。我认为这证明了它在 SqlParameter 中没有影响,并且由于底层接口,它只是一个实现要求。很遗憾 1) 文档没有这样说 2) 对于 SQL Server,它似乎并没有始终正确设置为 true,因为 SQL Server 总是允许传递 NULL,所以如果你检查这个以获得一些关于界面的想法,是不正确的。【参考方案2】:

查看链接并阅读 MSDN 上的几篇文章后。

SqlParameter.IsNullable Property 实现接口IDataParameter.IsNullable 并阅读一篇文章,其中指出“使用 DBNull 类处理空值”

DBNull 类只实现了一个接口方法IConvertible.ToType 基础设施。将当前 DBNull 对象转换为指定的类型。”其中还指出“DBNull.Value 可用于显式为数据库字段分配不存在的值,尽管大多数 ADO.NET 数据提供程序在字段不存在时自动分配 DBNull 值一个有效的值”

读到这意味着大多数 ADO.NET 类自动实现了这个属性,并在图片后面进行 NULL 到 DBNull 的类型转换。根据我的理解,我假设我们是writing our own API 例如(System.Data.CustomDatabaseClient,而不是System.Data.SqlClient)用于建立连接和其他数据库任务,并且我没有实现这个属性,那么任何使用 System.Data.CustomDatabaseClient 的人都必须将 Null 值显式转换为 DBNull。

寻找您的 cmets 和任何修正

【讨论】:

以上是关于System.Data.SqlClient.SqlParameter.IsNullable 的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章