sql - 使用liquibase修改SQL-Server中的数据类型和数据

标签 sql sql-server spring-boot liquibase

我在 SQL Server 中有一个使用 liquibase 创建的表 temp

temp 的 liquibase 变更日志是

databaseChangeLog:
  - changeSet:
      author: Author_name
      id: create_temp_table
      createTable:
        tableName: temp
        columns:
          - column:
              name: id
              type: BIGINT
              constraints:
                primaryKey: 'true'
          - column:
              name: type
              type: VARCHAR(255)
          - column:
              name: reference
              type: VARCHAR(255)
          - column:
              name: rate
              type: VARCHAR(255)

我想将rate列从字符串修改为十进制。所以我在下面创建一个新的变更日志文件

databaseChangeLog:
  - changeSet:
      id: modify_column_temp_table
      author: Author_name
      changes:
        - modifyDataType:
            columnName: rate
            newDataType: DECIMAL(18,4)
            tableName: temp

现在,temp 表中已经存在一些现有数据,其中 rate 列为字符串。当 modify_column_temp_table 更改日志运行时,我知道 SQl Server 将抛出一个强制转换错误,指出字符串不能转换为十进制。

如何在同一变更日志中执行脚本或命令,该脚本或命令实际上会修改列的数据以及数据类型,以便将 rate 中的现有数据修改为新的数据类型?

最佳答案

这是一种常见的情况,并且有一个众所周知的决定。您应该创建几个逐步修改数据库的变更集。

  1. 使用新名称重命名原始列:
    <changeSet id="rename column" author="authorName" failOnError="true">
        <preConditions>
            <columnExists tableName="temp" columnName="rate"/>
            <!-- if you also wanna check the column type use <sqlCheck> with database-dependent syntax -->
        </preConditions>
        <renameColumn oldColumnName="rate" newColumnName="rate_number" tableName="temp"/>
    </changeSet>
  • 使用新数据类型创建列:
  •     <changeSet id="create new column" author="authorName" failOnError="true">
            <preConditions>
                <columnExists tableName="temp" columnName="rate_number"/>
                <not>
                    <columnExists tableName="temp" columnName="rate"/>
                </not>
            </preConditions>
            <addColumn tableName="temp">
                <column name="rate" type="NUMBER(38,0)"/>
            </addColumn>
        </changeSet>
    
  • 使用数据库特定的功能移动和转换数据:
  •     <changeSet id="copy data" author="authorName" failOnError="true">
            <preConditions>
                <columnExists tableName="rate" columnName="rate"/>
                <columnExists tableName="rate" columnName="rate_number"/>
            </preConditions>
            <sql>
                <!-- your database-specific sql code for copy and transform data -->
            </sql>
        </changeSet>
    

    如果您想在工作流程中使用回滚功能,您可以添加 语句。另外,您可以添加第四个更改集,该更改集会删除名为“rate_number”的列,但在删除此列之前测试应用程序可能会很有用。

    这里的任何DDL语句都需要不同的变更集,因为DDL语句的执行会提交当前事务并且无法回滚。所以你应该手动处理更新过程中liquibase掉线的情况。

    关于sql - 使用liquibase修改SQL-Server中的数据类型和数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63119200/

    相关文章:

    sql-server - SSRS 中的自定义定时订阅计划

    SQL Server 更新时间戳列

    excel - 在 XSSFWorkbook 中保存时日期字段未以正确格式保存

    java - 将 java.util.Date 转换为 json 格式

    php - 左连接 ON 条件和 Doctrine 中的其他条件语法

    mysql - 如果我们可以为唯一索引设置空值,那么查询的持续时间是否会更短?

    php - 内连接包含 3 个表的计数

    java - 使用 Spring Boot 和 H2 运行测试时出现异常 "Failed to load ApplicationContext"

    mysql - 从对话中选择最新消息

    sql - 在一天/月/周结束时获取值的总和