Как найти ошибку в SQL-запросе

SQL-запрос — это то, что либо работает хорошо, либо не работает вообще, частично он никак работать не может, в отличие, например, от того же PHP. Как следствие, найти ошибку в SQL-запросе, просто рассматривая его — трудно, особенно если этот запрос снабжён целой кучей JOIN и UNION. Однако, в этой статье я расскажу о методе поиска ошибок в SQL-запросе.
Поскольку обычно в SQL-запрос подставляются какие-то переменные в PHP, то необходимо его сначала вывести. Сделать это можно, например, так:
<?php
$a = 5;
$query = «SELECT FROM `table` WHERE `id` = ‘$a'»;
$result_set = $mysqli->query($query); // Не работает
echo $query; // Выводим запрос, который отправляется
?>
В результате, скрипт выведет такой запрос: SELECT FROM `table` WHERE `id` = ‘5’. Теперь чтобы найти ошибку в нём, надо зайти в phpMyAdmin, открыть базу данных, с которой происходит работа, открыть вкладку «SQL» и попытаться выполнить запрос.
И вот здесь уже ошибка будет показана, не в самой понятной форме (иногда прямо точно описывает ошибку), но она будет. Вот что написал phpMyAdmin: «#1064 — You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘FROM `table` WHERE `id` = ‘5’ ORDER BY `table`.`id` ASC LIMIT 0, 30′ at line 1«. Это означает, что ошибка рядом с FROM. Присматриваемся к этому выделенному нами небольшому участку и обнаруживаем, что мы забыли поставить «*«. Исправляем сразу в phpMyAdmin эту ошибку, убеждаемся, что запрос сработал и после этого идём исправлять ошибку уже в коде.
С помощью этого метода я нахожу абсолютно все ошибки в SQL-запросе, которые мне не удаётся обнаружить непосредственно при осмотре в PHP-коде.
Надеюсь, теперь и Вы сможете найти ошибку в любом SQL-запросе.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!
Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
Она выглядит вот так:
Комментарии ( 1 ):
Здравствуйте Михаил! Пробовал найти ошибку в запросе по вашей подсказке, но ничего не получается. Если можно подскажите чего здесь не хватает. ************************************ $sql_banip = mysql_query("SELECT `banserfip` FROM `tb_statistics` WHERE `id`='1'"); ** Линия 44 — $vsego_banip = mysql_result($sql_banip,0,0); ********************************* Warning: mysql_result(): Unable to jump to row 0 on MySQL result index 9 in /home/forexbiz/forexbiz.org.ua/nikbux/view_sites.php on line 44 ******************************* результат проверки в SQL: Ответ MySQL: Документация #1064 — You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '$sql_banip = mysql_query("SELECT `banserfip` FROM `tb_statistics` WHERE `id`='1'' at line 1 С уважением Сергей.
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.
Методы выявления ошибок в SQL приложении
По мотивам своего мастер-класса на PHPConf 2009 (http://phpconf.ru) я написала гид для тех, кому нужно поймать ошибку в SQL приложении. Правильнее было бы назвать в MySQL приложении, но я всё-таки думаю, что общие принципы едины для всех. В идеале мне бы хотелось, чтобы текст охватывал основные случаи неправильного поведения. Оговорюсь, что под неправильным поведением я понимаю логические ошибки, а не проблемы производительности. Проблемы производительности — это отдельная тема, кстати, достаточно хорошо представленная в сети.
Книжка состоит из 4 частей, ниже можно посмотреть краткое содержание:
Часть 1. Одиночные запросы.
Рассмотрены случаи, когда ошибка повторяется для одного клиента-потока.
Часть 2. Конкурентные запросы.
Случаи, когда ошибка повторяется только в случаях, когда несколько клиентов работают с базой одновременно.
Часть 3. Другие случаи.
Случаи, не подходящие под предыдущие определения.
Часть 4. Техники, применяющиеся для отладки Production приложений.
Краткий перечень того, что нужно делать, если приходится тестировать на рабочем сервере.
Текст получился достаточно объёмный, поэтому я посчитала нужным дать ссылку на внешний ресурс, а не выкладывать здесь, так как получилось достаточно «много букаф», а несколько постов подряд на одну тему может утомить.
Пожалуйста, почитайте и покритикуйте. Ваше мнение очень интересно. Комментарии оставляйте здесь 🙂
Основы WEB-программирования
Ориентировано на новичков и только на новичков. Профики и просто разработчики с опытом сами прекрасно все знают. Писать буду применительно к MySQL, но принципы подходят для любых баз данных, работающих с запросами в формате SQL.
На программистских форумах в разделах MySQL регулярно появляются темы с просьбами помочь найти ошибки в SQL-запросах. Ошибки, как правило, оказываются тривиальными и очень легко обнаруживаются без привлечения консилиума форумных гуру. Для новичков и просто ленивых я попробую описать приемы, которыми пользуюсь для отладки запросов сама.
Простые запросы
Переменная $_GET[‘album’] не инициализирована. Причины могут быть самые разные, чаще всего это опечатка в имени переменной. В данном случае, например, я «забыла» передать скрипту параметр album. На самом деле таких ошибок легко избежать, если включить режим ошибок E
Исправили, запускаем снова:
Если текст ошибки Вам ни о чем не говорит, обратитесь к русскоязычным FAQ с описанием ошибок MySQL. Здесь очевидно, что мускул не знает столбца с именем album_id.
Наиболее вероятная причина — опечатка в имени столбца. Часто опечатку можно не заметить в больших запросах или когда имена составлены из аббревиатур и сокращений. Менее вероятно — вы переименовали столбец и забыли. Исправляем имя и получаем, наконец, искомый результат.
Пример, конечно, сильно притянут за уши, и трудно найти такую концентрацию глупых ошибок в одном простом SQL-запросе. Но мне не хватило бы фантазии на несколько разных примеров.
Запросы к нескольким таблицам
Теперь рассмотрим более сложные запросы к нескольким таблицам с группировкой результата. Методы отладки такие же, поэтому я сразу покажу на примере корректно работающего запроса, где чаще всего возникают ошибки. Итак:
В запросах, которые должны вернуть много полей, таблицам и полям лучше назначать «псевдонимы». Таблицам — для более краткой записи, полям — чтобы не было конфликтов имен и не запутаться потом при работе с результатом запроса.
Как узнать на какой именно записи случилась ошибка при обработке запроса?
Дано: есть большая табличка CuteTable, в ней поле MegaField типа varchar(20), в этом поле хранятся даты определенного формата.
При попытке сделать select convert(DATETIME,MegaField,121) from CuteTable случается облом и вываливается ошибка конвертации. Я хочу узнать какая запись тлетворно влияет на табличку, и выкорчевать ее с корнем. Как это правильно сделать?
Доступен инструментарий ms sql management studio 2012.
Субд соответственно mssql 2012
![]()
Используйте метод деления попалам. У большинства баз данных для select есть limit и offset. Вначале делаете запрос для первой половины данных (только не забудьте отсортировать, иначе будете долго искать). Если в первой половине нет, тогда оно гарантированно в второй половине.
При таком подходе, даже есть у Вас 10.000.000 записей, то Вам нужно не более 24 запросов.
Если же Ваша версия БД не поддерживает limit\offset, то можно просто использовать id для этой цели, даже если там есть разрывы.