简体   繁体   English

Liquibase:在DB2中将列更改为自动递增列(标识)

[英]Liquibase: Change column to an autoincrement column (identity) in DB2

I'm trying to change a BIGINT Column to an autoincremented column in DB2 but I can't seem find how. 我正在尝试将BIGINT列更改为DB2中的自动递增的列,但似乎找不到方法。 I tried doing it like this: 我尝试这样做:

    <changeSet id="08.01" author="...">
        <addColumn tableName="table_name">
            <column name="id" type="bigint">
                <constraints nullable="true"/>
            </column>

            <column name="member_type" type="varchar(100)">
                <constraints nullable="true"/>
            </column>
        </addColumn>
    </changeSet>

    <changeSet id="08.02" author="...">
        <addAutoIncrement tableName="table_name"
                          columnDataType="bigint"
                          columnName="id"/>
    </changeSet>

and when it runs I get this error: 当它运行时,我得到这个错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]: Invocation of init method failed; nested exception is liquibase.exception.MigrationFailedException: Migration failed for change set classpath:db/changelog/08-separation.xml::08.01::author:
     Reason: liquibase.exception.DatabaseException: DB2 SQL Error: SQLCODE=-270, SQLSTATE=42997, SQLERRMC=72, DRIVER=4.13.127 [Failed SQL: ALTER TABLE SCHEMATEST.table_name ALTER COLUMN id SET GENERATED BY DEFAULT AS IDENTITY]
    at org.springframework.bean
...
...
...
Caused by: liquibase.exception.MigrationFailedException: Migration failed for change set classpath:db/changelog/08separation.xml::08.01::author:
     Reason: liquibase.exception.DatabaseException: DB2 SQL Error: SQLCODE=-270, SQLSTATE=42997, SQLERRMC=72, DRIVER=4.13.127 [Failed SQL: ALTER TABLE SCHEMATEST.table_name ALTER COLUMN id SET GENERATED BY DEFAULT AS IDENTITY]
...
...
...
Caused by: com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-270, SQLSTATE=42997, SQLERRMC=72, DRIVER=4.13.127

An identity column cannot be nullable, this is what the error message tells you : 身份列不能为空,这是错误消息告诉您的内容

A nullable column cannot be changed to become an identity column. 无法将可为空的列更改为标识列。

Change the column constraint to nullable="false" I guess. 我想将列约束更改为nullable="false"

I found an answer myself at this link and the explanation is this: 我自己在此链接上找到了答案,其解释是:

Every DB2 admin discovers sooner or later that DB2 can not add identity column to existing table easily. 每个DB2管理员迟早都会发现DB2无法轻松地将Identity列添加到现有表中。 Following statements fails due to syntax error: alter table public.clicks add column id integer generated always as identity But i have good news for everyone. 以下语句由于语法错误而失败:alter table public.clicks添加始终将ID整数列始终作为标识生成,但是我对每个人都有好消息。 It can be still done, but it requires more steps. 仍然可以完成,但是需要更多步骤。

  1. Add not null integer column You need to provide default value for it otherwise db2 will refuse it to make not null alter table public.clicks add column id integer not null default 0 添加非空整数列您需要为其提供默认值,否则db2将拒绝它使非零更改表成为公共。

  2. Drop default value from column I am not exactly sure why it is needed because some manuals on internet omits this step but i was not able to make it work without this on DB2 9.7.3 LUW alter table public.clicks alter column id drop default 从列中删除默认值我不确定是否需要它,因为互联网上的一些手册省略了此步骤,但是如果没有DB2 9.7.3 LUW alter table public.clicks,我将无法使它起作用。

  3. Now set column to always generated ( add the autoincrement ) alter table public.clicks alter column id set generated always as identity 现在将列设置为始终生成( 添加自动增量 )alter table public.clicks将始终生成的alter column id设置为身份

  4. Reorg table to make it writeable (I didn't do this and it still works) reorg table public.clicks 重组表使其可写(我没有这样做,它仍然有效)重组表public.clicks

  5. Now replace zeros with generated itentity values update public.clicks set id = default 现在将零替换为生成的实体值, 更新public.clicks set id = default

  6. And optionally make id column primary key for table alter table public.clicks add constraint pkey primary key(id) 并可选地将表更改表的id列主键设为public.clicks添加约束pkey主键(id)

And the liquibase code for it: 以及它的liquibase代码:

defaultSchemaNames comes from spring properties which I defined like this. defaultSchemaNames来自我定义的spring属性。 I don't know if there's a better way to get the schema but this one works also 我不知道是否有更好的方法来获取模式,但是这种方法也可以

# in application.properties I've set this
liquibase.parameters.defaultSchemaName=MY_SCHEMA_NAME

The liquibase.xml liquibase.xml

    <property name="defaultSchema" value="${defaultSchemaName}" /> 

    <changeSet id="08.01.00" author="alex@mail.com">
        <dropPrimaryKey tableName="members" constraintName="pk_members_relation"/>
    </changeSet>

    <changeSet id="08.01" author="alex@mail.com">
        <addColumn tableName="members">
            <column name="id" type="BIGINT" defaultValue="0">
                <constraints nullable="false"/>
            </column>

            <column name="member_type" type="varchar(100)">
                <constraints nullable="true"/>
            </column>
        </addColumn>
    </changeSet>

    <changeSet id="08.02" author="alex@mail.com">
        <dropDefaultValue tableName="members" columnName="id"/>
    </changeSet>

    <changeSet id="08.03" author="alex@mail.com">
        <addAutoIncrement tableName="members" columnName="id" columnDataType="bigint"/>
    </changeSet>

    <changeSet id="08.04" author="alex@mail.com">
        <sql>
            UPDATE ${defaultSchema}.members SET id = default
        </sql>
    </changeSet>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM