简介
在这篇文章中,我将向你展示如何使用命令行格式化SQL,并将单行SQL语句转化为多行SQL字符串,使其更具可读性。
单行SQL字符串
正如我在这篇文章中所解释的,当使用一个代表你生成语句的数据访问框架时,记录你的SQL查询是非常重要的,不管是Hibernate还是jOOQ。
如果你正在使用Spring或Spring Boot,那么我最喜欢的SQL日志框架是 datasource-proxy,除了日志,它还允许我们在测试过程中检测N+1查询问题。
一旦你添加了datasource-proxy ,SQL语句就会被记录下来,如下所示。
2022-03-30 10:22:18.274 DEBUG 6152 --- [io-8080-exec-10] n.t.d.l.l.SLF4JQueryLoggingListener :
Name:dataSource, Connection:6, Time:0, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["select visits0_.pet_id as pet_id4_6_0_, visits0_.id as id1_6_0_, visits0_.id as id1_6_1_, visits0_.visit_date as visit_da2_6_1_, visits0_.description as descript3_6_1_, visits0_.pet_id as pet_id4_6_1_ from visits visits0_ where visits0_.pet_id=?"]
Params:[(1)]
虽然你可以在日志记录时格式化SQL语句,但这是不可取的,因为这会使提取日志信息并聚合的日志解析逻辑复杂化(例如Elastic Stack)。因此,我们需要一种方法来按需格式化SQL语句,只针对我们感兴趣的查询进行分析。
关于如何用Spring Boot配置
datasource-proxy的更多细节,请查看这篇文章。
SQLFormat Dot Org
如果你曾经参加过我的精彩培训和研讨会,那么你已经知道我在使用SQLFormat来格式化我们在培训中运行的测试案例所产生的SQL语句。
这项服务的伟大之处在于它提供了一个我们可以用来格式化SQL语句的API。
根据你所使用的操作系统,你可以选择其中一个提供的选项来调用SQLFormat服务。在我的例子中,由于我是在Windows上运行的,所以我创建了下面的PowerShell脚本。
# Payload in hashtable
$body = @{
sql = $args[0]
reindent = 1
indent_width = 3
# identifier_case ="upper"
keyword_case = "upper"
strip_comments = 1
}
# Prepare hashtable to be used in the invocation
$params = @{
Uri = 'https://sqlformat.org/api/v1/format'
Method = 'POST'
Body = $body
ContentType = "application/x-www-form-urlencoded"
}
# Invoke using hashtables
$response = Invoke-RestMethod @params
write-host $response.result
为了方便调用这个Powershell脚本,我在Powershell脚本所在的同一文件夹中创建了以下sqlformat.bat Windows批处理脚本。
@echo off
Powershell.exe -File %~dp0\sqlformat.ps1 "%*"
我所有的Windows批处理脚本都存储在PATH 环境变量中的一个文件夹中,所以我可以直接从命令行中执行它们,而不需要提供脚本路径位置。
使用命令行格式化一个SQL查询
当从前面的日志条目中提取SQL语句时,我们可以简单地把它传递给sqlformat 命令,我们将得到以下结果。


棒极了,对吗?
结论
SQLFromat网站使解析你的SQL语句变得非常容易,你可以很容易地把它的功能作为一个命令行工具公开。