如何将DBNull值传递给参数化的SELECT语句?

我在C#(针对SQL Server 2k8运行的.NET Framework 4)中有一个SQL语句,如下所示:

SELECT [Column1] FROM [Table1] WHERE [Column2] = @Column2 

以上查询可以使用以下ADO.NET代码正常工作:

 DbParameter parm = Factory.CreateDbParameter(); parm.Value = "SomeValue"; parm.ParameterName = "@Column2"; //etc... 

但是,如果我将DBNull.Value分配给DbParameter的Value成员,即使Column2中有空值,此查询也返回零行。 如果我更改查询以特别适应null测试:

 SELECT [Column1] FROM [Table1] WHERE [Column2] IS @Column2 

我在运行时遇到“@ Column2’附近的语法错误”exception。 我无法在SELECT语句的WHERE子句中使用null或DBNull作为参数吗?

你可以用

 SELECT [Column1] FROM [Table1] WHERE [Column2] = ISNULL(@Column2 , 'value'); 

‘value’可以是您希望它表示的任何值。 如果要匹配具有空列的column2,

 SELECT [Column1] FROM [Table1] WHERE ISNULL([Column2], 'value') = ISNULL(@Column2 , 'value'); 
 SELECT [Column1] FROM [Table1] WHERE [Column2] = @Column2 OR (@Column2 IS NULL AND [Column2] IS NULL) 

但我不确定这是多么可怕。

编辑:这实际上看起来很好,最终至少在2008年寻找索引

 CREATE TABLE [Table1] ( [Column1] INT, [Column2] INT ) CREATE CLUSTERED INDEX [IX] ON [dbo].[Table1] ([Column2] ASC) INSERT INTO [Table1] VALUES(1,NULL) INSERT INTO [Table1] VALUES(2,NULL) INSERT INTO [Table1] VALUES(3,1) INSERT INTO [Table1] VALUES(4,1) GO CREATE PROC foo @Column2 INT AS SELECT [Column1] FROM [Table1] WHERE [Column2] = @Column2 OR (@Column2 IS NULL AND [Column2] IS NULL) GO EXEC foo NULL EXEC foo 1 

计划

您可以使用:

 var cmd =new SqlCommand("SELECT ISNULL([Column1],'VALUE') as [Column1] FROM [Table1] WHERE [Column2] = @Column2"), con) string a; if(textbox.text == string.empty) { a = DbNull.Value} else { a =textbox.text} cmd.Parameters.AddWithValue("@Column2",a); cmd.ExecuteNonQuery(); 

问候!

你确定它们的值是NULL而不仅仅是空字符串吗? 如果是后者,它确实不会返回任何记录。 正如Joel在他的回答中所述,你应该总是在你的C#代码DbNull.Value你的null改为DbNull.Value 。 如果它是第一个你应该与''相比。

如果数据确实为NULL,也许您可​​以尝试此语句(如果您使用的是存储过程):

 SET ANSI_NULLS OFF SELECT [Column1] FROM [Table1] WHERE [Column2] = NULL 

看看下面的文章 ,了解一些额外的见解。

只需将第二行更改为:

 parm.Value = DbNull.Value; 

这就是你所要做的一切,真的。 在这种情况下,不要担心= vs IS

在我所处的位置,我们在项目中共享的本地数据访问层也会自动检查所有查询参数,并在执行查询之前用DbNull.Value替换任何C# null