如何使用命令行格式化SQL

760 阅读2分钟

简介

在这篇文章中,我将向你展示如何使用命令行格式化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 命令,我们将得到以下结果。

Format SQL using the command lineFormat SQL using the command line

棒极了,对吗?

结论

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