【问题标题】:C# and MS Access SQL with Date Delimiter带有日期分隔符的 C# 和 MS Access SQL
【发布时间】:2021-06-02 17:02:30
【问题描述】:

我遇到了这个查询的错误

"SELECT COUNT(*) AS x FROM accounts_info ";
        query += "INNER JOIN customers_info ON accounts_info.cust_code = customers_info.cust_code ";
        query += "WHERE accounts_info.date_due >= #@a# AND accounts_info.is_paid = 0";

OleDbCommand cmd = new OleDbCommand(query, con);
String aaa = DateTime.Now.ToString("MM/dd/yyyy");
cmd.Parameters.AddWithValue("@a", aaa);

一个错误告诉我:附加信息:查询表达式中的日期语法错误 'accounts_info.date_due >= #@a# AND accounts_info.is_paid = 0'。

我可以在日期分隔符 #1/13/2021# 中插入参数,例如 #@param@# 吗?

【问题讨论】:

  • 我认为你不需要 @a 周围的 #,你应该只传递 DateTime.Now.Date 而不是 aaa。
  • - 或简称:DateTime.Today.

标签: c# sql ms-access


【解决方案1】:

两件事

  • 删除#
  • 将参数值设为日期而不是字符串

喜欢...

"SELECT COUNT(*) AS x FROM accounts_info ";
    query += "INNER JOIN customers_info ON accounts_info.cust_code = customers_info.cust_code ";
    query += "WHERE accounts_info.date_due >= @a AND accounts_info.is_paid = 0";

OleDbCommand cmd = new OleDbCommand(query, con);
cmd.Parameters.AddWithValue("@a", DateTime.Now.Date); //.Date will remove time portion from date

旁注..

OLEDB 不做命名参数。您可以将它们与名称一起放入,但您给出的名称无关紧要,重要的是顺序。参数集合必须包含相同数量的参数,并且与它们在 SQL 中出现的顺序相同。出于这个原因,为了避免误以为参数名称可以在查询中多次重复使用,有些人使用 ?参数占位符的标记

"SELECT COUNT(*) AS x FROM accounts_info ";
    query += "INNER JOIN customers_info ON accounts_info.cust_code = customers_info.cust_code ";
    query += "WHERE accounts_info.date_due >= ? AND accounts_info.is_paid = 0";

OleDbCommand cmd = new OleDbCommand(query, con);
cmd.Parameters.AddWithValue("p1", DateTime.Now.Date);

【讨论】:

  • 如果用户想更改查询怎么办?哪怕是一点点改变?然后再次更改代码。再次部署应用程序。一个小小的改变太让人头疼了。让我们假设查询是否很大?那么过多的字符串操作呢?再次出现性能问题
  • 你在说什么?如果用户想要更改查询,并且查询是代码,那么它就是代码更改。存储在哪里并不重要。如果您希望更改生效,必须部署。在访问中打开数据库,更改代码,然后单击保存正在更改代码并进行部署。您正在争论“打开视觉工作室,更改代码,单击发布”与“打开访问,更改代码,单击保存”之间存在巨大差异 - 绝对愚蠢
  • 老板你也在做同样的事情。试想一下,如果只需更改一个 SP 就可以完成,是否需要重新部署整个应用程序
  • 您可以单独测试SO,也可以检查语法错误。使用代码运行时,需要完成整个流程来测试和调试SP
  • 所以你的意思是你喜欢在变更管理、端到端测试之类的事情上快速而松散地玩,你喜欢把你的代码分散在所有地方......好吧。我理解你的观点,但我永远不会同意它们对于解决所提出的这个问题是强制性的。我对此讨论没有更多意见
【解决方案2】:

您的查询给出了下面的查询。

SELECT COUNT(*) AS x FROM accounts_info
INNER JOIN customers_info ON accounts_info.cust_code = customers_info.cust_code
WHERE accounts_info.date_due >= #@a# AND accounts_info.is_paid = 0

所以请从查询中删除#。

另外请创建一个存储过程并传递参数,而不是在代码中编写查询。

【讨论】:

  • 真的吗?存储过程?为什么,当查询可以/已经被参数化时,结束?
  • 因为它是松耦合的。假设您需要修改查询,然后无需更改代码并重新部署应用程序。
  • 将您的应用程序飞天访问逻辑与应用程序代码的其余部分保持在不同的位置并不是我所说的“松散耦合”,它只是一种替代代码管理策略,或者可能是变更管理头痛但各有各的。我对您的建议这样做的主要问题是,它看起来像是解决问题所必需的,但事实并非如此
  • @CaiusJard 这只是对良好做法的建议
  • 我指出它读起来不像是建议,而是读起来像指令。添加一些诸如“或者,您可以创建一个存储过程..”之类的词,如果这是您的意图.. 我不认为它比例如将查询文本保存在与一起部署的文本文件中更“好的做法”应用程序。您对存储过程所做的只是更改查询文本的存储位置;更改仍然必须“编译”和“部署”。采用参数化查询并制作必须使用参数化查询调用的参数化存储过程,在这里毫无意义
猜你喜欢
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-30
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
相关资源
最近更新 更多