SqlDataReader如何判断数据字段是否可为空。

7

在.NET中,我是否可以确定任何任意的SQL Server结果集中,给定的结果集列是否可以包含空值?

例如,如果我有以下语句:

Select NullableColumn From MyTable

and

Select IsNull(NullableColumn, '5') as NotNullColumn From MyTable

我得到了一个数据阅读器,就像这样:

var cmd = new SqlCommand(statement, connection);
var rdr = cmd.ExecuteReader();

我可以提供这样的函数吗?
bool ColumnMayHaveNullData(SqlDataReader rdr, int ordinal)
{
   //????
}

我希望第一个语句返回true,第二个语句返回false。

rdr.GetSchemaTable() 无法实现此功能,因为它返回的是底层列是否可以为空,而这不是我想要的。虽然datareader上有一些函数可以返回字段的底层SQL类型,但没有一个能告诉我它是否可以为空。


1
我可以问一下你想知道的原因吗? - tomfanning
@tomfanning 我正在破解一个ORM。我想记录每当有人尝试运行一个查询,其中可空的数据库字段映射到非可空值类型时的情况。 - dan
2个回答

1
我有点困惑:
“因为它返回的是底层列是否可为空,这不是我想要的。”
“但似乎没有一个告诉我它是否可以为空。”
你可以查询底层表格以查看列是否可为空(假设这是你想要的)。
SELECT IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'MyTable' AND COLUMN_NAME = 'MyColumn'

我想知道结果集中的某一列是否可以包含空值,而不是底层表中的列是否可以包含空值。在我的示例中,我在选择语句中使用IsNull()将空值转换为非空值。在这种情况下,即使底层表列可以包含空值,结果集列也不能包含空值。 - dan
结果集列仍然可以包含空值,但您已将所有空值替换为非空值。因此,您想知道数据是否“清洗干净”?您可以检索相同的列两次...一次是原始列带有空值,另一次是同一列的已清理版本。 - Steve Wellens
如果我已经用非空值替换了所有的空值,那么结果集列就不包含空值。这就是我想找出的,但是不想通过循环遍历行来查看单个值。基本上,我正在尝试在运行时验证临时查询与对象模型是否匹配。你和我可以通过查看查询来判断哪些结果列可能包含空值,因此应该有一种方法编写一个函数来解决这个问题。 - dan
在我看来,使用isnull在返回null的查询中并不是正统的方式(尽管你的情况可能有所不同)。上帝创造了可空类型,以便将其映射到可空结果字段,然后我们在poco的属性实现中调用GetValueOrDefault,这样一切都很干净;-) - luckyluke

1

很不幸,你不能这样做,因为SQL服务器无法确定字段是否可为空。你可以对结果集中的字段进行任意转换(运算符、函数调用等),这些转换没有关于它们是否能返回null的元数据。所以你必须手动找出这个问题或使用具有架构绑定的视图...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接