2008-08-27 36 views
11

我有一个包含名字的数据库,例如John Doe等。不幸的是,其中一些名称包含引用如Keiran O'Keefe。现在当我尝试搜索这样的名称如下:我如何处理SQL中的引号'

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' 

我(可以理解)得到一个错误。

如何防止发生此错误。我正在使用Oracle和PLSQL。

+0

参见[单引号**引用字符串文字技术**](http://lalitkumarb.com/2014/12/31/quoting-string-literal-technique-to-avoid-erros -due-to-single-quotation-marks-in-the-string /) – 2015-12-18 06:29:53

回答

30

转义字符是',所以你需要用两个引号替换引号。

例如,

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe'

成为

SELECT * FROM PEOPLE WHERE SURNAME='O''Keefe'

这就是说,它可能不正确自己做。您的语言可能有一个函数来转义SQL中使用的字符串,但更好的选择是使用参数。通常这个工作如下。

你的SQL命令是:

SELECT * FROM PEOPLE WHERE SURNAME=?

然后,当你执行它,你在 “奥基夫” 作为参数传递。

因为在设置参数值之前解析了SQL,所以参数值无法改变SQL的结构(如果要用不同的参数多次运行同一语句,它甚至会更快一些)。

我还应该指出,虽然你的例子只是导致了一个错误,但你通过适当地转义字符串来解决很多其他问题。请参阅http://en.wikipedia.org/wiki/SQL_injection以获得良好的起点或以下经典xkcd comic

alt text

+0

+1用于推荐绑定变量。如果使用绑定变量这样的事情永远不会发生,并且您的查询更好,并且您不打开SQL注入攻击。 – 2009-08-27 12:57:58

+0

非常感谢,你刚刚救了我一天:)。希望我可以+2这些帖子。尼斯卡通太:) – 2013-03-30 16:24:55

0

输入滤波通常是在语言层面,而不是数据库层完成。
php和.NET都有它们各自的库用于转义sql语句。检查你的语言,看看你的语言。
如果你的数据是可信的,那么你可以做一个字符串替换来添加另一个'infront'来逃避它。通常这是足够的,如果没有任何风险,输入是恶意的。

1

我想一个很好的问题是你在用什么语言?
在PHP中,你会这样做:SELECT * FROM PEOPLE WHERE SURNAME ='mysql_escape_string(O'Keefe)'
但是既然你没有指定语言,我会建议你看一下转义字符串函数mysql或者在你的语言。

+0

`mysqli_real_escape_string()`为更多的最新方法。 – Jordan 2017-10-27 15:46:44

1

参数化查询是你的朋友,马特的建议。

Command = SELECT * FROM PEOPLE WHERE SURNAME=? 

他们会保护你的参与

  • 字符串用引号头痛
  • 查询使用日期
  • SQL注入
1

参数化的SQL的使用还有其他好处,它通过减少Oracle req的工作量来减少Oracle中的CPU开销(以及其他资源)以解析陈述。如果你不使用参数(我们称它们为Oracle中的绑定变量),那么“select * from foo where bar ='cat'”和“select * from foo where bar ='dog'”被视为单独的语句,其中“ select * from foo where bar =:b1“是相同的语句,这意味着语法,引用的对象的有效性等等......不需要再次检查。使用绑定变量时会出现偶然的问题,这些变量通常表现为没有得到最有效的SQL执行计划,但是有解决方法,这些问题实际上取决于您正在使用的谓词,索引和数据歪斜。

3

甲骨文10解决方案是

SELECT * FROM PEOPLE WHERE SURNAME=q'{O'Keefe}' 
0

,如果你正在使用Zend Framework这里是代码

$db = Zend_Db_Table_Abstract::getDefaultAdapter();

$db->quoteInto('your_query_here = ?','your_value_here');

例如对付报价;

//SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' will become 
SELECT * FROM PEOPLE WHERE SURNAME='\'O\'Keefe\''