【问题标题】:escape characters in SQL query string produced via string.format通过 string.format 生成的 SQL 查询字符串中的转义字符
【发布时间】:2013-11-19 18:36:43
【问题描述】:

我有 c# 中的语句:

String sql = String.Format("UPDATE Table SET FIRST_NAME='{0}',LAST_NAME='{1}',BIRTH_DATE='{2}' where CUSTOMER_NUMBER ='{3}'",FirstName, LastName,DateOfBirth,Number);

如果名字、姓氏等有撇号(如 O'Hare,O'Callahagan),则上述语句不会执行,因为更新语句的语法错误。

如何转义string.format中的撇号?

【问题讨论】:

标签: c# sql string formatting


【解决方案1】:

如何转义string.format中的撇号?

不要转义,改用参数化查询。

想象一个用户的really unconventional name 与 SQL 语句非常相似,用于删除表或执行同样恶意的操作。转义引号不会有太大帮助。

改用这个查询:

String sql = @"UPDATE Table
    SET FIRST_NAME=@FirstName
,   LAST_NAME=@LastName
,   BIRTH_DATE=@BirthDate
WHERE CUSTOMER_NUMBER =@CustomerNumber";

然后在对应的参数上设置FirstNameLastNameDateOfBirthNumber的值:

SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.AddWithValue("@FirstName", FirstName);
command.Parameters.AddWithValue("@LastName", LastName);
command.Parameters.AddWithValue("@BirthDate", BirthDate);
command.Parameters.AddWithValue("@CustomerNumber", CustomerNumber);

您的 RDMBS 驱动程序将为您完成所有其他工作,保护您免受恶意攻击。作为一个额外的好处,当您的 RDBMS 的日期格式与您的计算机不同时,它可以让您避免出现问题:由于您的 date 将不再作为字符串表示形式传递,因此理解格式化的哪一部分不会有问题date 代表一天,哪一个代表一个月。

【讨论】:

  • 我使用参数更改了程序的整个结构。这工作谢谢你:)
  • @user1118468 欢迎您!如果这对您有用,请考虑通过单击旁边的灰色复选标记来接受答案。这将使该网站的其他访问者知道您不再积极寻找改进的解决方案,并为您赢得 Stack Overflow 上的全新徽章。
  • 如果我改用 SqlDataAdapter 会怎样?
  • 我想知道的是:为什么在遇到像“Robert'); DROP TABLE Students;--”这样的恶意名称时,转义引号没有多大帮助?将单引号转义为 2 个单引号时,我没有看到任何问题。由于转义,恶意的 DROP TABLE 将是一个字符串并且不会执行。
【解决方案2】:

您应该使用参数化查询:

using (SqlCommand cmd = new SqlCommand("UPDATE Table SET FIRST_NAME= @FirstName, LAST_NAME= @LastName, BIRTH_DATE=@BirthDate where CUSTOMER_NUMBER = @CustomerNumber"))
{
    cmd.Parameters.Add(new SqlParameter("FirstName", FirstName));
    cmd.Parameters.Add(new SqlParameter("LastName", LastName));
    cmd.Parameters.Add(new SqlParameter("BirthDate", DateOfBirth));
    cmd.Parameters.Add(new SqlParameter("CustomerNumber", Number));

    // Now, update your database
} // the SqlCommand gets disposed, because you use the 'using' statement

通过使用参数化查询,您可以解决问题。使用参数化查询还有两个优点:

【讨论】:

    【解决方案3】:

    使用参数化查询。

    string commandString = "insert into MyTable values (@val1, @val2)";     
    SqlCommand command = new SqlCommand(commandString, connection);
    command.Parameters.AddWithValue("val1", "O'Hare");
    command.Parameters.AddWithValue("val2", "O'Callahagan");
    command.ExecuteNonQuery();
    

    【讨论】:

      猜你喜欢
      • 2013-08-10
      • 2015-11-05
      • 2015-02-09
      • 2016-10-30
      • 1970-01-01
      • 1970-01-01
      • 2012-07-10
      • 1970-01-01
      • 2016-03-07
      相关资源
      最近更新 更多