Reputation: 1933
I have a table with following schema in my DB2 database.
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)
/
I need to add a new column ID of Type integer not null auto increment, and make it the primary key. How can I do that without deleting the table?
Upvotes: 3
Views: 23041
Reputation: 3256
I recommend using this approach. It does not require creating any satellite objects - no triggers, sequences, etc...
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;
If using "db2" cli then the reorg command may be run directly without the "call sysproc.admin_cmd" wrapper.
Upvotes: 4
Reputation: 7880
Tried this on DB2 for z/OS v12 and it worked:
alter table TABLE_NAME add column id integer generated always as identity
Upvotes: 0
Reputation: 608
Building on Chamila Wijayarathna's answer, I used the following:
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
Then to reverse:
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
Upvotes: 0
Reputation: 422
There is an easy way to do it. Just run the alters above:
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;
It is simple and fast even on big tables. Tested and working on DB2 for i V7R2.
Upvotes: 2
Reputation: 1933
I could do this successfully using following set of queries.
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
And then add primary key using alter table.
Upvotes: 3
Reputation: 17118
Use a multi-step approach:
ALTER TABLE ADD...
with just the integer data type and as nullableYou need to have multiple steps because the identity values need to be added manually. Syntax and examples for ALTER TABLE
can be found here.
Upvotes: 2
Reputation: 20804
Create a new table with the primary key field. Insert the records from the old table. Drop the old table and if you can, rename the new one. If you can't rename it, recreate it and populate from the one that now has the records.
Upvotes: 0