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

时间:2011-02-14 22:43:04

标签: c# sql-server ado.net

我在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中有空值也是如此。如果我更改查询以特别适应空测试:

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

我在运行时遇到“@ Column2'附近的”语法不正确“异常。我无法在SELECT语句的WHERE子句中使用null或DBNull作为参数吗?

5 个答案:

答案 0 :(得分:4)

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

Plan

答案 1 :(得分:2)

你可以使用

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

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

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

答案 2 :(得分:0)

您可以使用:

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();

问候!

答案 3 :(得分:0)

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

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

SET ANSI_NULLS OFF

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

请查看以下article以获得更多见解。

答案 4 :(得分:-1)

只需将第二行更改为:

parm.Value = DbNull.Value;

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

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

相关问题