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

发布于 2024-10-17 09:29:57 字数 598 浏览 2 评论 0原文

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

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 作为参数?

I have a SQL statement in C# (.NET Framework 4 running against SQL Server 2k8) that looks like this:

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

The above query works fine with the following ADO.NET code:

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

This query returns zero rows, though, if I assign DBNull.Value to the DbParameter's Value member even if there are null values in Column2. If I change the query to accommodate the null test specifically:

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

I get an "Incorrect syntax near '@Column2'" exception at runtime. Is there no way that I can use null or DBNull as a parameter in the WHERE clause of a SELECT statement?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱她像谁 2024-10-24 09:29:57
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

SELECT [Column1] 
FROM [Table1] 
WHERE [Column2] = @Column2  OR (@Column2 IS NULL AND [Column2] IS NULL)

But I'm not sure how sargable this is.

Edit: This looks fine actually and ends up with an index seek at least in 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

场罚期间 2024-10-24 09:29:57

您可以使用

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

“值”可以是您希望它代表的任何值。如果你想匹配具有空列的column2,

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

you may use

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

'value' can be any value that u want it to represent. If you want to match column2 that has null columns,

SELECT [Column1] FROM [Table1] WHERE ISNULL([Column2], 'value') = ISNULL(@Column2 , 'value');
巴黎盛开的樱花 2024-10-24 09:29:57

您可以使用:

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

问候!

You can use:

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

regards!

So要识趣 2024-10-24 09:29:57

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

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

SET ANSI_NULLS OFF

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

看看下面的 文章 以获得一些额外的见解。

Are you sure that they the values are NULL and not just empty strings? If it's the latter, it would indeed not return any record. And as Joel stated in his answer, yoou should allways change your null to DbNull.Value in your C#-code. If it's the first you should compare to '' instead.

If the data is indeed NULL, maybe you can try this statement (if you're using stored procedures):

SET ANSI_NULLS OFF

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

Take a look at the folowing article for some extra insight.

记忆之渊 2024-10-24 09:29:57

将第二行更改为:

parm.Value = DbNull.Value;

这就是您所要做的,真的。在这种情况下,不必担心 =IS

在我看来,我们在项目之间共享的自主开发的数据访问层还会自动检查所有查询参数,并在执行查询之前将任何 C# null 替换为 DbNull.Value

Change your second line to this:

parm.Value = DbNull.Value;

That's all you have to do, really. Don't worry about the = vs IS in this instance.

Where I'm at, our homegrown data access tier that we share among projects also checks all query parameters automatically and replaces any C# null with DbNull.Value before executing the query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文