【问题标题】:How to Add Quotes to a Dynamic SQL Command?如何为动态 SQL 命令添加引号?
【发布时间】:2010-11-10 14:48:15
【问题描述】:

我正在数据库中存储和编辑包含一个或多个句子的长字符串的某些字段。每当我在文本框中输入单引号并想要保存它时,它都会引发异常,例如 “'l' 附近的语法不正确。 字符串 '' 后面的非闭合引号。" 有什么办法可以避免吗?

编辑: 查询是:

SqlCommand com = new SqlCommand("UPDATE Questions SET Question = '[" + 
    tbQuestion.Text + "]', Answer = '[" + 
    tbAnswer.Text + "]', LastEdit = '" + 
    CurrentUser.Login + 
    "'WHERE ID = '" + CurrentQuestion.ID + "'");

【问题讨论】:

  • 请显示您正在使用的 SQL 语句。
  • 简单地逃离 ' 与另一个 ' 像 Hell's AngelsHell's Angels
  • SqlCommand com = new SqlCommand("UPDATE Questions SET Question = '[" + tbQuestion.Text + "]', Answer = '[" + tbAnswer.Text + "]', LastEdit = '" + CurrentUser.Login + "'WHERE ID = '" + CurrentQuestion.ID + "'");
  • 我们都是这么想的。请编辑您的问题以添加该信息。
  • 别担心。我会为你做的。

标签: sql dynamic-sql


【解决方案1】:

编写一个存储过程来进行字段编辑并使用 SQL 参数来保存值。报价无关紧要。如果您不想要存储过程,至少使用参数标记构建您的 SQL 文本并使用 SQL 参数。

【讨论】:

    【解决方案2】:

    如果要在 SQL 字段中包含单引号,请使用单引号对其进行转义

    '''Test''' = 'Text'
    

    这是为 SQL Server 准备的。

    【讨论】:

    • 使用参数化 SQL 会更安全。
    • Luke:当然会,但我不会坐在这里试图猜测他目前是如何执行 SQL 的,所以我会给出最直接的答案。
    • @TheTXI:很公平,但是无论他在执行 SQL,但可以确定的一件事是他没有使用参数。使用参数可以完全避免这个问题。
    【解决方案3】:

    在 MSSQL 中,您可以将引号加倍:

    my dodg'y test          -> 'my dodg''y test'
    my 'quoted' string      -> 'my ''quoted string'''
    'first and last quotes' -> '''first and last quotes'''
    

    【讨论】:

    • 但问题是我从用户那里得到了输入,所以告诉用户添加另一个报价不会很好
    【解决方案4】:

    很难给你一个具体的答案,因为你没有列出你正在使用的数据库或应用程序语言。

    您必须动态构建 SQL,并且字符串中的引号被解释为字符串的结尾。根据您使用的数据库,您需要转义您打算在 sql 命令中使用的每个字符串中的单引号。这可以通过在尝试运行之前打印查询来看到。

    您没有提及您从中调用数据库的应用程序,但是当您构建命令时,您需要使用您编写的或由您的语言提供的 FIX_QUOTES() 命令:

    SqlCommand com = new SqlCommand("UPDATE Questions SET Question = '[" + FIX_QUOTES(tbQuestion.Text) + "]', Answer = '[" + FIX_QUOTES(tbAnswer.Text) + "]', LastEdit = '" + FIX_QUOTES(CurrentUser.Login) + "'WHERE ID = '" + FIX_QUOTES(CurrentQuestion.ID) + "'"); – A
    

    这种类型的动态查询对于sql injection attack 来说非常容易。我建议使用存储过程或参数列表来调用数据库。

    【讨论】:

      【解决方案5】:

      正如 KM 所说,不要这样做!

      改为这个

      private static void UpdateQuestionByID(
          int questionID, string question, string answer, string lastEdited)
      {
          using (var conn = new SqlConnection(connectionString))
          {
              conn.Open();
              const string QUERY =
                  @"UPDATE Questions " +
                  @"SET Question = @Question, Answer = @Answer, LastEdit = @LastEdited " +
                  @"WHERE ID = @QuestionID";
              using (var cmd = new SqlCommand(QUERY, conn))
              {
                  cmd.Parameters.AddWithValue("@Question", question);
                  cmd.Parameters.AddWithValue("@Answer", answer);
                  cmd.Parameters.AddWithValue("@LastEdited", lastEdited);
                  cmd.Parameters.AddWithValue("@QuestionID", questionID);
                  cmd.ExecuteNonQuery();
              }
          }
      }
      

      【讨论】:

        【解决方案6】:

        正如一些人已经说过的,添加一个额外的引号就可以了。我可以确认这也是 Oracle 的情况(其他人给出的这个答案对 MSSQL 和 SQL Server 有效)。我认为为此使用存储过程是矫枉过正的。

        【讨论】:

        • 使用参数化查询怎么样?
        • 是的,你可以这样做。如果您直接运行 sql,而不是通过 .NET API,则必须使用双引号解决方案。
        猜你喜欢
        • 2020-09-24
        • 2014-09-28
        • 1970-01-01
        • 2012-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-16
        相关资源
        最近更新 更多