2009-11-06 7 views
13

私はPerlのDBIモジュールを使用しています。プレースホルダを使用して文を準備し、クエリを実行します。PerlのDBIがプレースホルダに埋め込まれた後に実行されるSQLクエリを出力するにはどうすればよいですか?

パラメータを手動でエスケープしてプレースホルダにドロップせずに実行された最後のクエリを印刷することは可能ですか?

おかげで、一般的に

+1

可能な複製[どのようにDBIがすべてのクエリにパラメータを含めることができますか?](http://stackoverflow.com/questions/19703521/how-can-i-make-dbi-log-all-queries-including- params) – Jake

+0

@Jakeこの質問は他の質問の4年前に尋ねられましたが、この質問も(私の意見では)より良い回答があります。だからこそ、私はもう一つの質問を複製とクローズの候補としてマークしました。 – aidan

答えて

16

Tracing in DBIを参照してください。次DBD::SQLiteを使用して動作しますが、大量の出力生産:

$dbh->trace($dbh->parse_trace_flags('SQL|1|test')); 

出力:

<- prepare('SELECT ... FROM ... WHERE ... = ?')= DBI::st=HASH(0x21ee924) at booklet-excel.pl line 213

<- execute('Inhaler')= '0E0' at booklet-excel.pl line 215

などなど

あなた可能性plug your own filter in to the trace streamにはprepare秒を保ちます。

+1

質問に答えることはできませんが(他の人が指摘しているように、それは不可能なので)、トレースについて私に教えてもらった。そして、このコメントは私が質問に答えないことを知っている答えをupvotingすることに対して罪悪感を感じているからです。 lol:$ – msb

10

ない、DBIは、必ずしも、このようなクエリを生成していないため。データベースがプリペアドステートメントとプレースホルダーをAPIにサポートしている場合、DBIはそれらを渡してデータベースに処理をさせます。これはプリペアドステートメントを使用する理由の1つです。

8

Statement属性を使用して、プリペアドステートメントのデバッグプリントを実行できます。これは、 "ステートメントハンドル"または "データベースハンドル"でアクセスできます。

print $sth->{Statement} # with a statement handle 

print $dbh->{Statement} # with a database handle 
+1

これは最後の 'prepare'や' do'に渡された文字列を返すだけなので、要求されたOPとしてプレースホルダは埋められません。 – ThisSuitIsBlackNot

+1

'print Dumper($ statement_handle - > {'ParamValues'});' を使用してバインドパラメータを個別に印刷することができます。 – user1027562

1

一般に、mastoはSQL内のプレースホルダは直接パラメータに置き換えられないと言っています。パラメータ化されたSQLの全体のポイントは、プレースホルダ付きのSQLがデータベースエンジンに渡されて一度解析された後、パラメータを受け取るだけです。

idsslノートでは、ステートメントまたは接続ハンドルからSQLを取得し、ParamValuesからパラメータを取得することもできます。これを自分でやりたいのでなければ、DBIx::Log4perlのようなものを使ってSQLとパラメータだけを記録することができます。このような何かを出力するDBIX_L4P_LOG_DELAYBINDPARAMを参照してください:

DEBUG - prepare(0.1): 'insert into mje values(?,?)' 
DEBUG - $execute(0.1) = [{':p1' => 1,':p2' => 'fred'},undef]; 

もちろん、それはログイン:: Log4perlを使用して、あなたが「DEBUGを - 」は省略することができますしたい場合。 DBIx :: Log4perl hereを使用するための小さなチュートリアルがあります。

あなたはDBIx :: Log4perlをDBDと一緒に使うことができます。何らかの理由でRTできない場合は、私はそれを見ます。

DBIx :: Log4perlを使用したくない場合、DBIトレースオプションがニーズに合わない場合は、DBIのprepare/select */executeメソッドのコールバックを作成し、好きなものを集めることができます。

0

独自のトレーサモジュール(Sinanの提案)を作成したくない場合は、引数ハッシュが$sth->execute()に渡される前に、引数のハッシュを出力するほうがよいでしょう。これは、 "Trace"機能がDBMSに依存し、$sth->{Statement}がSQLプレースホルダステートメントのみを返すため、特に当てはまります。ここに私がしたことがあります。私はテキスト:: CSVを使用していた

... 
while (my $row = $csv->getline_hr($fh)) { 
    my $cval = ""; 
    my $tquery = $query; 
    foreach my $j (@cols) { 
      $cval = $row->{$j}; 
      $tquery =~ s/\?/\'$cval\'/; 
    } 
    print "$tquery\n\n"; 
    $rc = $sth->execute(@{$row}{@cols}); 
} 

... :これは、{ '}秒のDBMSの実装に依存する処理に、正確ではありません。

1

これは、サーバー側でDBD::mysqlの作品は、無効(デフォルト)の準備:

$ DBI_TRACE=2 perl your-script-here 

それはかつて一度後にパラメータを結合して前に、2回ずつ文を出力します。後者は、自分で実行できる整形式のSQLになります。

関連する問題