我对Perl很新,我被DBI的错误困扰了。我正在尝试查询由其十六进制值定义的一系列字符:
my @compare = ( '\'%\'+x\'0A\'+\'%\'',
'\'%\'+x\'92\'+\'%\'',
'\'%\'+x\'96\'+\'%\'',
'\'%\'+x\'A0\'+\'%\'' );
my $fetch_bad_rows = $dbh->prepare( qq{
SELECT B.* FROM ... AS B
WHERE B. ... LIKE ?
OR B. ... LIKE ?
OR B. ... LIKE ?
OR B. ... LIKE ?
});
$fetch_bad_rows->execute(@compare)
my $counter;
for( $counter = 0; $fetch_bad_rows->fetch; $counter++ ) {};
print LOG sprintf("Found %d bad rows\n", $counter);
以这种方式执行语句会找到0行。但是,如果我在查询中硬编码字符串,我会得到437条记录:
my $fetch_bad_rows = $dbh->prepare( qq{
SELECT B.* FROM ... AS B
WHERE B. ... LIKE '%'+x'0A'+'%'
OR B. ... LIKE '%'+x'92'+'%'
OR B. ... LIKE '%'+x'96'+'%'
OR B. ... LIKE '%'+x'A0'+'%'
});
$fetch_bad_rows->execute
我无法弄清楚传递绑定值时我做错了什么。
有人有什么想法吗?提前谢谢。
答案 0 :(得分:4)
?
中的prepare
将确保所有内容都已转义。因此,如果你传递了'
的东西,它将逃脱引号:
'\'%\'+x\'0A\'+\'%\''
可以更容易地写成:
q{'%'+x'0A'+'%'}
将变为:
... LIKE '\'%\'+x\'0A\'+\'%\''
因此它找不到任何东西。
答案 1 :(得分:3)
感谢您的回复。我根据提供的信息进行了一些挖掘,并找到了一种方法来实现它:
my @compare = ( '0A','92','96','A0' );
my $fetch_bad_rows = $dbh->prepare( qq{
SELECT B.* FROM ... AS B
WHERE B. ... LIKE '%' + UNHEX(?) + '%'
OR B. ... LIKE '%' + UNHEX(?) + '%'
OR B. ... LIKE '%' + UNHEX(?) + '%'
OR B. ... LIKE '%' + UNHEX(?) + '%'
});
$fetch_bad_rows->execute(@compare)
我无法使用'x?'因为准备调用将其视为表引用并抱怨没有找到表'x'。然而,UNHEX例程是我所需要的,因为它需要一个字符串输入。
再次感谢大家
答案 2 :(得分:1)
它在这里做的逃避是保护你免受SQL注入。在查询本身中进行任何连接,并仅传递更改的部分。例如:
my $sql = "SELECT x FROM y WHERE z LIKE '%' + x? + '%'";
my $sth = $dbh->prepare($sql);
$sth->execute("0A");