我有一个数据库,其中包含名称,例如 John Doe 等。不幸的是,其中一些名称包含 Keiran O'Keefe 等引号。现在,当我尝试搜索以下名称时:
SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe'
我(可以理解)得到一个错误。
如何防止发生此错误。我正在使用 Oracle 和 PLSQL。
转义字符是 ',因此您需要将引号替换为两个引号。
例如,
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 漫画。
Oracle 10 解决方案是
SELECT * FROM PEOPLE WHERE SURNAME=q'{O'Keefe}'
正如 Matt 所建议的,参数化查询是您的朋友。
Command = SELECT * FROM PEOPLE WHERE SURNAME=?
他们将保护您免受与
使用参数化 SQL 还有其他好处,它通过减少 Oracle 解析语句所需的工作量来减少 Oracle 中的 CPU 开销(以及其他资源)。如果您不使用参数(我们在 Oracle 中将它们称为绑定变量),那么“select * from foo where bar='cat'”和“select * from foo where bar='dog'”将被视为单独的语句,其中“ select * from foo where bar=:b1" 是相同的语句,这意味着语法、引用的对象的有效性等……不需要再次检查。使用绑定变量时偶尔会出现问题,这通常表现为无法获得最有效的 SQL 执行计划,但有解决方法,这些问题实际上取决于您使用的谓词,
输入过滤通常在语言级别而不是数据库层上完成。
php 和 .NET 都有各自的用于转义 sql 语句的库。检查您的语言,查看可用的语言。
如果您的数据是可信赖的,那么您只需进行字符串替换以在 ' 前面添加另一个 ' 来转义它。如果输入不存在任何恶意风险,通常这就足够了。
我想一个很好的问题是你使用什么语言?
在 PHP 中,您可以: SELECT * FROM PEOPLE WHERE SURNAME='mysql_escape_string(O'Keefe)'
但是由于您没有指定语言,我建议您查看转义字符串函数 mysql 或您的语言。
如果您使用 Zend 框架,要处理报价,这里是代码
$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\''
在 Google 上发现 30 岁以下...