在SQL查询中如何转义单引号

22

我有一个名为companies的表,它有两列分别命名为nameaddress。通过运行以下代码,新数据将被插入到该表中:

my_name = "my company name"
my_address = "ABC"

query = "INSERT INTO companies (name,address) VALUES ('#{my_name}','#{my_address}');"

ActiveRecord::Base.connection.execute(query);

如果我将my_name的值从"我的公司名称"更改为"约翰的公司",我将收到语法错误。这是因为查询变成了:

"INSERT INTO companies (name,address) VALUES ('John's company','ABC');"

并且'John's company'中有一个单引号。

假设我已经使用双引号来定义查询字符串,那么如何消除关于值中单引号的错误?


如果我的名字包含单引号,那么就用单引号替换它。 - Leem.fin
5
这是一个非常糟糕的想法...即使你用反斜杠转义单引号,仍然存在SQL注入攻击的风险。你需要理解字符编码,但这种天真的方法存在一个严重的(已知的)漏洞。在查询中使用绑定参数,并允许DBMS安全地传输值。 - d11wtq
1个回答

82
如果您必须这样做,那么请在连接对象上使用quote方法

quote(value, column = nil)
引用列值以帮助防止SQL注入攻击。

因此,类似于以下内容:

my_name    = ActiveRecord::Base.connection.quote("John O'Neil")
my_address = ActiveRecord::Base.connection.quote("R'lyeh")

query = "INSERT INTO companies (name,address) VALUES (#{my_name}, #{my_address})"

ActiveRecord::Base.connection.execute(query);

永远不要尝试处理自己的报价。不要尝试使用双引号引用SQL字符串文字,单引号是为此而设计的;大多数数据库中,双引号用于引用标识符(例如表和列名),但MySQL使用反引号。


1
我认为你的代码有误,你应该在查询VALUES部分中删除单引号,因为quote()方法已经为字符串添加了引号。现在,如果我按照你说的运行代码,我会得到SQL语法错误,因为我将' 'John's company' '作为值。 - Leem.fin
1
请查看此帖子,了解您想要执行的替代方案以及如何清理参数:https://dev59.com/ZW855IYBdhLWcg3wMRRV - Moiz Raja
这种方法适用于查询除字符串以外的其他对象吗?我想提交一个包含整数和两个日期时间对象的 SQL 查询。 - Argus9
@Argus9:你尝试过在控制台中查看ActiveRecord::Base.connection.quote对于FixnumTime对象的处理吗?它应该会做正确的事情。 - mu is too short
是的,我在我的调试器控制台中查看了一下,发现它确实返回了正确的变量。谢谢! - Argus9
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接