在c#中的SQL查询字符串中转义单引号

时间:2014-03-20 20:20:19

标签: c# sql escaping

假设我无法控制创建查询字符串,例如

select * from customer where name='Joe's construction'

此外,无法控制执行查询,例如,将其传递给rest api以在数据库上执行

我需要将查询转义为

 select * from customer where name='Joe\'s construction'

所以我需要写一个像这样的函数

 string escape(string sql)

该函数传递原始查询并返回转义字符串。所以它可以使用这样的函数:

 string s = "select * from customer where name='Joe's construction'";
 string es = escape(s);
 //es should equals "select * from customer where name='Joe\'s construction'"

如何让这个函数逃脱工作?

同样,我无法控制创建sql查询,我只能将查询字符串作为一个整体来获取。而且我没有使用它来执行任何数据库,我只需要将其转义并传递给API。

4 个答案:

答案 0 :(得分:2)

逐字符状态机似乎最好:

  1. 默认状态

    • 过渡到"引用"遇到单引号字符的状态
    • 保留其他任何内容的默认状态
    • 始终将字符发送到输出
  2. 引用状态

    • 过渡到"可能的报价已完成状态"单引号,持有字符
    • 在其他任何内容中保留Quoted状态,将字符发送到输出
  3. 可能的报价已完成状态

    • 在空白处转换为默认状态,将报价发送到输出,然后将字符输出为正常
    • 转换为Quoted状态的其他任何内容,但输出额外的\'第一个字符
  4. 一个问题是转义引号的sql标准方法不是\',而是''。是否有可能获得已经以这种方式转义的任何查询,如果是这样,您想对它们做什么?

    此外,无论何时你逃避sql,你 最终会犯一个错误,让你容易受到sql注入攻击。 sql注入和单引号问题的答案是来转义sql查询中的数据;答案是隔离它。

答案 1 :(得分:1)

如何使用转义引号替换所有单引号,然后删除第一个和最后一个斜杠。这将逃脱所有内部单引号。

string sql = "select * from customer where name = 'Joe's construction'";
sql = sql.Replace(@"'", @"\'");
sql = sql.Remove(sql.LastIndexOf(@"\"), 1).Remove(sql.IndexOf(@"\"), 1);

答案 2 :(得分:1)

这很容易解决..... 只需在查询中写两次单引号,它就会被SQL Server接受....

你不能用反斜杠来逃避单引号....你需要另一个单引号

select * from customer where name = 'Joe''s construction'

答案 3 :(得分:0)

我已经做了类似的事情,但没有任何例外。这可能是一个解决方案,但请注意它可能附带的SQL注入问题。

name.Replace("'", $"{(char)39}");