将主键更改为新的 id 列

Changing primary key to new id column

我有一个现有的数据库,其主键是名称和时间戳的组合。还没有 ID 列。我想添加该 ID 列并将主键更改为 ID 和时间戳。具有相同名称的行应获得相同的 ID。

因为我只是一名实习生,所以我宁愿避免删除和重新创建我正在工作的 table,因为我目前没有这样做的特权。

最简单的方法是什么?

您可以删除主键并根据 docs 创建一个新主键。

ALTER TABLE table_name
DROP CONSTRAINT primary_key;

然后您必须添加 ID 列并将其设置为新的主键:

ALTER TABLE table_name
ADD (ID NUMBER);

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

编辑:如果您希望 ID 自动递增,您将需要创建一个序列和一个触发器:

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;

要完成整个任务,您需要

  1. 创建 ID 列
  2. 根据您的要求在 ID 列中填写数据
  3. 掉落PK
  4. 使用 ID 和时间戳列创建 PK

下面是完整的脚本:

--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

干杯!!