Bri*_*ian 2 sql oracle oracle11g
目标:
交换两个记录的主键而不会遇到ORA-00001:违反了唯一约束."有效"的解决方案(下面再说)只是一个愚蠢的黑客.在提交事务之前是否存在推迟约束强制执行的功能/技术?
至于动机 - 使用此数据的遗留应用程序存在设计缺陷并依赖于ID顺序和值 - 请求是交换PK值,如下所示:
BEFORE:
388 English
389 French
AFTER:
389 English
388 French
Run Code Online (Sandbox Code Playgroud)
什么不起作用:
BEGIN
UPDATE SPOKEN_LANGUAGES
SET id = 388
WHERE id = 389;
UPDATE SPOKEN_LANGUAGES
SET id = 389
WHERE id = 388;
END;
Run Code Online (Sandbox Code Playgroud)
黑客/解决方案"有效"
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;
Run Code Online (Sandbox Code Playgroud)
表定义:
CREATE TABLE SPOKEN_LANGUAGES
(
ID NUMBER(10) NOT NULL,
LANGUAGE_NAME VARCHAR2(40 BYTE) NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
PK/UNIQUE INDEX:
CREATE UNIQUE INDEX SL_PK ON SPOKEN_LANGUAGES (ID)
Run Code Online (Sandbox Code Playgroud)
您需要在一个语句中执行此操作:
UPDATE SPOKEN_LANGUAGES
SET id = case when id = 388 then 389 else 388 end
WHERE id in (388,389);
Run Code Online (Sandbox Code Playgroud)