有没有办法重用DBI prepare语句中使用的?请考虑以下代码:
$sth=$dbh->prepare("INSERT INTO mytable(a,b,c) SELECT ?,B(?),C(?)");
$sth->execute($a,$a,$a);
使用这样的东西会非常好:
#I'm making this up as something I hope exists
$sth=$dbh->prepare("INSERT INTO mytable(a,b,c) SELECT ?,B(?:1),C(?:1)");
$sth->execute($a);
请注意,只有一个$a
传递给执行而不是三个。有没有办法在现实生活中做到这一点?
答案 0 :(得分:7)
这取决于你的DBD。例如,使用带有$1
样式占位符的DBD :: Pg,或带有命名占位符和bind_param
的DBD :: Oracle,您可以完全按照自己喜欢的方式执行操作。但是使用在DBI范围内工作的通用?
占位符样式,这是不可能的。
答案 1 :(得分:4)
如果您使用库为您生成SQL语句,例如SQL::Abstract或DBIx::Class之类的完整ORM,你不必担心这样的事情。
或者你可以用几行代码做类似的事情:
my $sql = 'INSERT INTO ...blah blah... VALUES (' . (join(', ', ('?') x scalar(@insert_elements))) . ')';
答案 2 :(得分:3)
@hobbs'answer是对的 - 默认的DBI占位符不能这样做。 @Ether的answer是对的 - SQL抽象可以使这成为一个无问题。
但是,通常只需要一次绑定每个不同的参数化值。在您的示例中,使用标量派生表使用户提供的值按名称可用于查询的其余部分:
my $sth = $dbh->prepare(<<'__eosql');
INSERT INTO mytable(a,b,c)
SELECT x, B(x), C(x) FROM (SELECT ? AS x) subq
-- Subquery may vary from DB to DB:
-- "FROM (SELECT ? AS x FROM DUAL) subq"
-- "FROM (SELECT ? FROM rdb$database) subq(x)"
-- "FROM (VALUES (?)) subq(x)"
-- etc.
__eosql
for $v (@values) {
$sth->execute($v);
}
通常,这比其他选择更具“线路效率”,因为用户提供的参数通常只传输一次而不是 N 次。
答案 3 :(得分:0)
您可以在一个SQL语句中设置SQL变量,然后在下一个查询中多次使用该变量。
$dbh->do('set @reusable = ?', undef, $perl_var);
$dbh->select_arrayref('select * from table where cola = @reusable or colb = @reusable');
没有重复的变量,您仍然可以获得参数化查询的安全性。