【问题标题】:SQL Query with single quotes带单引号的 SQL 查询
【发布时间】:2012-07-07 10:37:49
【问题描述】:

执行此查询时出错,因为列文本也可能包含带单引号的文本。我如何在没有任何错误的情况下使用此查询 我的代码是

public bool updateCMStable(int id, string columnName, string columnText)
{
    try
    {
        string sql = "UPDATE  CMStable SET " + columnName + 
                      "='" + columnText + "' WHERE cmsID=" + id;
        int i = SqlHelper.ExecuteNonQuery(Connection.ConnectionString,
                                          CommandType.Text,
                                          sql);
        if (i > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    catch (Exception ee)
    {
        throw ee;
    }
} 

【问题讨论】:

  • 您能否提供您在此代码中遇到的确切错误。
  • 字符串或二进制数据将被截断。声明已终止。
  • 所以你意识到这里的 try/catch 没有任何用处,而是做了一些坏事?在这里转义不是正确的解决方法:这应该 100% 使用参数化。

标签: c# .net sql database


【解决方案1】:

您应该使用parameterized queries,而不是在字符串中构造您的SQL - 您当前的代码,除了单引号问题外,容易受到SQL Injection 的攻击。

存在一个限制,即您尝试使用无法参数化的动态列名,但您仍然可以以更安全的方式使用动态 SQL。

我建议阅读 Erland Sommarskog 的 The Curse and Blessings of Dynamic SQL 以全面了解该主题。

【讨论】:

  • +1 用于参数化查询 - 在代码中使用 SQL 而不是存储过程不仅会降低其可维护性,还会导致 sql 注入问题。
【解决方案2】:

要修复您的代码,请使用额外的单引号转义所有单引号。 不过我同意 Oded... 您需要使用参数化查询,或者可能是存储过程。

public bool updateCMStable(int id, string columnName, string columnText) 
{ 
   if(!string.IsNullOrEmpty))
   {
       switch(columnName)
       {
           // TODO: change 50 & 100 to the real sizes of your columns, 
           // and obviously the column names too...
           case "column1":
               if(columnText.Length > 50)
                   columnText = columnText.SubString(0, 50);
               break;
           case "column2":
               if(columnText.Length > 100)
                   columnText = columnText.SubString(0, 100);
               break;
           etc... 
        }
    }
    // replace single quote with double single quotes
    columnText = columnText.Replace("'", "''");
    string sql = string.Format("UPDATE CMStable SET {0} = '{1}' WHERE cmsID={2}", 
        columnName, 
        columnText, 
        id); 
    int i = SqlHelper.ExecuteNonQuery(Connection.ConnectionString, CommandType.Text, sql); 
    return (i > 0); 
}

我对您的代码做了一些额外的更正。

  1. 当您返回 true | 时,您可以简单地返回 if 语句的结果。错误
  2. 如果只是将异常扔到 catch 块中,则不需要捕获异常
  3. 如果你确实捕获了一个异常,对它做一些有意义的事情,并决定重新抛出它,单独使用throw,否则你将重置堆栈跟踪。不要使用throw ee
  4. 如果 + 类型连接变得太不可读,请将其替换为 string.Format。

编辑:

发生您发布的错误是因为传入的数据长度超过了指定的列长度。由于您使用的是动态 SQL,因此我能看到的唯一解决方法是使用 case 语句。每个字段可能有不同的大小,也可能没有,但必须截断字符串以适应以避免错误。如果所有字段大小都相同,则不需要 case 语句。

【讨论】:

  • @user1372444 连接字符串以形成 SQL 是完全错误的,正如本答案顶部所警告的那样。不要成为另一个实施安全漏洞的人。
  • @spender - 我相信使用参数类型查询,双单引号也可以删除,因为我认为它是自动处理的。
【解决方案3】:

错误是

“字符串或二进制数据将被截断。语句已终止”

此错误的主要原因是您尝试保存任何值的列的长度较短,假设如果您的列是 varchar(100) 类型并且您尝试在其中保存一个 105 个字符的字符串,那么您会得到这个错误。

【讨论】:

  • 我的列有 nvarchar(max) 数据类型
【解决方案4】:

使用LinqToSql。拜托....... 上面列出的编写代码不是一个好主意的原因有很多 - 安全性、设计、理智......

Google LinqToSql 和“存储库模式”作为编写可维护、有用的数据交互的基本起点。

【讨论】:

    【解决方案5】:

    试试这个:

    public bool updateCMStable(int id, string columnName, string columnText)
    {
        try
        {
            columnText=columnText.Replace("'","''")
            string sql = "UPDATE  CMStable SET " + columnName + 
                          "='" + columnText + "' WHERE cmsID=" + id;
            int i = SqlHelper.ExecuteNonQuery(Connection.ConnectionString,
                                              CommandType.Text,
                                              sql);
            if (i > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        catch (Exception ee)
        {
            throw ee;
        }
    } 
    

    【讨论】:

      【解决方案6】:
      public bool updateCMStable(int id, string columnName, string columnText)
                  {
                       try
                      {
      string sql = "UPDATE  CMStable SET '"+columnName+"' = '"+columnText+"' where cmdID='"+id+"'";
      int i = SqlHelper.ExecuteNonQuery(Connection.ConnectionString,CommandType.Text,sql);
              if (i > 0)
              {
                  return true;
              }
              else
              {
                  return false;
              }
          }
          catch (Exception ee)
          {
              throw ee;
          }
      } 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-12
        • 2022-10-24
        • 1970-01-01
        相关资源
        最近更新 更多