【发布时间】: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 我不是要和你争论我商店的代码要求。总的来说,我同意你的观点,我也反对过,但无济于事。