2010-07-05 70 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'); 

沒有重複的變量,您仍然可以獲得參數化查詢的安全性。