2016-02-29 165 views
4

我對Perl很陌生,我試圖克服最初的學習曲線。Perl中編寫的SQL語句

我有以下SQL語句:

 SELECT 
      node_id 
     FROM 
      pagenodes 
     INNER JOIN 
      pageproducts 
     ON 
      pagenodes.node_id = pageproducts.nodeid 
     INNER JOIN 
      products 
     ON 
      pageproducts.prodid = products.prodid 
     WHERE 
      products.prodid = ? 
     LIMIT 1 

正如你可以看到這個有限制1集查詢,我試圖執行從Perl腳本此查詢,並將結果設置爲變量。

到目前爲止,我有以下幾點:

my $sql = 
    'SELECT 
     node_id 
    FROM 
     pagenodes 
    INNER JOIN 
     pageproducts 
    ON 
     pagenodes.node_id = pageproducts.nodeid 
    INNER JOIN 
     products 
    ON 
     pageproducts.prodid = products.prodid 
    WHERE 
     products.prodid = ? 
    LIMIT 1'; 

    my $sth = $dbh->prepare($sql); 
    my $sth->execute(); 

我的問題是,我怎麼能在$prod_id通過爲WHERE paramater,哪有我的結果設置爲變量。謝謝

回答

9

你已經很遠了。很高興你已經擁有the placeholders (?)。您只需傳遞參數as an argument to execute即可。它會按照它們在查詢中出現的順序自動將它們填充到佔位符中。

use strict; 
use warnings; 
use DBI; 

my $dbh = DBI->connect('dsn goes here', 'user', 'password') or die $DBI::errstr; 

# stuff happens ... 

my $prod_id = 1337; # or whatever 

my $sql = 
    'SELECT 
     node_id 
    FROM 
     pagenodes 
    INNER JOIN 
     pageproducts 
    ON 
     pagenodes.node_id = pageproducts.nodeid 
    INNER JOIN 
     products 
    ON 
     pageproducts.prodid = products.prodid 
    WHERE 
     products.prodid = ? 
    LIMIT 1'; 

my $sth = $dbh->prepare($sql); 
$sth->execute($prod_id);  # no `my` here! 

在這種情況下LIMIT並不重要。它也將循環工作。

請注意,您在execute行之前有一個my。這是錯誤的語法。 my用於聲明變量,但在該行中只調用已存在的語句句柄對象的方法。 execute方法有返回值,但通常不會將其分配給變量。如果返回值爲true,則execute成功。如果它是錯誤的,就會出錯。您也可以使用orcheck for errors

$sth->execute or die $dbh->errstr; 

現在要從數據庫中獲取單個值,您可以use fetchrow_array in list context

(my $node_id) = $sth->fetchrow_array; 

這會給你一個單一的node_id,一次。


如果你打算只得到一個價值只有一次調用該方法,還可以節省代碼和use selectrow_array instead一些行。

(my $node_id) = $dbh->selectrow_array('SELECT node_id FROM foo WHERE prodid=? LIMIT 1', undef, $prod_id); 

再次,列表環境是很重要的,因爲fetchrow_arrayselectrow_array返回列表,而不是數組引用。如果沒有左邊的(),它會分配結果的數量(由於標量上下文)。

但是,如果你想在一個循環中爲一堆值做所有這些,它看起來有點不同。在這種情況下,請在循環的外部進行準備工作,並在循環內執行executefetchrow_array(或任何其他fetchrow_*方法)。這會使它快得多。

my $sth = $dbh->prepare($sql); 
foreach my $prod_id (@prod_ids) { 
    $sth->execute($prod_id); 
    (my $node_id) = $sth->fetchrow_array; 
    print "$node_id\n"; 
} 
+1

也許還可以看看[Tim Bunce關於OSCON高級DBI演示文稿的優秀幻燈片](http://www.slideshare.net/Tim.Bunce/dbi-advanced-tutorial-2007)。 – simbabque

+0

這是一個很好的答案,謝謝你。我似乎拉錯了一個錯誤:「全局符號」$ dbh「需要顯式包名」我只是看着這一點。 –

+0

@Liam你是否加載DBI並連接到數據庫? – simbabque