有没有办法使用 DBI 和 MySQL/MyISAM 将 @variables 与 Perl 中的占位符混合?
Posted
技术标签:
【中文标题】有没有办法使用 DBI 和 MySQL/MyISAM 将 @variables 与 Perl 中的占位符混合?【英文标题】:Is there a way to mix @variables with placeholders in Perl using DBI and MySQL/MyISAM? 【发布时间】:2020-11-19 09:14:16 【问题描述】:我有一个这样的查询:
SELECT
foo.bar
FROM
foo
WHERE
foo.bang = 0
AND (
CASE
WHEN ? = 2 THEN foo.baz IS NOT NULL
WHEN ? = 1 THEN foo.baz IS NULL
ELSE ? NOT IN (1, 2)
END
)
AND (
(? = 0)
OR
(foo.bang = ?)
)
占位符 (?
) 用作过滤器参数的输入:
my $query = $aboveQuery;
my ( $results ) = $dbh->DBI::db::selectall_arrayref(
$query,
Slice => ,
$bazFilter,
$bazFilter,
$bazFilter,
$bangFilter,
$bangFilter,
);
这可行,但对读者不太友好。
mysql 支持@
变量,这将增加可读性:
SET @bazFilter = ?; -- passed in via selectall_arrayref or execute;
SET @bangFilter = ?;
SELECT
foo.bar
FROM
foo
WHERE
foo.bang = 0
AND (
CASE
WHEN @bazFilter = 2 THEN foo.baz IS NOT NULL
WHEN @bazFilter = 1 THEN foo.baz IS NULL
ELSE @bazFilter NOT IN (1, 2)
END
)
AND (
(@bangFilter = 0)
OR
(foo.bang = @bangFilter)
);
我想做这样的事情:
my $query = $aboveAtVariablizedQuery;
my ( $results ) = $dbh->DBI::db::selectall_arrayref(
$query,
Slice => ,
$bazFilter,
$bangFilter,
);
但 MyISAM 显然不会在单个查询中执行多个语句。
我的 google-fu 让我失望了。 有没有一种很好的方法可以将@variables 与占位符混合匹配?
【问题讨论】:
$dbh->do('SET @bazFilter = ?;', ...); $dbh->do('SET @bangFilter = ?;', ...); $dbh->selectall_arrayref(...)
?
提示:$dbh->DBI::db::selectall_arrayref
应该只是 $dbh->selectall_arrayref
@ikegami 我宁愿一次性完成所有操作,而不是对$dbi
进行三个单独的调用(而且我的商店的代码要求迫使我们在使用它们时必须完全限定它们,因此上面代码中的DBI::db::
)。
Re "和我商店的代码要求迫使我们完全限定软件包",这很糟糕。您要求调用者对 DBI 的工作有内部知识,并对这些内部施加依赖。你的方法很脆弱,很容易出错,也很容易出错。糟糕,糟糕,糟糕。这与程序员应该努力的目标完全相反
@ikegami 我不是要和你争论我商店的代码要求。总的来说,我同意你的观点,我也反对过,但无济于事。
【参考方案1】:
单独执行每个语句,使用execute
而不是其中一种 fetch 方法。
@变量对于连接来说是本地的,所以线程之间不存在污染问题。
如果目标是没有重复替换的单个查询,那么考虑:
SELECT foo.bar
FROM ( SELECT baz = ?, bang = ? ) AS init
JOIN foo
WHERE foo.bang = 0
AND (
CASE
WHEN init.baz = 2 THEN foo.baz IS NOT NULL
WHEN init.baz = 1 THEN foo.baz IS NULL
ELSE init.baz NOT IN (1, 2)
END
)
AND (
(init.bang = 0)
OR
(foo.bang = init.bang)
);
【讨论】:
虽然我希望真正将@
变量与 ?
占位符混合在一起,但这绝对符合我的(隐含的)单一可读 没有重复替换的查询。谢谢!以上是关于有没有办法使用 DBI 和 MySQL/MyISAM 将 @variables 与 Perl 中的占位符混合?的主要内容,如果未能解决你的问题,请参考以下文章