有没有办法使用 DBI 和 MySQL/MyISAM 在 Perl 中混合 @variables 和占位符?
Is there a way to mix @variables with placeholders in Perl using DBI and MySQL/MyISAM?
我有这样的查询:
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,
);
这可行,但不是很 reader 友好。
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 与占位符混合搭配吗?
分别执行每个语句,使用execute
而不是其中一种提取方法。
@变量是连接的局部变量,所以不存在线程间污染的问题。
如果目标是没有重复替换的单个查询,那么请考虑:
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)
);
我有这样的查询:
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,
);
这可行,但不是很 reader 友好。
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 与占位符混合搭配吗?
分别执行每个语句,使用execute
而不是其中一种提取方法。
@变量是连接的局部变量,所以不存在线程间污染的问题。
如果目标是没有重复替换的单个查询,那么请考虑:
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)
);