2010-07-05 66 views
8

是否有重用在DBI准备语句中使用的?的方法。请看下面的代码:在DBI准备语句中重复使用?准备


$sth=$dbh->prepare("INSERT INTO mytable(a,b,c) SELECT ?,B(?),C(?)"); 
$sth->execute($a,$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); 

通知。有没有办法在现实生活中做到这一点?

+3

请不要使用'$ a'(和'$ b')作为nonce变量。它们是特殊的和特殊定义的:http://perldoc.perl.org/perlvar.html#%24a – pilcrow 2010-07-06 13:18:37

回答

7

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

4

如果您使用库为您生成SQL语句,例如SQL::Abstract或者像DBIx::Class这样的全功能ORM,你不必担心这样的事情。

或者你可以做的代码,只需几行类似的东西:

my $sql = 'INSERT INTO ...blah blah... VALUES (' . (join(', ', ('?') x scalar(@insert_elements))) . ')'; 
+1

所有这些解决方案都需要键入'$ a'三次,我相信这是User1试图避免的唯一任务。 – 2010-07-05 18:38:22

+0

@Bippedal:我们可以传递绑定参数为'(($ a)x 3)'。 – Ether 2010-07-05 18:53:11

+0

是的,'x'运算符可以用作解决方法,但是这不会改变1)OP询问是否有一种方法可以传递一次变量,并将它绑定到多个占位符,2)使用' x'运算符多次传入变量,每个占位符一次,这就是问题想要避免的。 – 2010-07-06 12:45:11

3

@hobbs'answer是正确的 - 默认的DBI占位符不能这样做。 @以太的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次。

0

您可以在一个SQL语句中设置SQL变量,然后在下一个查询中多次使用该变量。

$dbh->do('set @reusable = ?', undef, $perl_var); 
$dbh->select_arrayref('select * from table where cola = @reusable or colb = @reusable'); 

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