Найти ошибку mysql

SQL queries are easy to learn and reuse.

The difficulty of reading and understanding current SQL queries is known as query interpretation. It’s frequently as difficult as Query Composition, which entails writing a new query.

SQL Syntax Checker validates and marks any errors in your SQL queries.

Common Causes of Syntax Errors

  • Mismatched number of open and close parentheses
  • Improper query language used 
  • The data required for the query is missing
  • Typos
  • Syntax errors such as misspelling
  • Use of Reserved words
  • An old version of the keyword is used
  • Misspelling a keyword or function name

How to Validate Syntax and Disable Statement Execution

Before executing SQL on your production database server, you can run a SQL syntax check without connecting to the database server and look for syntax issues.
The following are supported by the database: Oracle (PLSQL), SQL Server, MySQL, DB2, and Access are all examples of database management systems.
When you’re debugging and come across any syntax that’s part of a long query and wants to validate it, all you have to do is use Syntax.

SQL is the Language used to Communicate with Databases

SQL, SQL Server, MySQL, PostgreSQL, Oracle, and so on. You want to learn SQL, but you’re intimidated by the number of keywords and don’t know where to begin. Let’s go over the definitions for each of these terms.

A database is a type of computer program that stores and processes vast volumes of information. Database vendors come in a variety of shapes and sizes. Database products from different vendors include PostgreSQL, MySQL, Oracle, and SQL Server. The programming language SQL is used to communicate with these databases, and each database product has its SQL variant. These variations are referred to as SQL dialects.

Using SQL Queries to Create Visualizations

Many individuals have tried but failed to create a successful parser due to the intricacy of the SQL grammar and dialicts. Our parser reduces the problems of deciphering SQL grammar. The parsing logic generates an abstract syntax tree (AST) containing «raw» or optionally qualified table and column IDs.

AST Tree Algorithm

The parsing stage entails breaking down the components of a SQL statement into a data structure that may be processed by subsequent algorithms. The database only parses a statement when the application tells it to. Therefore only the application, not the database, may reduce the number of parses. Various utility function analyze the AST tree to identify the components:

  1. what tables appear in the query?
  2. what columns appear in the query, per clause?
  3. what is the table/column lineage of a query?
  4. what sets of columns does a query compare for equality?

Как найти ошибку в 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-запросе.

  • Создано 01.05.2013 10:54:01


  • Михаил Русаков

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

����� 1. ��������� �������.

����� 1. ������.

�������� ������ �� ��� �����, ���� �� �� ��������� ����� ����������, ��� ����� ������� ������ ����� ���� ������� � ������ �������. ��� �� ��ɣ� ����� ��������� � � ��������� SQL ����������.

��� ������ ��������� ������ � ������� ��������. ������ � ���� ������ ��������� ����� ������.


select * fro t1 where f1 in (1,2,1);

� �����, ����������� ��������� ��� �������� � ޣ� ��������. ���� ��������� ���� ������ � mysql cli ������ ������ �ݣ ��������:


mysql> select * fro t1 where f1 in (1,2,1);
ERROR 1064 (42000): 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 'fro t1 where f1 in (1,2,1)' at line 1

�� ���� ��� �������������� ������: ������� �������� ����� o � ��������� from. ������, �� ������ ��?

����ͣ� ������ ���������. ��� ��� �� PHP. (��� ��������� ��������� �������, ��� ��� ��� ����������� ��� PHP ����������� � ������. ����������� �������� ����� �������� � �� ����� ������ ����� ������� ����� ����������������.)


$query = 'SELECT * FROM t4 WHERE f1 IN(';
for ($i = 1; $i < 101; $i ++)
$query .= "'row$i,";
$query = rtrim($query, ',');
$query .= ')';
$result = mysql_query($query);

� ������ ������ ��������� ������ ��� �������. � ��� ����� � ������ �ݣ ����� �������� �������?

� ������ � PHP ��� ������� ������� ������� echo, ������� ������������ �����:


$query = 'SELECT * FROM t4 WHERE f1 IN(';
for ($i = 1; $i < 101; $i ++)
$query .= "'row$i,";
$query = rtrim($query, ',');
$query .= ')';
echo $query;
//$result = mysql_query($query);

�������� ������:


$php phpconf2009_1.php
SELECT * FROM t4 WHERE f1 IN('row1,'row2,'row3,'row4,'row5,'row6,'row7,'row8,'row9,'row10,'row11,
'row12,'row13,'row14,'row15,'row16,'row17,'row18,'row19,'row20)

� ��� ��� ������ ���������� ����� ���������: �������� ����������� �������� � ���������


$query .= "'row$i,";

���������� �������� ��� ����������


$query .= "'row$i',";

� ������ ����� ����������� �����.

�������� ��������, ��� �� �������� ������ ������ � ��� ����, � ������� ��� �������� ����. ������� ����� ����� ������ � ������� �������, ��� � ������, ������� ���������� �� ������ ������ ��� �������� ����������.

������������� ��������� ������ ��� ��������� ����������� ������� ����������, �� ����������� ��ɣ�.

��ɣ� 1: ����������� �������� ������ ��� ������ ������� � ��� ����, � ������� ��� �������� ����.

� ��������� �� �� ������ ����� ������������ echo. �������� � ������ ��������� ������������� �������� ����������.

��������� �� ��������� ������.

�������� �������� �� web-�������� �� �������� �����������:


��������� �������

    * �������
    * ����
    * test2
    * test2
    * test2
    * test2
    * test2

������� �������� ����� �������:

<>

��������:

<>

<Go!>

�������� � ���, ��� � ��� �����-�� ������� ������������ ��������� ������ � ���������� ������.

��������� �� ���, ������� �� ��� ��������:


$system = System::factory()
->setName($this->form->get(Field::NAME))
->setDescription(
$this->form->get(Field::DESCRIPTION)
);
DAO::system()->take($system);

���-������ �������? � ����� ������� ������� ����� ������������ � ޣ� ��������, �� � ����� ������ ��� ������ ��������, ������� ���������� ����������� ��� ������������. �ݣ ����� ������� ��� � ���� ������� �������� ����� � ����� ���� ������: � ��� ��� �� ��������� � ����, �� �������.

� PHP ���������� ����� �������� ��� ����������, ������� �������� �� ���������� �������, ����� �� ������� ��� (������) � ���� ��� �� stderr ����� ���, ��� ��������� ����, �� � ������ � �������������� �������, ��������, � Java, ���������� ���ģ��� �����������������. �� � �� ������ ��� ���������� ������.

��� �� ������? � ������ � MySQL �� ����� ��������� general query log:


mysql> set global log_output='table';
Query OK, 0 rows affected (0.00 sec)


mysql> select * from mysql.general_log;
Empty set (0.09 sec)


mysql> set global general_log='on';
Query OK, 0 rows affected (0.00 sec)

��������� ����������.


mysql> select * from mysql.general_log order by event_time desc limit 25\G
*************************** 1. row ***************************
  event_time: 2009-10-19 13:00:00
   user_host: root[root] @ localhost []
   thread_id: 10323
   server_id: 60
command_type: Query
    argument: select * from mysql.general_log order by event_time desc limit 25
...
*************************** 22. row ***************************
  event_time: 2009-10-19 12:58:20
   user_host: root[root] @ localhost [127.0.0.1]
   thread_id: 10332
   server_id: 60
command_type: Query
    argument: INSERT INTO `system` (`id`, `name`, `description`) VALUES ('', 'test2', '')
...
mysql> set global general_log='off';
Query OK, 0 rows affected (0.08 sec)

� 22 ������ �� ����� ��� ������. �� �� �������� ����������: ������� INSERT.

��������� ��� �� ����� � ������� system:


mysql> select * from system;
+----+---------+------------------------------------------+
| id | name    | description                              |
+----+---------+------------------------------------------+
|  1 | �������  | ��������������� ������� � ������� ������      |
|  2 | ����     | �������� �������������� �����                 |
|  3 | test2   | New test                                 |
|  4 | test2   | foobar                                   |
|  8 | test2   |                                          |
+----+---------+------------------------------------------+
5 rows in set (0.00 sec)

��������� ţ �����������:


mysql> show create table system\G
*************************** 1. row ***************************
       Table: system
Create Table: CREATE TABLE `system` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `description` tinytext NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
1 row in set (0.09 sec)

���� name �� �������� ����������. ������� �� ����� ������ �������� � ����������� ����� ���������: ����� ���� ������� ��� ���� ����������


(alter table system add unique(name))

���� �������� ���������� ����� �������, ����� ��� �������� �������������� �� �� ������ SQL.

�� ������ ��� ����������� ��������� ��ɣ�: ����������� general query log ��� ��������� �������, ������� �������� ������������ ���������.

��ɣ� 2: ����������� general query log, ���� ��� ����� ���������� ����� ������ ������ �������� ������������ ��������� ������ ����������.

�� ���������, ��� ����������� ������ ����� �������� ������, ��������� �������� � ����������. � ����������� ������� ����� ����������, ����� ����� � ��������� ������. ��� ���������, ������ ������� ����� ������� ������ � ������ ������ ��� ������ ����������� �������. �������, ���������� ��������, ����� ����������� ���������� ������� �� ����������. ��� �������� ����� ����������� ��������.
� ������ �� �������� ���� �������� �� ��������� �������:


mysql> select * from mysql.general_log;
Empty set (0.09 sec)


mysql> set global general_log='on';
Query OK, 0 rows affected (0.00 sec)

...

mysql> set global general_log='off';
Query OK, 0 rows affected (0.08 sec)

����� ��� ����� �������� �������� ���������� ����������, ���� �� ����� �������� general query log � ���������������� �����?

���� � ���, ��� general query log ��� �� ���� ������ �����������: �� ����������� �������� �� ������ � ��� ��� �� �������� ��� �������, �� ��� ����� ���ģ��� ������� �� ������ �� �����. ������� �� � ������ 5.1 ��� ����� ��������-��������� � ������ ��������� ������� ��� ����� ����� �������������� �������� �� MySQL ������ � ��������.

��������� ������ �������� ����� �� � ����, � � �������. ����� � ������� ����� ��� ��������� ����� ���������� �������� ��� � ��������� 2-�� ��������, ��� ��� ������� ����� �������������: �� ����������� � ��� ����� ��� � ����� ������ �������.


mysql> set global log_output='table';
Query OK, 0 rows affected (0.00 sec)

After searching for a CLI tool for syntax linting in Mysql to use in Jenkins and didn’t find anything quickly (this Stackoverflow question is one of the first results — LOL) I came up with the following solution (OS: Linux, but should be feasible with Windows too):

Something like the follwoing:

lint_result=`mysql mysql_test -B -f -e 'select asdf s where x;' 2>&1`; if [ `echo $lint_result | sed -r "s/ERROR ([0-9]*).*/\1/g"` -eq 1064 ]; then echo -e "Syntax error:\n${lint_result}"; fi
Syntax error:
ERROR 1064 (42000) at line 1: 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 'where x' at line 1

(To check sql files you can use «< filename.sql» instead of -b -e ‘statement’)

If the syntax of the query can not be parsed by mysql it claims:
ERROR 1064 (42000) at line 1: 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 » at line 1

Only if the syntax is correct it tries to execute the query and realize that the table don’t exists but this isn’t interesting anymore:

ERROR 1146 (42S02) at line 1: Table 'mysql_test.s' doesn't exist

Therefor Error 1064 is the invalid syntax. You only need to create an empty test database because otherwise only errors with a wrong FROM part would appear (here for example the database is needed in order to get a valid syntax check result: ‘select asdf from s where x and if;).

As far as i tested it works fine (Version Mysql 5.5).

Here a complete bash script vesion:

#!/bin/bash

source_dir=${1};
database="mysql_test";
mysql_args="-h127.0.0.1";

mysql $mysql_args -B -e "DROP DATABASE IF EXISTS $database; CREATE DATABASE $database;";
for file in `find $source_dir -name "*.sql"`; do
    lint_result=`mysql $mysql_args $database -f -b < $file 2>&1`;
    if [ "`echo $lint_result | sed -r \"s/ERROR ([0-9]*).*/\1/g\"`" = "1064" ]; then
        echo -e "Syntax error in file ${file}:\n${lint_result}" && exit 1;
    fi;
done

Время на прочтение
1 мин

Количество просмотров 5.7K

Здравствуй Хабр!

Периодически возникает необходимость отследить запросы, которые отправляет Ваше приложение к базе данных. К примеру:
— Вам нужно отладить/доработать чужой код;
— Запросы генерируются с помощью сторонней библиотеки (к примеру ActiveRecord), не понятно, какие именно и сколько их;
— Нужно оптимизировать приложение: посмотреть какие запросы и сколько их, посмотреть explain этих запросов.

В этих ситуациях на помощь приходит Beaver mysql logger.

Для отслеживания запросов достаточно mysql консоли, включить set global general_log = ‘on’; и set global log_output = ‘table’; и просматривать логи в таблице general_log, но это не удобно:

— отсутствие форматирования и подсветки;
— если параллельно выполняется несколько потоков — визуально сложнее найти искомый запрос.
etc.

Поскольку в general_log мне приходилось заглядывать часто, а готовых инструментов я не нашел — я написал Beaver mysql logger.

Демо.

На демо сайте explain и выполнение ограничены одним запросом в целях безопасности (всегда будет выполняться запрос по умолчанию, независимо от того, какой Вы запрос выбрали).

Что умеет:
— включать/отключать general_log;
— выводить лог в приятный Web интерфейс;
— поиск по логам;
— делать explain запросов;
— можно отредактировать и выполнить запрос;
— очищать general_log.

Скачать можно отсюда: Сайт проекта.

При обнаружении багов — просьба сообщить. Спасибо!

Понравилась статья? Поделить с друзьями:
  • Найти ошибки реестра
  • Найдите ошибку основными типами растительности россии являются
  • Найдите ошибку обмен веществ неотделим от превращения
  • Найдите ошибку основными объектами правопреемства являются
  • Найдите ошибку основными источниками международного права являются