如何将DBNull值传递给参数化的SELECT语句?
问题描述:
我在C#中的SQL语句(.NET Framework 4的对SQL Server 2K8运行),看起来像这样:如何将DBNull值传递给参数化的SELECT语句?
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中有空值,该查询也会返回零行。如果我更改查询以适应空测试:
我在运行时发现“@ Column2附近的语法错误”异常。有没有办法可以在SELECT语句的WHERE子句中使用null或DBNull作为参数?
答
您可以使用
SELECT [Column1] FROM [Table1] WHERE [Column2] = ISNULL(@Column2 , 'value');
“值”可以是ü希望它来表示任何价值。如果你想匹配COLUMN2具有空列,
SELECT [Column1] FROM [Table1] WHERE ISNULL([Column2], 'value') = ISNULL(@Column2 , 'value');
答
你的第二个线就改成这样:
parm.Value = DbNull.Value;
这就是你需要做的,真的。在这种情况下,不要担心=
与IS
。
我在哪里,我们在项目之间共享的本地数据访问层也会自动检查所有查询参数,并在执行查询之前用DbNull.Value
替换任何C#null
。
答
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#代码中将你的null
更改为DbNull.Value
。如果是第一个,则应该与''
进行比较。
如果数据确实是空的,也许你可以试试这个声明(如果你使用存储过程):
SET ANSI_NULLS OFF
SELECT [Column1] FROM [Table1] WHERE [Column2] = NULL
看看如下因素article一些额外的洞察力。
记住null不等于null。尝试使用LIKE而不是IS – albanx 2011-02-14 22:52:45
一注。将字符串字段设置为非空值并且不用担心这样的问题是值得的。添加OR或ISNULL或COALESCE可以真正达到性能。 – LukLed 2011-02-14 23:14:54
@LukLed - 在我的答案中看到执行计划`OR`在那里似乎没有问题。 `WHERE [Column2] = @ Column2 OR(@ Column2 IS NULL AND [Column2] IS NULL)`似乎是一个可识别的模式,最后只是一个简单的索引查找。 – 2011-02-14 23:18:00