简体   繁体   中英

Changing primary key to new id column

I have an existing database with the primary key being the combination between a name and a timestamp. There is no ID column yet. I would like to add that ID column and change the primary key to ID and timestamp. Rows with the same name should get the same ID.

Since I'm only an intern I would prefer to avoid droping and recreating the table I'm working on since I currently don't have the privileges to do that.

What would be the easiest way to do that?

You can drop a primary key and create a new one according to the docs .

ALTER TABLE table_name
DROP CONSTRAINT primary_key;

Then you'll have to add the ID column and set it as the new Primary Key:

ALTER TABLE table_name
ADD (ID NUMBER);

ALTER TABLE table_name
ADD CONSTRAINT table_pk PRIMARY KEY (ID, Time_Stamp);

Edit: If you would like the ID's to auto increment you will need to create a sequence and a trigger:

CREATE SEQUENCE S
START WITH 1
INCREMENT BY 1;


CREATE OR REPLACE TRIGGER T
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
  if(:new.ID is null) then
  SELECT S.nextval
  INTO :new.ID
  FROM dual;
  end if;
END;
/

ALTER TRIGGER "T" ENABLE;

For completing your entire task you need to

  1. Create ID column
  2. Fill data in ID column according to your requirement
  3. Drop PK
  4. Create PK with ID and Timestamp column

Below is the entire script for the same:

--CREATING THE TABLE
CREATE TABLE TEST (NAME VARCHAR2(200), TIME_STAMP TIMESTAMP,
CONSTRAINT TEST_PK PRIMARY KEY (NAME, TIME_STAMP)
);

-- INSERTING SAMPLE DATA ACCORDING TO YOUR REQUIREMENT -- DUPLICATE NAMES
INSERT INTO TEST 
SELECT * FROM 
(
SELECT 'NAME1', SYSTIMESTAMP - INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'NAME2', SYSTIMESTAMP - INTERVAL '2' HOUR FROM DUAL UNION ALL
SELECT 'NAME3', SYSTIMESTAMP - INTERVAL '3' HOUR FROM DUAL UNION ALL
SELECT 'NAME4', SYSTIMESTAMP - INTERVAL '4' HOUR FROM DUAL UNION ALL
SELECT 'NAME4', SYSTIMESTAMP - INTERVAL '5' HOUR FROM DUAL UNION ALL
SELECT 'NAME4', SYSTIMESTAMP - INTERVAL '6' HOUR FROM DUAL
);

-- ADDING NEW COLUMN ID
ALTER TABLE TEST ADD ID NUMBER;

-- FILLING THE DATA INTO ID COLUMN
MERGE INTO TEST T
USING (SELECT TIN.NAME, TIN.TIME_STAMP, RANK() OVER (ORDER BY TIN.NAME) RN
FROM TEST TIN) TIN
ON (T.NAME = TIN.NAME AND T.TIME_STAMP = TIN.TIME_STAMP)
WHEN MATCHED THEN 
UPDATE SET T.ID = TIN.RN;

-- DROPPING TH EXSITING PK
ALTER TABLE TEST DROP CONSTRAINT TEST_PK;

-- ADDING THE PK WITH ID AND TIME_STAMP
ALTER TABLE TEST ADD CONSTRAINT TEST_PK PRIMARY KEY (ID, TIME_STAMP);

db<>fiddle demo

Cheers!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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