【发布时间】:2020-06-14 18:02:57
【问题描述】:
任务定义: 使用 OR 从两个不同的列中获取数据。
问题: 在使用普通 (MySQL) 查询时,Perl DBI 由于 bind variables 的奇数个数而引发异常。
让我们假设以下数据库架构:
customer vpn_primary_ip vpn_secondary_ip
1000 1.1.1.1 2.2.2.2
1001 3.3.3.3 NULL
1002 4.4.4.4 5.5.5.5
1003 NULL 6.6.6.6
旁注: 由于存储 ip 地址的列是不可预测的,我使用 OR 运算符组合搜索列 vpn_primary_ip AND vpn_secondary_ip。 普通 SQL查询如下:
SELECT
customer,
vpn_primary_ip,
vpn_secondary_ip,
FROM
table
WHERE
vpn_primary_ip IN ( '1.1.1.1', '4.4.4.4', '5.5.5.5', '6.6.6.6' )
OR
vpn_secondary_ip IN ( '1.1.1.1', '4.4.4.4', '5.5.5.5', '6.6.6.6' );
上面的查询给出了以下(适当的)结果:
+----------+-----------------+------------------+
| customer | vpn_primary_ip | vpn_secondary_ip |
+----------+-----------------+------------------+
| 1000 | 1.1.1.1 | 2.2.2.2 |
| 1002 | 4.4.4.4 | 5.5.5.5 |
| 1003 | NULL | 6.6.6.6 |
+----------+-----------------+------------------+
与 Perl DBI 相同的 SQL 查询:
my @ip_addresses = ('1.1.1.1', '4.4.4.4', '5.5.5.5', '6.6.6.6');
my $sth = $dbh->prepare (
"SELECT
customer,
vpn_primary_ip,
vpn_secondary_ip,
FROM
table
WHERE
vpn_primary_ip IN ( @{[join',', ('?') x @ip_addresses]} )
OR
vpn_secondary_ip IN ( @{[join',', ('?') x @ip_addresses]} )"
);
$sth->execute(@ip_addresses);
抛出以下异常:
DBD::mysql::st execute failed: called with 4 bind variables when 8 are needed at get_vpn_customers line 211, <DATA> line 1.
DBD::mysql::st execute failed: called with 4 bind variables when 8 are needed at get_vpn_customers line 211, <DATA> line 1.
使其工作的唯一方法是将@ip_addresses 传递给execute 方法两次:
$sth->execute(@ip_addresses, @ip_addresses);
问题: 这是正确的方法还是有其他方法,比如最佳或更好的做法?
【问题讨论】:
-
这是正确的方法。 Perl 无法知道您将同一组值传递了两次,因此它只希望在调用的参数中指定所有 8 个值。