Дамп подготовленного sql-запроса из инструкции DBI в PERL

#perl #debugging #dbi #dump

#perl #отладка #dbi #дамп

Вопрос:

я использую DBI в Perl для подключения к моей базе данных PostgreSQL. Все работает нормально, но в моей отладке (печать результатов и т.д.) Я не могу увидеть, действительно ли запрос, подготовленный модулем perls DBI, является правильным.

У меня есть что-то вроде этого:

 $sth->prepare( qq{SELECT * FROM company WHERE companyname LIKE ? AND city = ?});
$sth->execute( $name.'%', $city);
  

Я не могу увидеть, как выглядит sql-запрос после вызова execute, поскольку execute — это последний шаг, на котором параметры привязываются к запросу.

Я хотел бы иметь что-то вроде $sth->getLastExecutedQuery() или что-то еще, чтобы посмотреть, как выглядел запрос.

В этом случае функция getLastExecutedQuery() вернет:

 SELECT * FROM company WHERE companyname LIKE 'Company Name%' AND city = 'City name';
  

Есть ли какой-либо способ получить это? Это только для целей отладки.

Ответ №1:

DBI поддерживает следующее: Существует DBI->trace($tracefile_handle) метод (отслеживает все взаимодействия DBI), или $dbh->trace($tracefile_handle) который отслеживал бы только взаимодействия с определенным дескриптором. По умолчанию выводится STDERR, но, указав $tracefile_handle , вы можете явно отправить вывод в другой файл (или просто использовать перенаправление командной строки).

DBD::pg также поддерживает $h->trace('SQL'); Для работы это должно поддерживаться вашим драйвером DBD, но, к счастью, DBD:: Pg поддерживает эту функцию.

Документация для DBI в CPAN — DBI и для DBD::Pg в CPAN — DBD::Pg действительно дает вам все, что вам нужно знать о трассировке.

Ответ №2:

Используйте средство трассировки DBI. Это работает следующим образом:

 use strict;
use warnings;
use DBI;
my %opt = ( RaiseError => 1 );
my $dbh = DBI->connect( 'dbi:mysql:test', 'fred', 'secret', %opt );
$dbh->trace(2); # level 2 shows statement with inserted parameters
my $sql_i = 'insert into t1 (a, b) values ( ?, ? )';
my $sth_i = $dbh->prepare( $sql_i );
for ( qw/ eins zwei drei / ) {
    $sth_i->execute( $_, $_ );
}
$dbh->disconnect;
  

Комментарии:

1. Хорошо, но разве это не работает только в том случае, если произошла ошибка? Значит, трассировки будут отправляться в STDERR? Я хотел бы получать все запросы независимо от того, была ошибка или нет. Я знаю, что не могу указать имя файла для trace (), но в документах я ничего не могу подготовить о том, чтобы они всегда записывались не только в случаях ошибок.

Ответ №3:

Помимо трассировки, о которой упоминали другие, вам следует взглянуть наhttps://metacpan.org/pod/DBI#Statement который выдает вам SQL, выполненный последним и https://metacpan.org/pod/DBI#ParamValues и https://metacpan.org/pod/DBI#ParamTypes которые сообщают вам о ваших параметрах.

Также существует DBIx::Log4perl, который может регистрировать то, что вы хотите, без всякой трассировки DBI.