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

标签 sql oracle oracle11g

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

BEFORE: 
388    English
389    French

AFTER:
389    English
388    French


什么不起作用:

BEGIN
   UPDATE SPOKEN_LANGUAGES
      SET id = 388
    WHERE id = 389;

   UPDATE SPOKEN_LANGUAGES
      SET id = 389
    WHERE id = 388;
END;


hack /解决方案“有效”

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;


表定义:

CREATE TABLE SPOKEN_LANGUAGES
(
  ID             NUMBER(10)                     NOT NULL,
  LANGUAGE_NAME  VARCHAR2(40 BYTE)              NOT NULL
)


PK /唯一索引:

   CREATE UNIQUE INDEX SL_PK ON SPOKEN_LANGUAGES    (ID)

最佳答案

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

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

关于sql - 交换两个主键值并规避ORA-00001的更好方法:违反唯一约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42006959/

相关文章:

SQL:GROUP BY 之后的 SUM

php - MySQL 多表更新语句

java - 获取 Java.sql.SQLException : ORA-01461: can bind a LONG value only for insert into a LONG column. 。插入数据时

java - Oracle 表被 Hibernate 丢弃;从回收站闪回到DB。出现错误 "SQL Error: 942, SQLState: 42000"

sql - 更新语句 : re-evaluate subquery after each SET

sql - 在多列中查找最大值

mysql - 最大和计数查询

mysql - 尝试恢复大于 10 GB 的 sql 转储文件

sql - 分组中最小值的 Oracle 分析函数

c# - 使用简单数据的连接池的问题