Perl DBI:转义LIKE准备好的语句

时间:2016-01-13 07:42:36

标签: sql perl dbi

我有一个查询将参数绑定到LIKE语句,如下所示:

my $sth = $dbh->prepare('SELECT foo FROM bar WHERE baz LIKE ?');
$sth->execute("%$like%");

但是,$like是用户输入的值。因此,如果值包含LIKE子句(&_\)识别的任何特殊字符,则这些字符将被转义到数据库并解析为通配符或转义字符。例如,如果用户输入%value,则提交的查询为:SELECT foo FROM bar WHERE baz LIKE '%%value',而不是LIKE '%\%value,这是我所期望的。

目前我正在使用正则表达式手动转义字段:

# Escape LIKE wildcard characters
$like =~ s!\\!\\\\!g;
$like =~ s!%!\\%!g;
$like =~ s!_!\\_!g;

my $sth = $dbh->prepare('SELECT foo FROM bar WHERE baz LIKE ?');
$sth->execute("%$like%");

但感觉逃避是DBI应该能够处理的事情。我使用了DBI::quote,但这是为引用整个字段而设计的,因此在这种情况下,它还会引用我添加的%符号,DBI::quote的文档特别指出:

  

quote()方法不应与“占位符和绑定”一起使用   值”。

是否有更好的方法将用户提供的输入绑定到LIKE子句,同时转义输入并添加相关的通配符,而无需手动转义输入?

1 个答案:

答案 0 :(得分:-2)

尽管DBI::quote的文档说明了LIKE参数有点特殊。您想要做的几乎就是您在示例中已经拥有的内容:首先确保没有用户提供的元字符,方法是将quote应用于用户提供的字符串(在示例中使用regexp执行此操作),然后添加自己的元字符(在这种情况下为百分号),然后将其用作绑定参数的食物。