Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
更新多行时MySQL重复条目_Mysql - Fatal编程技术网

更新多行时MySQL重复条目

更新多行时MySQL重复条目,mysql,Mysql,我有一个项目表,其中每个项目都有一个itemOrder。itemOrder是主键的一部分。我正试图写一个更新,将重新排序的项目 例如,如果我想将项目3移动为项目1,则项目3的新itemOrder将为1,项目1将为2,项目2将为3。此查询在SQL Server中工作,因为UPDATE语句是事务性的 更新tbl_项目 当itemOrder=3时,设置itemOrder=CASE,然后设置1 ELSE itemOrder+1 END 其中项目顺序介于1和3之间; 在MySQL中,一次更新一行,如果在任

我有一个项目表,其中每个项目都有一个itemOrder。itemOrder是主键的一部分。我正试图写一个更新,将重新排序的项目

例如,如果我想将项目3移动为项目1,则项目3的新itemOrder将为1,项目1将为2,项目2将为3。此查询在SQL Server中工作,因为UPDATE语句是事务性的

更新tbl_项目 当itemOrder=3时,设置itemOrder=CASE,然后设置1 ELSE itemOrder+1 END 其中项目顺序介于1和3之间; 在MySQL中,一次更新一行,如果在任何一点上存在重复的PK,就会抛出一个错误。一定有办法解决这个问题,对吧?我试着回答,但没有用。我还尝试将该语句包装到启动事务中/犯罪但它也有同样的错误


我猜MySQL解决方案与ON-DUPLICATE KEY有关,但我还不能完全理解它,也无法在我的场景中使用它。

默认情况下,MySQL以自动提交模式运行;您需要手动创建事务:

begin;
update ...;
update ...;
commit;
或者,您可以在更新之前关闭自动提交

set autocommit = 0;
并可选择在更新后再次打开:

set autocommit = 1;

这是一个非常粗糙的工作,如果有人有正确的答案,我很乐意将其标记为正确答案,但在此之前,我的解决方案如下

分隔符// 创建过程'sp_move_item` fromOrder INT, toOrder INT 开始 -@shift是每个其他物品需要移动的量,以腾出空间 -对于目标项:-1用于上移,1用于下移 选择@low:=当fromOrder>toOrder,然后从Order END选择toOrder ELSE时的大小写, @高:=当fromOrder到订单然后是1 ELSE-1 END时的情况; 启动交易; -获取列表底部项目的itemOrder并添加1。 -将项目的itemOrder设置为值≥ @偏移保证不重叠 -使用表中未受影响的项。 选择@offset:=MAXitemOrder+1 来自tbl_项目; -将所有受影响项目的itemOrder设置为在 -表的顺序与它们已有的顺序相同。保证没有重叠 -彼此之间。 更新tbl_项目 SET itemOrder=itemOrder+@offset 其中,itemOrder介于@low和@high之间; -按所需顺序将受影响的项目移回原位。 更新tbl_项目 SET itemOrder=大小写 当itemOrder=fromOrder+@offset时,则为toOrder ELSE itemOrder+@shift-@offset END 其中itemOrder>=@偏移量; 犯罪 结束// 定界符; 此方法的性能非常差,因为它需要重新排序索引2*@高-低时间。表中的行越多,性能受到的影响就越大,即使@high-@low=1是一个简单的交换,就像我目前的情况一样

如果表上只有一个索引,并且您只进行了一个位置交换,那么一种更快的方法是复制移动到变量中的行的每个列值,用另一个受影响的行覆盖该行的值,然后将该行更新为变量的值,就像在数组中交换值一样


注意:这段代码假设itemOrders是连续的,没有丢失值,尽管我认为即使不是这样,它仍然可以工作。不过,我还没有想清楚,所以您的里程数可能会有所不同。

这对我不起作用。我试着用这两种方法开始;并开始交易;,在事务内部和外部设置自动提交。虽然我只使用了一条UPDATE语句来完成所有的行,但我认为这不会有什么不同。