【问题标题】:Getting syntax error on sql code and cant work out why在 sql 代码上出现语法错误并且无法找出原因
【发布时间】:2019-04-05 10:51:35
【问题描述】:

一直在尝试在这里找到语法错​​误,sql 似乎被正确隔开,并且变量正在从我的数据库和其他预期的形式中读取。

        clsDBConnector dbConnector = new clsDBConnector();
        OleDbDataReader dr;
        dbConnector.Connect();
        string sqlStr1 = "SELECT ItemID" +
            " FROM         TblItem" +
            " WHERE ([Item Name]= " + ItemName + ")";
        dr = dbConnector.DoSQL(sqlStr1);
        while (dr.Read())
        {
            string ItemID = dr[0].ToString();
            string sqlStr2 = "SELECT   TOP 1 OrderItemID" +
            " FROM         TblOrderItem" +
            " WHERE(OrderID =" + orderID + ") AND(ItemID =" + ItemID +")";
            dr = dbConnector.DoSQL(sqlStr2);
            while (dr.Read())
            {
                string OrderItemID = dr[0].ToString();
                string sqlStr3 = "DELETE FROM TblOrderItem" +
                    " WHERE    (OrderItemID =" + OrderItemID + ")";
                dr = dbConnector.DoSQL(sqlStr3);
            }
        }

【问题讨论】:

  • 应该会抛出异常。你读过这个异常信息吗?
  • [Item Name] 建议它是一个(n)(var)char 列,这意味着值应该用引号括起来。
  • 除了您遇到的任何异常,我非常强烈建议您更改您处理 SQL 的一般方式。使用参数化 SQL 来: 1) 避免 SQL 注入攻击; 2) 避免转换问题; 3) 让代码更清晰易读。
  • 除了建议您参数化查询之外,您是否尝试过使用 ' 转义变量,所以 WHERE([Item Name] = '" + ItemName + "'.
  • 向我们展示最终的 SQL 字符串。

标签: c# sql winforms ms-access


【解决方案1】:

看起来就像您在同一个连接上执行两个嵌套查询,但是:通常不支持(除非您启用了“MARS”,这通常是个坏主意)。您应该看到连接上已经存在开放数据读取器的异常。在开始担心其他数据之前,您需要完成第一个阅读器。您可以通过缓冲数据来做到这一点,但坦率地说,我怀疑您也可以将查询重新设计为一个带有连接的查询,或者是同一 SQL 中的两个查询 - 这也将更多高效(它避免了“N+1”)。

另一个主要问题是您要连接数据以创建 SQL,这总是一个坏主意。在最坏的情况下,它是一个 SQL 注入漏洞,而在最好的情况下,它会使您的查询计划缓存饱和。所以:请使用参数而不是连接。参数还可以避免转义、用引号包裹字符串以及有关如何格式化整数、日期等的 i18n/l10n 问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 2023-04-08
    • 2016-04-04
    • 2017-10-12
    • 2013-10-14
    相关资源
    最近更新 更多