问题
Goal:
Swap the primary keys of two records without encountering an ORA-00001: unique constraint violated. The solution that 'works' (further below) is just a silly hack. Is there a feature/technique to defer constraint enforcement until the transaction is committed?
As far as motivation - a legacy application that uses this data has a design flaw and relies on the IDs order and values - the request is to swap the PK values as follows:
BEFORE:
388 English
389 French
AFTER:
389 English
388 French
What doesn't Work:
BEGIN
UPDATE SPOKEN_LANGUAGES
SET id = 388
WHERE id = 389;
UPDATE SPOKEN_LANGUAGES
SET id = 389
WHERE id = 388;
END;
Hack/Solution that 'works'
DECLARE
V_MAGIC_NUMBER NUMBER := 9999999;
BEGIN
UPDATE SPOKEN_LANGUAGES
SET id = 388 + V_MAGIC_NUMBER
WHERE id = 389;
UPDATE SPOKEN_LANGUAGES
SET id = 389 + V_MAGIC_NUMBER
WHERE id = 388;
UPDATE SPOKEN_LANGUAGES
SET id = id - V_MAGIC_NUMBER
WHERE id = 389 + V_MAGIC_NUMBER;
UPDATE SPOKEN_LANGUAGES
SET id = id - V_MAGIC_NUMBER
WHERE id = 388 + V_MAGIC_NUMBER;
END;
Table Definition:
CREATE TABLE SPOKEN_LANGUAGES
(
ID NUMBER(10) NOT NULL,
LANGUAGE_NAME VARCHAR2(40 BYTE) NOT NULL
)
PK/UNIQUE INDEX:
CREATE UNIQUE INDEX SL_PK ON SPOKEN_LANGUAGES (ID)
回答1:
You need to do it in a single statement:
UPDATE SPOKEN_LANGUAGES
SET id = case when id = 388 then 389 else 388 end
WHERE id in (388,389);
来源:https://stackoverflow.com/questions/42006959/a-better-way-to-swap-two-primary-key-values-and-circumvent-a-ora-00001-unique-c