簡體   English   中英

Perl DBI使用數組而不是標量列表執行

[英]Perl DBI execute with an array instead of list of scalars

我通過將字段添加到INSERT語句來根據某些條件(例如操作類型或某個值的存在)構建查詢。 但是然后我必須為具有不同參數列表的不同DBI execute分支,如下所示:

if ($x) {$extraFields .= ' , X'; $extraValues= ',? '}
if ($y) {$extraFields .= ' , Y, Z'; $extraValues= ',?, ? '}

my $theBasicQuery = "INSERT INTO sometable (A, B, $extraFields) VALUES (?, ? $extraValues)";

$sth = $dbh->prepare($theBasicQuery) or error

# but I dont want to have to do this if for execute
if ($x) {$sth->execute(1,2,99);}
if ($y) {$sth->execute(1,2,88, 77);}

我希望做這樣的事情:

{$sth->execute($anArrayWithDifferentParams);}

這可能嗎? 還是有另一種方法可以做類似的事情?

為了更直接地回答問題,使用數組而不是標量列表執行查詢的方法就是簡單地將其傳遞給數組。 $sth->execute(@params)可以正常工作。

if ($x) {$extraFields .= ' , X'; $extraValues = ',? '; @params = (99); }
if ($y) {$extraFields .= ' , Y, Z'; $extraValues = ',?, ? '; @params = (88, 77); }

my $theBasicQuery = "INSERT INTO sometable (A, B, $extraFields) VALUES (?, ? $extraValues)";

$sth = $dbh->prepare($theBasicQuery) or error

$sth->execute(1,2, @params);

我強烈建議您使用SQL構建工具來幫助您。 我最喜歡的是與DBIx :: Simple結合使用的SQL :: Interp 這樣的工具將為您管理綁定變量,並且DBIx :: Simple還會自動為您准備和重新使用語句句柄。 使用DBIx :: Simple / SQL :: Interp的解決方案如下所示:

$db->iquery("INSERT INTO sometable", {
    a => 1,
    b => 2,
    %extra
});

SQL :: Abstract也很流行,並且具有類似語法的解決方案。

一種方法:

my %insert = ( A => 1, B=> 2 );

if ($condition_x) {
  $insert{X} = 99;
}

if ($condition_y) {
  $insert{Y} = 88;
  $insert{Z} = 77;
}

# 1. sprintf isn't very perlish, but I find it clearer here
# 2. quote_identifier():  you won't ever need this until you need it very badly
#
my $query = sprintf('INSERT INTO tbl (%s) VALUES (%s)',
                       join ', ' => map { $dbh->quote_identifier($_) } keys %insert,
                       join ', ' => ('?') x keys %insert);

my $sth = $dbh->prepare($query);  # Perhaps prepare_cached, instead?
$sth->execute(values %insert);

注意:!DIY

如果有可能,請不要自己做! 使用其他地方建議的模塊。 其他人已經比上述更切實和可靠地解決了這個問題。

您可能會發現我的DBIx :: PreQL庫對於此類任務很有幫助。 它提供了一種標記SQL查詢以基於可用數據進行處理的方法。

DBIx :: PreQL使用簡單的前綴和命名的占位符來標記應包含查詢的哪些行。

例如, *表示“始終包含”,而&表示“包含”(如果存在該行的所有數據字段)。

您的查詢將被標記如下:

*  INSERT INTO sometable (
*     A
*    ,B
&    ,C !C!  
&    ,D  !D!
)
*VALUES (
*   ?A?
*  ,?B?
&  ,?C?
&  ,?D?
* )

然后將查詢和數據哈希(例如{ A => '123', B => 'foo', D => 'bar' }傳遞給查詢處理器,這將返回查詢:

INSERT INTO sometable (
     A
    ,B
    ,D
)
VALUES (
   ?
  ,?
  ,?
 )

以及參數列表(123, 'foo', 'bar')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM