【问题标题】:Dynamic SQL query causes "Unclosed quotation mark" error动态 SQL 查询导致“未闭合引号”错误
【发布时间】:2011-09-02 17:17:20
【问题描述】:

我收到此错误:

字符串''后面的非右引号。

使用以下代码:

lSQL = "DELETE FROM tblCourses where courseCode='" + aCourseCode + "'";

其中lSQL 是局部变量,aCourseCode 是存储值。有什么建议吗?

【问题讨论】:

  • 课程代码中是否有可能包含单引号?请使用参数化 SQL 查询来保护自己免受 SQL 注入。这是一个很好的解释uberasp.net/getarticle.aspx?id=46。考虑一下如果 aCourseCode 是字符串 "x' or 1=1 --",该查询会做什么
  • 你的课程名称可能是“A History of Sql's Vulnerabilities”

标签: c# sql sql-delete


【解决方案1】:

您应该始终使用参数化查询,否则您的代码很容易出现错误,甚至更容易受到 SQL 注入攻击。在构建 SQL 查询时,从不在代码中使用字符串连接。这是正确的方法:

using (var conn = new SqlConnection(ConnectionString))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "DELETE FROM tblCourses WHERE courseCode = @courseCode";
    cmd.Parameters.AddWithValue("@courseCode", aCourseCode);
    int deletedRowsCount = cmd.ExecuteNonQuery();
}

这将确保即使aCourseCode 变量包含一些转义字符和危险字符,它们也会得到正确处理。

【讨论】:

  • +1 更不用说这也会转义 aCourseCode 变量中的任何引号。
【解决方案2】:

您的 aCourseCode 变量中可能有一个单引号或双引号。

【讨论】:

    【解决方案3】:

    格式化字符串的更好方法是使用如下内容:

    lSQL = String.Format("DELETE FROM tblCourses where courseCode='{0}'", aCourseCode);
    

    还要确保您的变量 aCourseCode 中没有任何嵌入的双引号或单引号。

    希望对您有所帮助。

    【讨论】:

    • 不,这不是更好的方法。它与原始代码存在相同的问题。
    • 我同意...我给了他一种正确格式化字符串的方法,而不是 SQL 操作。
    • 我不明白为什么这被否决了。当然,最后提到的一点是更重要的一点,但这仍然是合理的建议。 @Darin,虽然这不能解决问题,但它 确实 更容易发现丢失的引号,因此更难编写错误引用的查询。 (当然,一旦您编写参数化查询,引用就会消失。在其他场景中它仍然是一种有用的技术。)
    • @stakx,我没有对这个答案投反对票,但我认为投反对票的人想确保其他有同样问题的人永远不会使用这样的代码。我必须同意他的观点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多