2009-11-06 4 views
13

저는 Perl의 DBI 모듈을 사용하고 있습니다. 자리 표시자를 사용하여 문을 준비한 다음 쿼리를 실행합니다.Perl의 DBI가 자리 표시 자에 채워진 후 실행되는 SQL 쿼리를 어떻게 인쇄 할 수 있습니까?

수동으로 매개 변수를 이스케이프 처리하고 자리 표시 자로 놓지 않고 실행 한 최종 쿼리를 인쇄 할 수 있습니까?

감사합니다.

+1

가능한 복제본 [어떻게 매개 변수를 포함한 모든 쿼리를 로그 할 수 있습니까?] (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는이를 통해 데이터베이스를 전달하게되며 준비된 명령문을 사용하는 이유 중 하나가됩니다.

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의 전체 요점은 placeholder가있는 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의 준비/선택 */실행 메소드에 대한 콜백을 작성하고 원하는 방식으로 수집 할 수 있습니다.

0

Sinan에서 제안한대로 자체 추적자 모듈을 만들지 않으려면 으로 전달되기 전에 인수 해시를 인쇄하는 것이 좋습니다. "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 

은 한 번에 한 번 후에 매개 변수를 바인딩하기 전에 두 번 각각의 문을 인쇄합니다. 후자는 자신이 실행할 수있는 올바른 형식의 SQL입니다.

관련 문제