1

INSERTステートメントにフィールドを追加することにより、特定の条件(操作のタイプや特定の値の存在など)に応じてクエリを作成します。executeただし、次のように、パラメータのリストが異なるさまざまなDBIに分岐する必要があります。

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);}

これは可能ですか?または、同様のことを行う別の方法はありますか?

4

4 に答える 4

6

質問に直接答えるために、スカラーのリストの代わりに配列を使用してクエリを実行する方法は、単に配列を渡すことです。 $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);
于 2013-02-27T21:32:40.730 に答える
4

これを支援するためにSQL構築ツールを使用することを強くお勧めします。私のお気に入りは、 DBIx::Simpleと組み合わせて使用​​されるSQL::Interpです。このようなツールはバインド変数を管理し、DBIx::Simpleはステートメントハンドルの準備と再利用も自動的に処理します。DBIx :: Simple / SQL :: Interpを使用したソリューションは、次のようになります。

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

SQL :: Abstractも人気があり、同様の構文のソリューションがあります。

于 2013-02-27T20:58:01.723 に答える
2

1つのアプローチ:

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

可能であれば、自分でやらないでください。他の場所で提案されているように、モジュールを使用します。他の人は、上記よりもより確実かつ確実に、この問題をすでに解決しています。

于 2013-02-27T21:27:15.970 に答える
0

私の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')

于 2013-02-27T23:46:13.547 に答える