DBI准备语句 - 绑定hex-wildcard字符串

时间:2014-03-10 14:19:34

标签: sql arrays perl prepared-statement dbi

我对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

我无法弄清楚传递绑定值时我做错了什么。

有人有什么想法吗?提前谢谢。

3 个答案:

答案 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");