sql - 使用 liquibase 修改 SQL-Server 中的数据类型和数据
问题描述
我temp
在使用 liquibase 创建的 SQL 服务器中有一个表
表的 liquibase 更改日志temp
是
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
修改为新的数据类型?
解决方案
这是一种常见的情况,它有一个众所周知的决定。您应该创建几个逐步修改数据库的变更集。
- 用新名称重命名原始列:
<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>
如您所愿,如果您想在工作流程中使用回滚功能,可以添加 <rollback> 语句。此外,您可以添加第四个更改集以删除名称为“rate_number”的列,但在删除此列之前测试应用程序可能很有用。
此处的任何 DDL 语句都需要不同的变更集,因为执行 DDL 语句会提交当前事务并且不能回滚。所以你应该手动处理更新过程中 liquibase 掉线的情况。
推荐阅读
- docker - 无法连接到远程 Ubuntu 服务器上运行的 elasticsearch 或 kibana
- javascript - Javascript 画布 - 从加载的 4 波段 RGB 图像中删除 alpha 到 3 波段 JPEG 图像?
- javascript - Google Map-SDK:多边形不会出现在 Android 设备上
- android - 在 Ionic 4 应用程序中进行的 API 调用无法在 Android 设备上运行
- c++ - 构造模板化元组类型
- r - 如何有条件地从 r 中的观察中删除字符(例如“ed”、“s”词尾)
- php - PHP Domdocument 使用 saveXML 而不是 save
- python-3.x - 如何组合数据框
- c# - 当 sql 视图中有两条记录时,列表视图显示相同的记录两次
- python - system() 在 C 中调用的 Python 脚本无法将变量发送到文件