11

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

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

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

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

4

8 回答 8

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 漫画

替代文字

于 2008-08-27T08:17:56.293 回答
3

Oracle 10 解决方案是

SELECT * FROM PEOPLE WHERE SURNAME=q'{O'Keefe}'
于 2008-09-17T15:09:44.193 回答
1

正如 Matt 所建议的,参数化查询是您的朋友。

Command = SELECT * FROM PEOPLE WHERE SURNAME=?

他们将保护您免受与

  • 带引号的字符串
  • 使用日期查询
  • SQL 注入
于 2008-08-27T14:38:41.230 回答
1

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

于 2008-09-04T16:03:56.843 回答
0

输入过滤通常在语言级别而不是数据库层上完成。
php 和 .NET 都有各自的用于转义 sql 语句的库。检查您的语言,查看可用的语言。
如果您的数据是可信赖的,那么您只需进行字符串替换以在 ' 前面添加另一个 ' 来转义它。如果输入不存在任何恶意风险,通常这就足够了。

于 2008-08-27T08:05:05.903 回答
0

我想一个很好的问题是你使用什么语言?
在 PHP 中,您可以: SELECT * FROM PEOPLE WHERE SURNAME='mysql_escape_string(O'Keefe)'
但是由于您没有指定语言,我建议您查看转义字符串函数 mysql 或您的语言。

于 2008-08-27T08:05:29.490 回答
0

如果您使用 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\''
于 2012-02-16T07:27:27.427 回答
-3

在 Google 上发现 30 岁以下...

Oracle SQL 常见问题解答

于 2008-08-27T08:03:07.967 回答