将主键更改为新的 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;
要完成整个任务,您需要
- 创建 ID 列
- 根据您的要求在 ID 列中填写数据
- 掉落PK
- 使用 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);
干杯!!
我有一个现有的数据库,其主键是名称和时间戳的组合。还没有 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;
要完成整个任务,您需要
- 创建 ID 列
- 根据您的要求在 ID 列中填写数据
- 掉落PK
- 使用 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);
干杯!!