带有autoIncrement列的Liquibase createTable为Oracle 11g和12c生成不同的SQL

时间:2017-07-11 15:11:01

标签: oracle11g java-8 liquibase oracle12c

这是我的第一个问题所以请保持温和; - )。

我们有一个liquibase项目,其中包含以下changeSet:

<changeSet author="Me" id="db.changelog-master-1">
  <preConditions onFail="MARK_RAN">
    <not>
      <tableExists tableName="table_x" />
    </not>
  </preConditions>
  <createTable remarks="Groep" tableName="table_x">
    <column autoIncrement="true" name="id" type="${serial}">
      <constraints primaryKey="true" primaryKeyName="table_x_pk" />
    </column>
    <column name="indsync" type="varchar(5)">
      <constraints nullable="false" />
    </column>
    <column name="code" type="varchar(10)" />
    <column defaultValue="2" name="code_n" type="char(1)">
      <constraints nullable="false" />
    </column>
    <column name="description" type="varchar(80)" />
    <column defaultValue="2" name="description_n" type="char(1)">
      <constraints nullable="false" />
    </column>
  </createTable>

启动使用Oracle 11g的应用程序时,创建的表格如下所示:

  CREATE TABLE "SOMETHING"."TABLE_X" 
   (  "ID" NUMBER(*,0) NOT NULL ENABLE, 
   "INDSYNC" VARCHAR2(5 CHAR) NOT NULL ENABLE, 
   "CODE" VARCHAR2(10 CHAR), 
   "CODE_N" CHAR(1 CHAR) DEFAULT '2' NOT NULL ENABLE, 
   "DESCRIPTION" VARCHAR2(80 CHAR), 
   "DESCRIPTION_N" CHAR(1 CHAR) DEFAULT '2' NOT NULL ENABLE, 
    CONSTRAINT "TABLE_X_PK" PRIMARY KEY ("ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT)
  TABLESPACE "SOMETHING"  ENABLE
   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT)
  TABLESPACE "SOMETHING" ;

   COMMENT ON TABLE "SOMETHING"."TABLE_X"  IS 'Groep';

  CREATE OR REPLACE TRIGGER "SOMETHING"."TABLE_X_BI" before insert on table_x for each row  WHEN (new.id is null) begin select table_x_seq.nextval into :new.id from dual; end;
/
ALTER TRIGGER "SOMETHING"."TABLE_X_BI" ENABLE;

这按预期工作,sequence.nextval插入id列。 但是在启动使用Oracle 12c的应用程序时,创建的表格如下所示:

 CREATE TABLE "SOMETHING"."TABLE_X" 
   (  "ID" NUMBER(*,0) GENERATED BY DEFAULT AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER  NOCYCLE  NOT NULL ENABLE, 
   "INDSYNC" VARCHAR2(5 CHAR) NOT NULL ENABLE, 
   "CODE" VARCHAR2(10 CHAR), 
   "CODE_N" CHAR(1 CHAR) DEFAULT '2' NOT NULL ENABLE, 
   "DESCRIPTION" VARCHAR2(80 CHAR), 
   "DESCRIPTION_N" CHAR(1 CHAR) DEFAULT '2' NOT NULL ENABLE, 
    CONSTRAINT "TABLE_X_PK" PRIMARY KEY ("ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SOMETHING"  ENABLE
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SOMETHING" ;

   COMMENT ON TABLE "SOMETHING"."TABLE_X"  IS 'Groep';

  CREATE OR REPLACE EDITIONABLE TRIGGER "SOMETHING"."TABLE_X_BI" before insert on table_x for each row  WHEN (new.id is null) begin select table_x_seq.nextval into :new.id from dual; end;
/
ALTER TRIGGER "SOMETHING"."TABLE_X_BI" ENABLE;

12c创建的表的问题是序列的值从不用于列ID,因为它不会为空,因为“生成的默认值为IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 1个加速1个加速20 NOORDER NOCYCLE NOT NULL ENABLE“

id字段在每次插入时都会递增,但不使用序列。

我的问题是,经过一段时间和一些changeSet之后,我们擦除table_x的内容,删除序列并重新创建它以重新开始。 这完全可以使用oracle 11g,但不能在12c中使用。 12c中的id字段继续递增并且不会被重置,这会在启动应用程序时引起问题。

我需要做什么,在oracle 12c上拥有与11g相同的createTable定义?

Grtz,

莱克斯

编辑1:我们使用的liquibase版本是3.4.2(maven dependency org.liquibase:liquibase-core)

编辑2:根据@SteveDonie的要求,$ {serial}的定义如下:

<property name="serial" value="numeric(*,0)" dbms="oracle"/>
<property name="serial" value="serial" dbms="postgresql"/>
<property name="serial" value="int(10) UNSIGNED" dbms="mysql"/>

对于Oracle,只有一个定义用于两个版本。

1 个答案:

答案 0 :(得分:1)

您是否尝试过使用defaultValueComputed标签作为ID字段?

<changeSet id="table_x_seq_create" author="takacsl">
    <createSequence cacheSize="2000" cycle="false" incrementBy="1" sequenceName="SEQ_TABLE_X" startValue="1"/>
</changeSet>
<changeSet id="table_x_create" author="takacsl">
  <createTable remarks="Groep" tableName="table_x">
    <column name="id" type="integer" defaultValueComputed="nextval('SEQ_TABLE_X')>
      <constraints primaryKey="true"  />
    </column>
    <column name="indsync" type="varchar(5)">
      <constraints nullable="false" />
    </column>
    <column name="code" type="varchar(10)" />
    <column defaultValue="2" name="code_n" type="char(1)">
      <constraints nullable="false" />
    </column>
    <column name="description" type="varchar(80)" />
    <column defaultValue="2" name="description_n" type="char(1)">
      <constraints nullable="false" />
    </column>
  </createTable>
</changeSet>

另一个-更复杂-变通方法是使用自定义生成器类覆盖sql代码生成。