我有一个名字在其中的数据库,如John Doe等。不幸的是,其中一些名字包含像Keiran O'Keefe这样的引号。现在,当我尝试搜索如下名称时:
SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe'
我(可以理解)得到错误。
如何防止发生此错误。我正在使用Oracle和PLSQL。
答案 0 :(得分:30)
转义字符是',因此您需要用两个引号替换引号。
例如,
SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe'
变为
SELECT * FROM PEOPLE WHERE SURNAME='O''Keefe'
那就是说,自己这样做可能是不对的。您的语言可能具有转义字符串以在SQL中使用的函数,但更好的选择是使用参数。通常这样做如下。
您的SQL命令是:
SELECT * FROM PEOPLE WHERE SURNAME=?
然后,当你执行它时,你传入“O'Keefe”作为参数。
因为在设置参数值之前解析了SQL,所以参数值无法改变SQL的结构(如果你想用不同的参数多次运行相同的语句,它甚至会快一点)
我还应该指出,虽然你的例子只会导致错误,但你可以通过不适当地转义字符串来解决许多其他问题。请参阅http://en.wikipedia.org/wiki/SQL_injection以获得良好的起点或以下经典xkcd comic。
答案 1 :(得分:3)
Oracle 10解决方案
SELECT * FROM PEOPLE WHERE SURNAME=q'{O'Keefe}'
答案 2 :(得分:1)
根据Matt的建议,参数化查询是您的朋友。
Command = SELECT * FROM PEOPLE WHERE SURNAME=?
他们将保护您免受与
有关的麻烦答案 3 :(得分:1)
使用参数化SQL还有其他好处,它通过减少Oracle解析语句所需的工作量来减少Oracle中的CPU开销(以及其他资源)。如果你不使用参数(我们称它们为Oracle中的绑定变量),那么“select * from foo where bar ='cat'”和“select * from foo where bar ='dog'”被视为单独的语句,其中as select * from foo where bar =:b1“是相同的语句,意思是语法,引用的对象的有效性等等......不需要再次检查。使用绑定变量时偶尔会出现问题,这些问题通常表现在没有获得最有效的SQL执行计划,但是有解决方法,这些问题实际上取决于您使用的谓词,索引和数据倾斜。
答案 4 :(得分:0)
输入过滤通常在语言级别而不是数据库层次上完成 php和.NET都有各自的库来转义sql语句。检查您的语言,查看可用的语言 如果你的数据是可信的,那么你可以只做一个字符串替换来添加另一个'面前'以逃避它。如果没有任何输入是恶意的风险,通常就足够了。
答案 5 :(得分:0)
我想一个好问题是你用的语言是什么?
在PHP中你会这样做:SELECT * FROM PEOPLE WHERE SURNAME ='mysql_escape_string(O'Keefe)'
但由于你没有指定语言,我建议你查看一个转义字符串函数mysql或其他语言。
答案 6 :(得分: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\''
答案 7 :(得分:-2)
在Google上发现不到30岁......