带参数的访问查询在 Access 中有效,在 C# 中无效
Posted
技术标签:
【中文标题】带参数的访问查询在 Access 中有效,在 C# 中无效【英文标题】:Access query with parameters works in Access, not in C# 【发布时间】:2014-04-09 14:23:32 【问题描述】:我有一个可以在 Access 中完美运行的查询,但在 C# 中似乎无法运行。我很确定它与我添加的参数有关,因为如果我用“#”符号对日期进行硬编码,那么它可以正常工作。有谁知道这里的解决方案是什么?提前感谢
string queryAccessNewHires =
@"SELECT cdate([Date of Hire]), Count([SSN]) AS DateCount
FROM [FED]
WHERE
IIf(
IsNull([Date of Hire]), False,
IIf([Date of Hire] <> 'DoesNotApply'
AND [Date of Hire] <> ""
AND CDate([Date of Hire]) > CDate(PBP)
AND CDate([Date of Hire]) < CDate(PBE), True, False
)
)
GROUP BY [Date of Hire]
ORDER BY [Date of Hire]";
OleDbCommand cmdNewHires = new OleDbCommand(queryAccessNewHires, conn);
cmdNewHires.Parameters.AddWithValue("PBP", tbTYB.Text);
cmdNewHires.Parameters.AddWithValue("PBE", tbTYE.Text);
编辑:: 感谢您的帮助。而不是收到“查询表达式中的语法错误”错误,它似乎是在我更改代码时理解我想要的。但是我收到的新错误是:“OleDbParameterCollection 只接受非空 OleDbParameter 类型对象,而不接受字符串对象”
string queryAccessNewHires = @"SELECT cdate([Date of Hire]), Count([SSN]) AS DateCount
FROM [FED]
WHERE IIf(IsNull([Date of Hire]),False,
IIf([Date of Hire]<>'DoesNotApply'
AND [Date of Hire]<>""
AND CDate([Date of Hire])>CDate(?)
AND CDate([Date of Hire])<CDate(?), True, False))
GROUP BY [Date of Hire]
ORDER BY [Date of Hire]";
OleDbCommand cmdNewHires = new OleDbCommand(queryAccessNewHires, conn);
cmdNewHires.Parameters.Add(tbTYB.Text);
cmdNewHires.Parameters.Add(tbTYE.Text);
编辑: 仍然没有找到解决方案。我在想我可能使这变得比它需要的更难,所以我想向你们展示我想从 C# 运行的原始查询。 [Date of Hire] 是一个 varchar,需要转换。我不能改变设计。此查询返回“无效使用 null”。我不明白为什么这个查询没有执行。
SELECT cdate([Date of Hire]), Count([SSN]) AS DateCount
FROM [FED]
WHERE (CDate([Date of Hire]) > #1/1/2013#
AND CDate([Date of Hire]) < #12/31/2013#)
GROUP BY [Date of Hire]
ORDER BY [Date of Hire]
【问题讨论】:
不工作是指它抛出错误还是不返回数据? 我坚信你不能在你自己的应用程序中使用在 Access 中工作的 VBA 东西。 IE。IIf
、CDate
、IsNull
等
@UweKeim IsNull、CDate 和 IIf 不是“VBA 的东西”,有 Jet/ACE 的东西,并且在 MS Access 之外可以正常工作。
谢谢,@Remou 你确定吗? IIRC我过去尝试过类似上面的代码但没有成功。很高兴听到!
@UweKeim 我刚刚用 C# 和 ACE 进行了测试,虽然看到我已经在经典 ASP 中使用了一些这些东西,但我真的不需要:)
【参考方案1】:
您需要使用?
,因为OleDBCommand.Parameters
不支持命名参数。
OleDbCommand.Parameters Property
OLE DB .NET 提供程序不支持传递命名参数 SQL 语句或存储过程的参数 当 CommandType 设置为 Text 时的 OleDbCommand。在这种情况下, 必须使用问号 (?) 占位符。
因此,OleDbParameter 对象添加到 OleDbParameterCollection 必须直接对应的位置 命令文本中参数的问号占位符。
所以你的代码是这样的:
string queryAccessNewHires = @"SELECT cdate([Date of Hire]), Count([SSN]) AS DateCount
FROM [FED]
WHERE IIf(IsNull([Date of Hire]),False, IIf([Date of Hire]<>'DoesNotApply' AND [Date of Hire]<>"" AND CDate([Date of Hire])>CDate(?) AND CDate([Date of Hire])<CDate(?), True, False))
GROUP BY [Date of Hire]
ORDER BY [Date of Hire]";
OleDbCommand cmdNewHires = new OleDbCommand(queryAccessNewHires, conn);
cmdNewHires.Parameters.Add(tbTYB.Text);
cmdNewHires.Parameters.Add(tbTYE.Text);
【讨论】:
也谢谢你。但是,我现在遇到了一个新错误。 "OleDbParameter Collection 只接受非空类型对象,不接受字符串对象" 我已经评论了上面的命名参数。 @Remou,所以可以使用任何字符代替?
,但只有顺序很重要?这是一个很好的观点,我不想意识到这一点。当然 MSDN 文档具有误导性。
@Remou,但它如何区分查询中的参数和其他文本?
?和 @ 符号似乎是我快速测试中唯一触发参数的符号。【参考方案2】:
由于您使用OleDb
,看来您需要使用?
作为参数。它不支持命名参数。
来自OleDbCommand.Parameters
property
OLE DB .NET 提供程序不支持传递命名参数 SQL 语句或存储过程的参数 当 CommandType 设置为 Text 时的 OleDbCommand。 在这种情况下, 必须使用问号 (?) 占位符。例如:
SELECT * FROM Customers WHERE CustomerID = ?
AND CDate([Date of Hire]) > CDate(?)
AND CDate([Date of Hire]) < CDate(?), True, False
作为雷某said;
'不支持命名参数'只是意味着它只会 通过位置识别参数,而不是不能使用名称。 您不必使用?,您只需要确保订单是 正确。
【讨论】:
啊,我明白了,我不知道。谢谢你。但是,我现在收到一个不同的错误。 "OleDbParameter Collection 只接受非空类型对象,不接受字符串对象" '不支持命名参数'只是意味着它只会通过位置识别参数,而不是你不能使用名称。您不必使用?,您只需确保顺序正确。那句话不太正确。 @Remou 你是对的。用你的报价更新我的答案。以上是关于带参数的访问查询在 Access 中有效,在 C# 中无效的主要内容,如果未能解决你的问题,请参考以下文章
为啥此查询字符串在 Access 中有效,但在 C# 中无效?