liquibase - liquibase "splitStatements"有什么好处?

标签 liquibase liquibase-sql

正在使用的 liquibase 版本 - org.liquibase:liquibase-core:3.8.2。 (不是专业版)

Liquibase 文档(12)在下面说明了 splitStatements(默认为 true)

Set to false to not have Liquibase split statements on ;'s and GO's. Defaults to true if not set

Removes Liquibase split statements on ;'s and GO's when it is set to false. Default value is: true.

我发现的另一个有用的 sof 帖子 - In Liquibase is it OK to have an empty line on splitstatements?

我明白 - 当 splitStatements 为真时,liquibase 会拆分 ;GO

上的语句
  1. 目前还不完全清楚 splitStatements 有什么好处 - 即如果 SQL 语句在 ; (结束分隔符)上拆分,它会有什么不同 - 即如果语句在单个查询或多个查询中执行 - 数据库不会处理“;”无论如何基于的东西。这似乎是理解的必要条件。 --有人能举个例子吗。
  2. 我当前的项目有 splitStatements:false。我们通过禁用 splitStatements 获得了哪些优势。 -任何例子将不胜感激。

------------------------@user13579 回答后扩展了问题
下面是 liquibase 变更日志文件的摘录。这就是让我想到这个问题的原因。它在脚本中有 splitStatements:false 和一个 ;,并且可以正常工作。使用 splitStatements:false 我希望在这种情况下出现错误,我想答案在这种情况下也会提示错误。以下是生产代码,所以我不确定它是如何工作的,后端是 POSTGRE。谁能解释一下。

--liquibase formatted sql

--changeset adam:001-users-001 failOnError:true splitStatements:false logicalFilePath:001-users.sql

CREATE TABLE sys_users
(
  user_id SERIAL,
  first_name character varying(64) NOT NULL,
  last_name character varying(64) NOT NULL,
  email character varying(255) NOT NULL
)
WITH (
  OIDS=FALSE
);

CREATE TABLE user_role
(
  role_id SERIAL,
  role_name character varying(255) NOT NULL,
  description character varying(255) NOT NULL,
  created_on timestamp(6) with time zone NOT NULL,
  created_by character varying(64) NOT NULL,
)
WITH (
  OIDS=FALSE
);

最佳答案

数据库引擎通常不会自行拆分语句。使用 SQL Management Studio、MySQL Workbench 等 SQL 编辑器时,您可能会有不同的印象。他们拆分您的脚本并将单独的 SQL 语句发送到数据库引擎,例如使用 JDBC。它是自动发生的,因此您可能认为数据库会这样做。

这将因 splitStatements = true 而失败:

<changeSet id="it fails" author="DBA presents">
  <sql splitStatements="true">
    create procedure some_proc (out title int)
    begin
      select count(1) into title from titles
      where emp_no = 123;
    end
  </sql>
</changeSet>

Liquibase 会在遇到分号时尝试拆分语句,这显然是一个错误,因为分号是更大语句(创建过程)的一部分。 Change splitStatement to false to allow semicolons in Liquibase SQL tag .

另一方面,在大多数情况下将 splitStatements 设置为 true 是很有用的。例如,当您想在单个 SQL 标记中提供多个语句时。使用 splitStatement=false,它将失败:

<changeSet id="it works" author="DBA presents">
        <sql splitStatements="false">
            update titles
            set title = 'abc'
            where emp_no = 123;

            update titles
            set title = 'abc'
            where emp_no = 234;
        </sql>
    </changeSet>

您的 PostgreSQL 示例

我的计算机上没有安装 Postgres,但由于 splitStatements=false,相同的脚本(在明显的语法更改之后)在 MySQL 中失败。 这绝对是数据库引擎之间的众多差异之一 - 显然 Postgres 本身将脚本拆分为语句。也许对于 Postgres splitStatement 属性没有意义,但对于其他引擎它确实像 MySQL。 Liquibase 支持各种引擎,因此并非所有选项都是必需的。

总结

通常,使用默认值 (splitStatements=true),您不必为每个语句创建单独的 SQL 标记。但有时您可能想通过设置 splitStatements=false 明确地告诉 Liquibase “这是一个单独的语句,不要尝试拆分它”。例如在创建存储过程时。

关于liquibase - liquibase "splitStatements"有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72989797/

相关文章:

java - 我们可以使用 Liquibase 监控数据库表中新添加的数据吗?

oracle12c - liquibase 3.5.x 在执行变更集时是否有默认超时?

liquibase - 如何仅执行 liquibase 中未读的特定变更集?

java - 模块化数据库初始化

liquibase - 从Oracle数据库导出Liquibase数据-generateChangeLog

java - Liquibase 未针对 Spring Boot/MySQL 应用程序执行

csv - Liquibase CSV loadData 失败,带引号的字符串包含逗号

liquibase - SQL 格式变更集的失败消息