为什么oracle可以更新pk = pk + 1,但MySQL无法更新set pk = pk + 1

时间:2017-08-21 23:05:16

标签: mysql oracle primary-key

ORACLE:

 create table t7(c1 number primary key,c2 number);
 insert into t7 values (1,3);
 insert into t7 values (2,4);
 commit;
 update t7 set c1=c1+1;
 commit ;
 select * from t7;

MySQL的:

 create table t7(c1 int primary key,c2 int);
 insert into t7 values (1,3);
 insert into t7 values (2,4);
 select * from t7;
 update t7 set c1=c1+1;
 ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'

为什么MySQL会说

  

update set pk=pk+1 :Duplicate entry '2' for key 'PRIMARY'

ORACLE可以执行此操作update set pk=pk+1

2 个答案:

答案 0 :(得分:2)

似乎oracle要么更聪明地执行命令,要么只在将更新应用于所有行之后检查约束。无论如何,可以通过指定更新的顺序来修复mysql示例。

 create table t7(c1 int primary key,c2 int);
 insert into t7 values (1,3);
 insert into t7 values (2,4);
 select * from t7;
 update t7 set c1=c1+1 order by c1 desc;

参见 http://sqlfiddle.com/#!9/8611f4/1

尝试将第一行更新为(2,3)是一个重复键,因为(2,4)仍然具有旧值。此行为的解决方法是撤消订单并从最大的索引开始,更改(2,4) - > (3,4)然后(1,3) - > (2,3),并完全避免碰撞。

答案 1 :(得分:1)

在关系数据库中,更新主键存在概念上有限的含义(更不用说根本没有)。

Oracle实现了这一点,而MySQL并没有实现。你发现了它。

如果你真的想做你想做的事,解决办法就是插入新记录,然后删除之前的记录。

要在整个表上执行此操作,最好创建一个临时表。以下是它的外观:

create table t7_tmp(c1 int primary key,c2 int);
insert into t7_tmp (select c1+1,c2 from t7);
delete t7;
insert into t7 (select c1,c2 from t7_tmp);
drop table t7_tmp;