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.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
-
Кнопка:
Она выглядит вот так:
-
Текстовая ссылка:
Она выглядит вот так: Как создать свой сайт
- 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 25G
*************************** 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 systemG
*************************** 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)
Содержание
- Часть 1. Одиночные запросы.
- SQL syntax checker
- SQL query
- User guide
- SQL validator online
- SQL Syntax Checker, SQL Syntax Validator
- Validate SQL Syntax, show syntax errors, beautify SQL statements
- SQL queries are easy to learn and reuse.
- How to Validate Syntax and Disable Statement Execution
- Using SQL Queries to Create Visualizations
- AST Tree Algorithm
- SQL is the Language used to Communicate with Databases
- SQLShack
- SQL Syntax Checker Tools
- What is a SQL syntax checker?
- What is the query parsing in SQL Server?
- How to validate query syntax with SQL Server Management Studio (SSMS)
- Как найти ошибку в SQL-запросе
- Комментарии ( 1 ):
Часть 1. Одиночные запросы.
Наверное многие из вас знают, хотя бы из школьного курса математики, что любая сложная задача может быть сведена к набору простых. Тот же приём можно применить и к проблемам SQL приложения.
Для начала посмотрим пример с простым запросом. Ошибка в этом случае находится очень просто.
Я думаю, большинство читателей уже заметили в чём проблема. Если выполнить этот запрос в mysql cli ошибка стнает ещё заметней:
То есть это синтаксическая ошибка: опущена поледняя буква o в предикате from. Просто, не правда ли?
Возьмём пример посложнее. Это код на PHP. (Для любителей холиворов повторю, что код был подготовлен для PHP конференции в Москве. Аналогичную путаницу можно написать и на любом другом вашем любимом языке программирования.)
В данном случае вычленить ошибку уже труднее. А что будет в случае ещё более сложного запроса?
В случае с PHP нам поможет простой операто echo, который осуществляет вывод:
И тут нам ошибка становится более очевидной: пропущен закрывающий апостроф в выражении
Достаточно заменить его выражением
и запрос будет выполняться верно.
Обратите внимание, что мы выводили запрос именно в том виде, в котором его получает СУБД. Намного проще найти ошибку в готовом запросе, чем в строке, которая собирается из разных частей или содержит переменные.
Использование оператора вывода для выявления проблемного запроса простейший, но эффективный приём.
Приём 1: используйте оператор вывода для вывода запроса в том виде, в котором его получает СУБД.
К сожалению мы не всегда можем использовать echo. Например в случае поддержки существующего сложного приложения.
Посмотрим на следующий пример.
Проблема возникла на web-странице со следущим интерфейсом:
* Учебник
* Тест
* test2
* test2
* test2
* test2
* test2
Введите название новой системы:
Проблема в том, что у нас каким-то образом образовалось несколько систем с одинаковым именем.
Посмотрим на код, который за это отвечает:
Что-нибудь понятно? Я думаю опытный человек может предположить в чём проблема, но в любом случае это только гипотеза, которую необходимо подтвердить или опровергнуть. Ещё менее понятно где в этом примере добавить вывод и вывод чего именно: у нас нет ни обращения к базе, ни запроса.
В PHP достаточно легко изменить код библиотеки, который отвечает за компиляцию запроса, чтобы он печатал его (запрос) в файл или на stderr перед тем, как отправить базе, но в случае с компилируемыми языками, например, с Java, библиотеку придётся перекомпилировать. Да и не всегда код библиотеки открыт.
Что же делать? В случае с MySQL мы можем применить general query log:
В 22 строке мы видим наш запрос. Он не выглядит проблемным: обычный INSERT.
Посмотрим что мы имеем в таблице system:
Посмотрим её определение:
Поле name не является уникальным. Поэтому мы можем решить проблему с дубликатами двумя способами: нужно либо сделать это поле уникальным
либо изменить приложение таким образом, чтобы эта проблема обрабатывалась не на уровне SQL.
Мы только что рассмотрели следующий приём: используйте general query log для выявления запроса, который вызывает неправильное поведение.
Приём 2: используйте general query log, если вам нужно определить какой именно запрос вызывает неправильное поведение вашего приложения.
Мы убедились, что практически всегда можно выделить запрос, вызвавший проблему в приложении. В большинстве случаев этого достаточно, чтобы найти и устранить ошибку. Это объясняет, почему большую часть данного текста я отвела именно для поиска проблемного запроса. Конечно, существуют ситуации, когда нахождением единичного запроса не отделаться. Эти ситуации будут рассмотрены отдельно. Я хотела бы обратить ваше внимание на следующие запросы:
Зачем нам нужно изменять значение глобальной переменной, если мы можем влдючить general query log в конфигурационном файле?
Дело в том, что general query log сам по себе весьма дорогостоящ: он увеличивает нагрузку на сервер и так как он содержит все запросы, то вам также придётся следить за местом на диске. Начиная же с версии 5.1 его можно включать-выключать в режиме реального времени тем самым сводя дополнительную нагрузку на MySQL сервер к минимуму.
Следующий запрос включает вывод не в файл, а в таблицу. Вывод в таблицу хорош для выявления таких проблемных запросов как в последних 2-ух примерах, так как таблицу легко отсортировать: вы обращаетесь к ней также как к любой другой таблице.
Источник
SQL syntax checker
SQL query
SQL checker allows to check your SQL query syntax, it focuses on MySQL dialect (MySQL syntax checker). You can valide the syntax of your queries and find the syntax errors easily (the errors are highlighted).
User guide
To check syntax code:
- First, Drag and drop your SQL file or copy / paste your request directly into the editor above.
- Finally, you must click on «Check SQL syntax» button to display if there is an syntax error in your code.
You can click on «Format SQL query» to make your query more readable. This simplifies the correction.
SQL validator online
SQL (Structured Query Language) is a domain-specific language used in relational databases. It is useful in handling structured data.
When working on a large SQL query, it is sometimes difficult to find where a syntax error is.
SQL error checker tool allows to find syntax errors. You can test your SQL query online directly in your browser.
If a syntax error is detected in your request, then the line in error is highlighted (rather useful for large sql requests). Frequent errors: forgetting to close parentheses, typology error of a keyword, omission of a keyword, .
It is not necessarily easy to start in SQL, even for developers (it has nothing to do with programming languages). Even knowing the syntax of SQL, there is still a lot to learn to use the full power of SQL!
It checks the MySQL dialect because it is the most popular database. Mysql shares a significant part of its sql syntax with other databases (But there are of course differences with other databases like postgres, db2, . ). If you think it would be interesting to make it compatible with other databases, let me known via a comment.
Hoping that this little tool will be useful to developers and database administrators. It is a simple but effective tool 🙂
If you think of new features, do not hesitate to add a comment. I do not have a lot of time but I will do my best.
This tool uses the library SQL parser. This library has been used by phpMyAdmin since version 4.5!
Источник
SQL Syntax Checker, SQL Syntax Validator
Validate SQL Syntax, show syntax errors, beautify SQL statements
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.
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.
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:
- what tables appear in the query?
- what columns appear in the query, per clause?
- what is the table/column lineage of a query?
- what sets of columns does a query compare for equality?
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.
The only truly secure system is one that is powered off, cast in a block of concrete and sealed in a lead-lined room with armed guards.
Источник
SQLShack
In this article, we will look at the 2 different SQL syntax checker tools that help to find the syntax errors of the queries without executing them.
What is a SQL syntax checker?
SQL syntax checker tools validate SQL syntax or indicate the incorrect syntax errors if it exists. These tools can be helpful to determine the syntax errors without executing the whole query. The following 2 tools can be used to validate the syntax of our T-SQL queries:
What is the query parsing in SQL Server?
When we submit a query in SQL Server to execute, it performs 3 essential phases during the execution of the query:
- Parse: In this phase, the Query Parser checks and validates the syntax of the SQL statement and generates a parse tree of the query. The parse tree is sent to the next stage for processing
- Compile: In this phase, the query optimizer generates an execution plan for the query
- Execute: In this final stage, the storage engine executes the SQL statements
How to validate query syntax with SQL Server Management Studio (SSMS)
SQL Server Management Studio (SSMS) is an advanced integrated development tool to manage, administrate, and configure SQL Server and it also offers a query editor option to develop and execute T-SQL queries. We can find a Parse button on the query editor toolbar of SSMS, that only checks the syntax of the selected statement or all statements that are given by the users. So that, we can use SSMS as a SQL syntax checker tool.
Here we need to take into account that, when we parse a query the compile and execute phases are not performed. In the following example, we will check the syntax of a very simple query. To validate a query syntax consists of only 2 simple steps:
- Paste or write query into the query panel
- Click the parse button or press the Control + F5 key combination
As seen, the query syntax has been validated successfully. Now we will remove the FROM clause of the statement and re-parse the query.
After the re-parsing of the query, SQL Server returns an incorrect syntax error. Another option to check the syntax of the queries is using the SET PARSE ONLY command. This command configures the session into parsing mode.
Источник
Как найти ошибку в SQL-запросе
SQL-запрос — это то, что либо работает хорошо, либо не работает вообще, частично он никак работать не может, в отличие, например, от того же PHP. Как следствие, найти ошибку в SQL-запросе, просто рассматривая его — трудно, особенно если этот запрос снабжён целой кучей JOIN и UNION. Однако, в этой статье я расскажу о методе поиска ошибок в SQL-запросе.
Поскольку обычно в SQL-запрос подставляются какие-то переменные в PHP, то необходимо его сначала вывести. Сделать это можно, например, так:
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 С уважением Сергей.
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.
Copyright © 2010-2023 Русаков Михаил Юрьевич. Все права защищены.
Источник
Время на прочтение
1 мин
Количество просмотров 1.1K
По мотивам своего мастер-класса на PHPConf 2009 (http://phpconf.ru) я написала гид для тех, кому нужно поймать ошибку в SQL приложении. Правильнее было бы назвать в MySQL приложении, но я всё-таки думаю, что общие принципы едины для всех. В идеале мне бы хотелось, чтобы текст охватывал основные случаи неправильного поведения. Оговорюсь, что под неправильным поведением я понимаю логические ошибки, а не проблемы производительности. Проблемы производительности — это отдельная тема, кстати, достаточно хорошо представленная в сети.
Книжка состоит из 4 частей, ниже можно посмотреть краткое содержание:
Часть 1. Одиночные запросы.
Рассмотрены случаи, когда ошибка повторяется для одного клиента-потока.
Часть 2. Конкурентные запросы.
Случаи, когда ошибка повторяется только в случаях, когда несколько клиентов работают с базой одновременно.
Часть 3. Другие случаи.
Случаи, не подходящие под предыдущие определения.
Часть 4. Техники, применяющиеся для отладки Production приложений.
Краткий перечень того, что нужно делать, если приходится тестировать на рабочем сервере.
Текст получился достаточно объёмный, поэтому я посчитала нужным дать ссылку на внешний ресурс, а не выкладывать здесь, так как получилось достаточно «много букаф», а несколько постов подряд на одну тему может утомить.
Пожалуйста, почитайте и покритикуйте. Ваше мнение очень интересно. Комментарии оставляйте здесь 🙂
Почитать можно здесь: sql-error.microbecal.com
Designing Queries
Соблюдение нескольких соглашений значительно облегчает поиск ошибок в запросах,особенно когда вы обращаетесь за помощью к людям,которые могут знать SQL,но ничего не знают о вашей конкретной схеме.Легко читаемый запрос-это легко отлаживаемый запрос.Используйте пробельные символы для группировки предложений в запросе.Выбирайте хорошие псевдонимы таблиц и полей,чтобы добавить ясности,а не путаницы.Выбирайте синтаксис,который поддерживает смысл запроса.
Using Whitespace
Трудночитаемый запрос-трудноотлаживаемый запрос.Белое пространство свободно.Новые строки и отступы облегчают чтение запросов,особенно при построении запроса на языке сценариев,где переменные перемежаются по всему запросу.
В приведенном ниже тексте допущена синтаксическая ошибка.Как быстро вы сможете ее найти?
SELECT u.id, u.name, alliance.ally FROM users u JOIN alliance ON (u.id=alliance.userId) JOIN team ON (alliance.teamId=team.teamId WHERE team.teamName='Legionnaires' AND u.online=1 AND ((u.subscription='paid' AND u.paymentStatus='current') OR u.subscription='free') ORDER BY u.name;
Вот тот же запрос с правильным использованием пробельных символов.Можете ли вы быстрее найти ошибку?
SELECT u.id , u.name , alliance.ally FROM users u JOIN alliance ON (u.id = alliance.userId) JOIN team ON (alliance.teamId = team.teamId WHERE team.teamName = AND u.online = 1 AND ( (u.subscription = OR u.subscription = ) ORDER BY u.name;
Даже если вы не знаете SQL,вы все равно могли заметить отсутствие ‘)’ после team.teamId.
Точный стиль форматирования,который вы используете,не так важен.Возможно,вы хотите,чтобы запятые в списке выбора следовали за выражениями,а не предшествовали им.Вы можете делать отступы с помощью табуляции или пробелов.Соблюдение определенной формы не имеет значения.Единственной целью является наглядность.
Псевдонимы таблиц и полей
Псевдонимы позволяют переименовывать таблицы и поля для использования в запросе.Это может быть удобно,когда исходные имена очень длинные,и требуется для самосоединений и некоторых подзапросов.Однако неправильно подобранные псевдонимы могут не облегчить,а усложнить отладку запроса.Псевдонимы должны отражать оригинальное имя таблицы,а не произвольную строку.
Bad:
SELECT * FROM financial_reportQ_1 AS a JOIN sales_renderings AS b ON (a.salesGroup = b.groupId) JOIN sales_agents AS c ON (b.groupId = c.group) WHERE b.totalSales > 10000 AND c.id != a.clientId
По мере роста списка объединенных таблиц и предложения WHERE возникает необходимость неоднократно возвращаться к началу запроса,чтобы узнать,к какой таблице относится тот или иной псевдоним.
Better:
SELECT * FROM financial_report_Q_1 AS frq1 JOIN sales_renderings AS sr ON (frq1.salesGroup = sr.groupId) JOIN sales_agents AS sa ON (sr.groupId = sa.group) WHERE sr.totalSales > 10000 AND sa.id != frq1.clientId
Каждый псевдоним немного длиннее,но инициалы таблиц дают достаточно подсказок,чтобы человек,знакомый с базой данных,мог увидеть полное имя таблицы только один раз и,как правило,запомнить,какая таблица относится к какому псевдониму,читая остальную часть запроса.
Размещение условий JOIN
Руководство предостерегает от использования условия JOIN (то есть,предложения ON)для ограничения строк.Некоторые запросы,особенно те,которые используют неявные соединения,принимают противоположную крайность-все условия соединения переносятся в предложение WHERE.В результате отношения в таблице смешиваются с бизнес-логикой.
Bad:
SELECT * FROM family, relationships WHERE family.personId = relationships.personId AND relationships.relation = 'father'
Не копаясь в пункте WHERE,невозможно сказать,что связывает эти две таблицы.
Better:
SELECT * FROM family JOIN relationships ON (family.personId = relationships.personId) WHERE relationships.relation =
Связь между таблицами очевидна сразу.Предложение WHERE оставлено для ограничения строк в наборе результатов.
Соблюдение такого ограничения сводит на нет использование оператора запятой для объединения таблиц.Это небольшая цена.Запросы в любом случае следует писать с использованием явного ключевого слова JOIN,и эти два оператора никогда не следует смешивать (если только вам не нравится переписывать все свои запросы каждый раз,когда в новой версии меняется приоритет оператора).
Поиск синтаксических ошибок
Синтаксические ошибки-одни из самых легко решаемых проблем.MariaDB выдает сообщение об ошибке,показывающее точное место,где синтаксический анализатор запутался.Проверьте запрос,включая несколько слов перед фразой,показанной в сообщении об ошибке.Большинство синтаксических и синтаксических ошибок очевидны после второго взгляда,но некоторые из них более неуловимы,особенно когда текст ошибки кажется пустым,указывает на правильное ключевое слово,или кажется,что ошибка в синтаксисе,который кажется совершенно правильным.
Интерпретация пустой ошибки
Большинство синтаксических ошибок легко интерпретировать.В ошибке обычно указывается точный источник проблемы.Внимательное изучение запроса с учетом сообщения об ошибке часто позволяет обнаружить очевидную ошибку,например,неправильно написанные имена полей,пропущенное ‘AND’ или лишнюю закрывающую скобку.Иногда ошибка оказывается не столь полезной.Частое,менее полезное сообщение:
ERROR 1064: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near
Пустое ‘ ‘ может обескуражить.Очевидно,что произошла ошибка,но где? Хорошее место для поиска-конец запроса.’ ‘ говорит о том,что синтаксический анализатор достиг конца высказывания,но все еще ожидает появления синтаксического маркера.
Проверьте,нет ли отсутствующих закрывающих элементов,таких как ‘ и ):
SELECT * FROM someTable WHERE field =
Ищите неполные предложения,которые часто обозначаются открытой запятой:
SELECT * FROM someTable WHERE field = 1 GROUP BY id,
Проверка наличия ключевых слов
MariaDB допускает имена таблиц и полей, а также псевдонимы, которые также являются зарезервированными словами . Во избежание двусмысленности такие имена должны быть заключены в обратные кавычки (`):
SELECT * FROM actionTable WHERE `DELETE` = 1;
Если рядом с одним из ваших идентификаторов отображается синтаксическая ошибка, проверьте, присутствует ли он в списке зарезервированных слов .
Текстовый редактор с цветовой подсветкой синтаксиса SQL помогает найти эти ошибки.Когда вы вводите имя поля,а оно отображается тем же цветом,что и ключевое слово SELECT,вы знаете,что что-то не так.Некоторые распространенные ошибки:
- DESC — это обычное сокращение для полей «описание». Это означает «нисходящий» в предложении MariaDB ORDER .
- DATE , TIME и TIMESTAMP являются общими именами полей. Они также являются типами полей.
- ЗАКАЗ появляется в приложениях для продаж. MariaDB использует его для указания сортировки результатов.
Некоторые ключевые слова настолько распространены,что MariaDB делает специальное разрешение на их использование без кавычек.Мой совет:не делайте этого.Если это ключевое слово,заключите его в кавычки.
Синтаксис,зависящий от версии
По мере добавления в MariaDB новых функций синтаксис должен меняться для их поддержки.В большинстве случаев старый синтаксис будет работать в новых версиях MariaDB.Заметным исключением является изменение приоритета оператора запятой по отношению к ключевому слову JOIN в версии 5.0.Запрос,который раньше работал,например
SELECT * FROM a, b JOIN c ON a.x = c.x;
теперь не получится.
Однако более распространенной является попытка использовать новый синтаксис в старой версии.Известно,что хостинговые компании медленно обновляют MariaDB,и вы можете обнаружить,что используете версию,устаревшую на несколько лет.Результат может быть очень неприятным,когда запрос,который безупречно выполняется на вашей собственной рабочей станции с последней версией,не работает в производственной среде.
Этот запрос не работает в любой версии MySQL до 4.1,когда на сервер были добавлены подзапросы:
SELECT * FROM someTable WHERE someId IN (SELECT id FROM someLookupTable);
Этот запрос не работает в некоторых ранних версиях MySQL,поскольку синтаксис JOIN изначально не допускал предложения ON:
SELECT * FROM tableA JOIN tableB ON tableA.x = tableB.y;
Всегда проверяйте установленную версию MariaDB и читайте раздел руководства,относящийся к этой версии.В руководстве обычно указывается,когда именно конкретный синтаксис стал доступен для использования.
Содержание,воспроизводимое на этом сайте,является собственностью соответствующих владельцев,и это содержание не просматривается заранее компанией MariaDB.Взгляды,информация и мнения,выраженные в этом содержании,не обязательно представляют собой взгляды,информацию и мнения,выраженные MariaDB или любой другой стороной.