一尘不染

交换两个主键值并规避ORA-00001的更好方法:违反唯一约束?

sql

目标:
交换两个记录的主键,而不会遇到ORA-00001:违反了唯一约束。“可行”的解决方案(在下文中)只是一个破解。是否有一项功能/技术可以将约束执行推迟到提交事务之前?
motivation -使用此数据的遗留应用程序存在设计缺陷,并且依赖于ID顺序和值-请求是按以下方式交换PK值:

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)

阅读 171

收藏
2021-03-08

共1个答案

一尘不染

您需要在一个语句中执行此操作:

UPDATE SPOKEN_LANGUAGES
   SET id = case when id = 388 then 389 else 388 end
WHERE id in (388,389);
2021-03-08