【问题标题】:DB2 add auto increment column to an existing tableDB2 将自动增量列添加到现有表
【发布时间】:2016-05-29 04:37:48
【问题描述】:

我的 DB2 数据库中有一个具有以下模式的表。

CREATE TABLE IDN_OAUTH_CONSUMER_APPS (
        CONSUMER_KEY VARCHAR (255) NOT NULL,
        CONSUMER_SECRET VARCHAR (512),
        USERNAME VARCHAR (255),
        TENANT_ID INTEGER DEFAULT 0,
        APP_NAME VARCHAR (255),
        OAUTH_VERSION VARCHAR (128),
        CALLBACK_URL VARCHAR (1024),
        GRANT_TYPES VARCHAR (1024)
/

我需要添加一个类型为整数而不是空自动增量的新列 ID,并将其作为主键。如何在不删除表的情况下做到这一点?

【问题讨论】:

  • 表格是否已经值了?到目前为止,您尝试了什么,有什么错误,有什么要分享的吗?
  • 是的,表有值,我尝试了“ALTER TABLE IDN_OAUTH_CONSUMER_APPS ADD COLUMN ID INTEGER NOT NULL”,想在添加列后添加一个序列,但是如果不添加默认值,我就无法添加非空价值
  • alter table IDN_OAUTH_CONSUMER_APPS add ID INTEGER not null default 0; alter table IDN_OAUTH_CONSUMER_APPS alter column ID drop default; alter table IDN_OAUTH_CONSUMER_APPS alter column ID set GENERATED ALWAYS AS IDENTITY (start with 1); update IDN_OAUTH_CONSUMER_APPS set ID = DEFAULT; alter table IDN_OAUTH_CONSUMER_APPS add primary key (ID); call sysproc.admin_cmd('reorg table IDN_OAUTH_CONSUMER_APPS');

标签: sql db2 auto-increment dbmigrate


【解决方案1】:

使用主键字段创建一个新表。插入旧表中的记录。删除旧表,如果可以,重命名新表。如果您无法重命名它,请重新创建它并从现在有记录的那个中填充。

【讨论】:

  • 我想在不删除现有表的情况下这样做。
【解决方案2】:

使用多步骤方法:

  1. 添加列ALTER TABLE ADD...,仅具有整数数据类型,并且可以为空
  2. 更新表以设置该列的预期标识值
  3. 更改表以添加自动生成
  4. 更改表以在该列上添加主键

您需要执行多个步骤,因为需要手动添加标识值。 Syntax and examples for ALTER TABLE can be found here.

【讨论】:

    【解决方案3】:

    我可以使用以下一组查询成功地做到这一点。

    ALTER TABLE IDN_OAUTH_CONSUMER_APPS ADD COLUMN ID INTEGER NOT NULL DEFAULT 0
    
    CREATE SEQUENCE IDN_OAUTH_CONSUMER_APPS_SEQUENCE START WITH 1 INCREMENT BY 1 NOCACHE
    
    CREATE TRIGGER IDN_OAUTH_CONSUMER_APPS_TRIGGER NO CASCADE BEFORE INSERT ON IDN_OAUTH_CONSUMER_APPS REFERENCING NEW AS NEW FOR EACH ROW MODE DB2SQL BEGIN ATOMIC SET (NEW.ID) = (NEXTVAL FOR IDN_OAUTH_CONSUMER_APPS_SEQUENCE); END
    
    REORG TABLE IDN_OAUTH_CONSUMER_APPS
    
    UPDATE IDN_OAUTH_CONSUMER_APPS SET ID = IDN_OAUTH_CONSUMER_APPS_SEQUENCE.NEXTVAL
    

    然后使用alter table添加主键。

    【讨论】:

      【解决方案4】:

      有一种简单的方法可以做到这一点。只需运行上面的修改:

      ALTER TABLE idn_oauth_consumer_apps ADD COLUMN id INTEGER NOT NULL DEFAULT 0;
      ALTER TABLE idn_oauth_consumer_apps ALTER COLUMN id SET GENERATED ALWAYS AS IDENTITY;
      

      即使在大桌子上也简单快速。经过测试并在 DB2 for i V7R2 上工作。

      【讨论】:

      • 这对我在 DB2 10.5.7 上不起作用。我得到set generated always not compatible with the existing column
      【解决方案5】:

      Chamila Wijayarathna's answer 的基础上,我使用了以下内容:

      ALTER TABLE IDN_OAUTH_CONSUMER_APPS ADD COLUMN ID INTEGER NOT NULL DEFAULT 0
      
      CREATE SEQUENCE IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE START WITH 1 INCREMENT BY 1 NOCACHE
      
      CREATE TRIGGER IDN_OAUTH_CONSUMER_APPS_ID_TRIGGER NO CASCADE BEFORE INSERT ON
        IDN_OAUTH_CONSUMER_APPS REFERENCING NEW AS NEW
        FOR EACH ROW MODE DB2SQL BEGIN ATOMIC SET (NEW.ID) = (NEXTVAL FOR
        IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE); END
      
      REORG TABLE IDN_OAUTH_CONSUMER_APPS
      
      UPDATE IDN_OAUTH_CONSUMER_APPS SET ID = IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE.NEXTVAL
      
      ALTER TABLE IDN_OAUTH_CONSUMER_APPS ADD PRIMARY KEY (ID)
      
      REORG TABLE IDN_OAUTH_CONSUMER_APPS
      

      然后反转:

      REORG TABLE IDN_OAUTH_CONSUMER_APPS
      
      ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP PRIMARY KEY
      
      DROP TRIGGER IDN_OAUTH_CONSUMER_APPS_ID_TRIGGER
      
      DROP SEQUENCE IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE
      
      ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP COLUMN ID
      
      REORG TABLE IDN_OAUTH_CONSUMER_APPS
      

      【讨论】:

        【解决方案6】:

        在 DB2 for z/OS v12 上进行了尝试,它成功了:

        alter table TABLE_NAME add column id integer generated always as identity
        

        【讨论】:

          【解决方案7】:

          我建议使用这种方法。它不需要创建任何卫星对象 - 没有触发器、序列等......

          alter table test.test2  add column id integer not null default 0;
          alter table test.test2 alter column id drop default;
          alter table test.test2  alter column id set generated always as identity;
          call sysproc.admin_cmd ('reorg table test.test2');
          update  test.test2 set id = default;
          commit;
          

          如果使用“db2”cli,那么可以直接运行 reorg 命令,而无需“call sysproc.admin_cmd”包装器。

          【讨论】:

            猜你喜欢
            • 2019-01-18
            • 2013-01-23
            • 2015-06-05
            • 2016-07-23
            • 2011-06-19
            • 2022-10-05
            • 2019-04-21
            相关资源
            最近更新 更多