重新使用?在DBI准备

时间:2010-07-05 16:22:40

标签: perl dbi

有没有办法重用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传递给执行而不是三个。有没有办法在现实生活中做到这一点?

4 个答案:

答案 0 :(得分:7)

这取决于你的DBD。例如,使用带有$1样式占位符的DBD :: Pg,或带有命名占位符和bind_param的DBD :: Oracle,您可以完全按照自己喜欢的方式执行操作。但是使用在DBI范围内工作的通用?占位符样式,这是不可能的。

答案 1 :(得分:4)

如果您使用库为您生成SQL语句,例如SQL::AbstractDBIx::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');

没有重复的变量,您仍然可以获得参数化查询的安全性。