Доброго времени суток!
Строю запрос по следующему образцу:
my $request = "select * from somewhere where something=? and sometimes=?"; my $sth = $dbh->prepare($statement); $sth->bind_param(1, $value, { pg_type => PG_INT4 }); $sth->bind_param(2, $value_2); $sth->execute;
Хочу знать, можно ли получить строку финального запроса, в том виде, как она будет выполнена(с подставленными значениями). Например, $value = 2 и $value_2 = 44. В итоге на консоли должна будет быть напечатана строка:
SELECT * FROM somewhere WHERE something=2 AND sometimes=44

?
------------------
use Source();Мое мнение...
Насколько я знаю, DBI такой информации не дает. В отладочном логе у него запрос - отдельно, подставляемые значения - отдельно.
О, это уже
О, это уже теплее:) А как можно посмотреть лог? И насколько сильно его включение отражается на производительности? Просто у меня есть задача, которая где-то раз в две недели выдает ошибку в sql. Сейчас вот ищу, какую.
Ссылка...
Про отладочный лог читайте http://search.cpan.org/~timb/DBI-1.601/DBI.pm#TRACING
Я не рекомендую включать лог для вылавливания ошибки, которая происходит раз в две недели. Жаль, что Вы не указали какая именно возникает ошибка, чтобы можно было дать конкретные рекомендации.
В своем коде любые ошибки SQL я обычно отлавливаю при помощи исключений и записываю в журнал исключений. DBI выдает достаточно подробное сообщение об ошибке с указанием использованных для подстановки значений.
Пример из моего проекта:
К сожалению,
К сожалению, это все, что у меня есть
DBD::Pg::db do failed: ERROR: syntax error at or near "," at character 100Очень странно...
Мне показались странными два момента:
1. синтаксическая ошибка возникает на этапе разбора запроса и построения плана выполнения, подстановка значений - это уже следующий этап.
2. "do failed" по идее говорит о том, что $dbh->do() завершился с ошибкой, но ведь do() не умеет работать с placeholder'ами.
Вероятно,
Вероятно, какое-то из значений представляет собой пустую строку. Мне получение финального sql запроса нужно как раз для этих целей - узнать, какие данные отсутствуют. У меня проблема в том, что одни и те же данные обновляются из нескольких мест, причем есть еще стороннее приложение. Может, оно что-то затирает/обновляет... Сейчас сложно сказать, не зная, что именно:)
Думаю, что надо
Думаю, что надо включить "самописный" лог, и вносить туда что на первый взгляд вызывает ошибку. Я всегда так делаю, когда обнаруживается, что система работает нестабильно и вываливаются какие-то ошибки...
Минус один - влияет на скорость, но что скорость в течении некоторого времени по сравнению с дальнейшей стабильностью :)
________________
пустые значения
А если синтаксис в порядке, почему бы не сделать проверку параметров, допустим как минимум defined? или это не прелставляется возможным?
запросы к БД
может кому будет интересно и полезно:
Мониторинг запросов MySQL при помощи bash-скрипта
http://boombick.org/blog/posts/15
Мысли про мониторинг SQL-запросов к mysql...
Уважаемый Kavkaz!
Предложенный вариант кроме как "извращением", ничем другим назвать не могу :о)
В MySQL есть нормальный журнал запросов, который можно включить при запуске сервера (http://dev.mysql.com/doc/refman/5.0/en/query-log.html).
Сейчас нашел
Сейчас нашел такой вариант:
На консоль пойдет что-то вроде этого:
маразм :)
буду иметь ввиду, но мысль того парня тоже имеет право на существование :) а может и правда - нет ))) я хз, просто набрел на статью :)
Напоминание...
Уважаемый rimas!
В предложенном варианте надо учитывать тот факт, что print() при ошибке отработает только если RaiseError == 0.
А причем тут
А причем тут RaiseError? Печать выполняется вручную и ею управляет сам разработчик. Словили ошибку - печатаем в лог параметры. Во всяком случае, я сейчас поступил именно так. Жду данных для анализа;)))
В оправдание...
Уважаемый rimas!
Я слишком буквально воспринял Ваше сообщение, наивно посчитал, что Вы в программе код используете также, как в приведенном примере :о)
предложение
Можно использовать DBIx::Class. Мне он больше всего нравится. Там же есть DBIx::Class::QueryLog, который все показывает=)
вывод в консоль
Тут ковырялся на сервере и нашел такую утилитку:
в общем мускул по умолчанию хранит аккуратненько двоичные логи
вот пример записи:
для просмотра заходите в директорию с вашей бд ( например /home/mysql )
там буду лежать файлы типа:
-rw-rw---- 1 mysql mysql 973886454 Feb 13 14:12 office-bin.023просмотреть их можно командой
[root@office /home/mysql]# mysqlbinlog office-bin.025по-моему очень интересная вещь, очень даже может помочь
да, штука
да, штука классная, буду знать.
А что делать, если мы используем PostgreSQL?
Я уже написал небольшой вариан, не самый красивый, но кое-что он показывает. Закину завтра на критику:)
my $statement = 'insert
может позно и не в тему, но...
я делаю чуток проще и полезней (как мне кажется)
1. по сколько надо вставлять "правильные" данные в запрос. используем $dbh->quote($_);
2. в таком случае запрос имеет вид:
$sth=$dbh->prepare("select * from somewhere where something=".$dbh->quote($_)." and sometimes=".$dbh->quote($_));
3. а для того что б узнать что оно там выдаст на сервер:
$print=("select * from somewhere where something=".$dbh->quote($_)." and sometimes=".$dbh->quote($_));
В перле все
В перле все намного лучше чем в том-же php, потому что есть конструкции вида:
$rv = $dbh->do($statement, \%attr, @bind_values);
$rv = $sth->execute(@bind_values);
$sth->bind_param(1, 123);
И эти конструкции избавляют от необходимости заморачиваться с квотацией данных для sql запросов (данные передаются в SQL как двоичные).
Кстати, еще один плюс такого подхода в том что это немного быстрей чем когда парсер пытается парсить не только сам запрос но и его данные.