带参数的访问查询在 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。 IIfCDateIsNull @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# 中无效?

C#中 SQL语句 带参数的like 查询怎么写

如何在 Access 中进行查询将 tempvar 识别为有效字段(参数)

MS Access 更新查询和带字符串参数的内部连接

C# 选择带参数的 SQL 查询

关于C#中SQL查询语句的参数