首页 > 解决方案 > Perl DBD::MySQL 执行不支持 limit 关键字后的字符串参数。始终视为数字

问题描述

我们最近建立了一个带有最新 DBI MySQL、Perl 等的新操作系统。

这种模式在我们的几个应用程序中发现,并且在安装在新操作系统上时会中断。

my $sth = $dbh->prepare('select null colname, null colname2 limit 0'
        . ' union all select x, y from tbl where col like ?'
        . ' union all select z, a from tbl2 where col like ?');
$sth->execute('%test%', '%test%') or die ...;

该错误是 MySQL 语法错误。我们已经在引用参数的方式中发现了问题。

在上面的例子中,它在 MySQL 上是这样解析的。

select null colname, null colname2 limit 0
union all select x, y from tbl where col like 
union all select z, a from tbl2 where col like 

但是,如果'%test%'用数字(例如'555')换出,它就会通过。

select null colname, null colname2 limit 0
union all select x, y from tbl where col like 555
union all select z, a from tbl2 where col like 555

注意没有引号。

limit我们已将此确定为与关键字的存在有关。删除关键字可以解决语法错误。

select null colname, null colname2
union all select x, y from tbl where col like '%test%'
union all select z, a from tbl2 where col like '%test%'

此外,'555'在 Perl 中的设置现在会'555'在 MySQL 中产生,并带有引号。

我们发现使用派生表是目前最快的解决方法,

select * from (select null colname, null colname2 limit 0)a
union all select x, y from tbl where col like '%test%'
union all select z, a from tbl2 where col like '%test%'

(只尝试了括号,但需要派生表才能工作)但我很好奇是否有办法通过 DBI/DBD::MySQL 接口来控制引用方法。(避免更新声明)

要么更改默认行为以禁用limit关键字逻辑
,要么将特定参数类型强制为字符串?

标签: mysqlperllimitquotessanitization

解决方案


包含 LIMIT 的命令的解析是错误的。试试DBD::MariaDB,希望它已经解决了这个问题(这里)。


推荐阅读