《MySQL排错指南》——1.1 语法错误

简介:

本节书摘来自异步社区出版社《MySQL排错指南》一书中的第1章,第1.1节,作者:【美】Sveta Smirnova(斯维特 斯米尔诺娃),更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.1 语法错误

这个错误听起来十分简单,但仍可能很难发现。我建议你像处理其他问题一样,非常细心地查找可能出现的SQL语法错误。

类似如下错误,很容易被发现:

image

在这个示例中,很显然用户少转入了个“m”,错误消息也很清楚(输出结果根据页面设置进行宽度调整):

image

遗憾的是,不是所有的语法错误都这么显而易见。我曾经处理过一个问题,它的查询语句是这样的:

image

这是一个版本迁移导致的问题;该语句在5.0版本中运行正常,但是在5.1版本中出现错误。问题的原因在于,在5.1版本中,“accessible”是一个保留字。给该语句加上引号(反引号还是双引号取决于你的SQL格式),即可重新正常运行:

 image

实际场景中的查询语句看起来可能十分繁琐,包括大段的JOIN和复杂的WHERE条件。所以,即使是简单的错误在其他大量语句的干扰下也很难被查找出来。我们当时第一步的任务就是简化复杂的查询,使它变成像刚才看到的那样只有一行SELECT的语句。这就是一个最简化测试的示例。当我们看到简化后只有一行的语句也有同样的bug时,我们就能很快意识到原有程序是因为保留字的问题而产生了错误。

第一教训就是教你把检查查询的语法错误作为排错的第一步。
但是,当你不知道查询是什么样的时候该怎么办?比如,查询是由应用程序自动生成的,或是在存储库中由第三方库动态生成的。

考虑如下PHP代码:

image

从这段脚本中很难直接定位错误。幸运的是,我们可以通过调整代码,使用输出函数打印查询语句。在PHP语言中,可以使用echo运算符。因此,修改代码,如下所示:

image

当程序输出将要提交的语句的时候,问题暴露出来了:

image

如果你仍然没有发现错误,你可以在MySQL命令行客户端中尝试执行这个查询:
image

问题在于每一行都少了一个右单引号。返回PHP代码,需要把:

image

改为:

image

即可。

因此,一个重要的调试技巧是,始终尝试查看MySQL服务器最终接收到的查询。不要仅调试应用程序代码,要获取查询语句!
遗憾的是,你不可能始终使用输出函数。比如,我之前提到的那个场景,SQL语句是在编译好的第三方库中生成的。你的应用程序可能只是使用了库提供的高级的抽象接口,比如CRUD(新建、读、更新、删除)接口。或者在生产环境下,你不希望用户看到在使用特定参数对特定查询进行测试时的查询。在这种情况下,可以检查MySQL的通用查询日志。这里用一个新示例来说明其是如何工作的。

这是一段有问题的PHP代码:

image

这段代码更新了例1.1中定义的表。
**
例1.1 一般问题情形的示例表**
image

现在启用通用查询日志。该日志包含MySQL服务器接收到的每条独立查询。很多产品不会在日常运行中使用该日志,因为它在高负载的情况下增长十分迅速,并且写入日志会消耗MySQL服务器的资源,这些资源很可能用于更重要的用途。从5.1版本开始,你可以临时打开通用查询日志,方便随时记录你需要的查询。可以通过下面命令打开日志:

image

也可以将日志记录在表中,这可以帮你方便地分类索引日志文件项,因为你可以像查询其他表一样访问查询日志表:

image

现在可以运行应用程序。经过迭代地执行问题代码后,查询通用日志记录表,以查找有问题的查询:

image

注意上述代码中2.row中的查询语句:

image

错误再次显而易见:在语句的结尾有个多余的逗号。这个问题是由下面这部分PHP代码产生的:

image

如果字符串确实是以逗号结尾的,那么rtrim函数本应移除结尾的逗号。但是现在这行实际上是以空格结尾的,因此rtrim函数没有移除任何字符。

既然我们已经发现了应用程序中产生错误的原因,我们就可以关闭通用查询日志:

image

在这节,我们学到一些重要的东西:

语法错误可能是导致一些现实问题的原因;
你应该测试与MySQL服务器接收到的请求完全一致的查询;
编程语言的输出函数和通用查询日志可以帮助你快速定位由应用程序发送到MySQL服务器的查询的问题。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
SQL 自然语言处理 关系型数据库
MySQL的match匹配多个字符串的语法
【8月更文挑战第27天】MySQL的match匹配多个字符串的语法
750 67
|
11月前
|
SQL 关系型数据库 MySQL
MySQL的查询操作语法要点
储存过程(Stored Procedures) 和 函数(Functions) : 储存过程和函数允许用户编写 SQL 脚本执行复杂任务.
383 14
|
11月前
|
SQL 关系型数据库 MySQL
MySQL的查询操作语法要点
以上概述了MySQL 中常见且重要 的几种 SQL 查询及其相关概念 这些知识点对任何希望有效利用 MySQL 进行数据库管理工作者都至关重要
266 15
|
SQL 存储 关系型数据库
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
本文详细介绍了MySQL中的SQL语法,包括数据定义(DDL)、数据操作(DML)、数据查询(DQL)和数据控制(DCL)四个主要部分。内容涵盖了创建、修改和删除数据库、表以及表字段的操作,以及通过图形化工具DataGrip进行数据库管理和查询。此外,还讲解了数据的增、删、改、查操作,以及查询语句的条件、聚合函数、分组、排序和分页等知识点。
1535 57
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
|
SQL 关系型数据库 MySQL
MySQL探索:详解WITH AS语法的使用。
总的来说,MySQL的 `WITH AS`语法就如同我们路途中的导航设备,能帮助我们更好地组织和简化查询, 增强了我们和数据沟通的能力,使得复杂问题变得可控且更有趣。不论是在森林深处,还是在数据的海洋中,都能找到自己想要的路途和方向。
2049 12
|
Oracle 关系型数据库 MySQL
比较Oracle和MySQL的语法差异。
在使用Oracle和MySQL时,数据库设计、查询优化、以及日常管理的方式会因为这些差异而有不同的考虑和应用策略。因此,开发人员和数据库管理员必须了解各自数据库的特性和语法差异,以便更有效地利用数据库资源。适应这些语法和功能上的差异对于维护跨数据库平台应用至关重要。
538 0
|
存储 SQL 关系型数据库
【MySQL基础篇】MySQL约束语法
文章介绍了MySQL中表的约束概念,包括非空、唯一、主键、默认和外键约束,以及如何在创建和修改表时指定这些约束。外键约束用于保持数据的一致性和完整性,文章通过示例展示了添加、删除外键的语法,并讨论了不同的删除/更新行为,如CASCADE和SETNULL。
【MySQL基础篇】MySQL约束语法
|
关系型数据库 MySQL 数据库
MySQL的语法涵盖了数据定义、数据操作、数据查询和数据控制等多个方面
MySQL的语法涵盖了数据定义、数据操作、数据查询和数据控制等多个方面
386 6
|
关系型数据库 MySQL 数据库
MySQL的语法知识
MySQL的语法知识
163 5
|
SQL 关系型数据库 MySQL
MySQL语法
MySQL语法
417 4

推荐镜像

更多