我有一个包含唯一索引的表;比如说
A B
1 1
1 2
1 3
1 4
我想要更新B列,因为如果sql尝试将第一列更新为2,那么sql会逐一更新它们,因为ex i get ::
A B
1 2
1 2
1 3
1 4
结果我会在第1行和第2行得到两个重复的值,当然还有错误信息。
我应该像那样更新表格:
A B
1 2
1 1
1 3
1 4
那么在这种情况下我应该遵循的行动方案是什么?
问候。
也许我应该更新问题: 如果我想完全改变b列怎么办?如:
A B
1 4
1 2
1 3
1 1
答案 0 :(得分:3)
试试这个
UPDATE tbl
SET B = 3 - B
WHERE A = 1 AND B IN (1, 2)
或者,通常,你可以使用类似的东西:
UPDATE tbl
SET B = CASE B
WHEN 1 THEN 2
WHEN 2 THEN 1
END
WHERE A = 1 AND B IN (1, 2)
另一种方式:
添加列C
通过循环填充C列,使用新值
从C:更新字段B:
UPDATE tbl
SET B = C
答案 1 :(得分:0)
如果我理解的话,你有一个由两列组成的主键,并且你想要将两个第一行交换为PK。
如果您没有引用此主键的外键,只需将其中一个键更改为临时未使用的值:
A B
1 10000
1 2
然后改变第二行:
A B
1 10000
1 1
最后,改变第一个:
A B
1 2
1 1
如果您有依赖于此主键的对象,则必须将其他列的副本(例如11的其他列)复制到“临时行”,复制第二列的数据(1 2) )到第一个(1 1)并最终将“临时行”复制到第二个(1 2)
这一切都取决于你正在尝试做的事情和方式。它是一个存储过程,是一个查询...你应该显示更多的上下文。
您可以将此技术应用于无限数量的行。您还可以创建具有键等价的临时表,并从临时表更新表。因此,它将在原子操作中完成,并且不会违反PK。
create table T
(A int, B int, C char(5),
primary key (A,B))
insert into T values(1,1,'first')
insert into T values(1,2,'secon')
insert into T values(1,3,'third')
create table #KeyChanges
(A int, B int, newA int, newB int)
insert into #KeyChanges values(1,1,1,3)
insert into #KeyChanges values(1,2,1,1)
insert into #KeyChanges values(1,3,1,2)
update T set T.A = KC.newA, T.B = KC.newB
from T
left join #KeyChanges as KC on T.A = KC.A and T.B = KC.B
答案 2 :(得分:0)
解决方案是在单个语句中进行交换:
UPDATE YOUR_TABLE
SET B = (CASE B WHEN 1 THEN 2 ELSE 1 END)
WHERE A = 1 AND B IN (1, 2)
---编辑---
要一次更新多行,您可以从临时表中执行JOIN更新:
CREATE TABLE #ROWS_TO_UPDATE (
A int,
B int,
NEW_B int,
PRIMARY KEY (A, B)
);
INSERT INTO #ROWS_TO_UPDATE (A, B, NEW_B) VALUES (1, 1, 4);
INSERT INTO #ROWS_TO_UPDATE (A, B, NEW_B) VALUES (1, 2, 3);
INSERT INTO #ROWS_TO_UPDATE (A, B, NEW_B) VALUES (1, 3, 2);
INSERT INTO #ROWS_TO_UPDATE (A, B, NEW_B) VALUES (1, 4, 1);
UPDATE YOUR_TABLE
SET B = NEW_B
FROM
YOUR_TABLE JOIN #ROWS_TO_UPDATE
ON YOUR_TABLE.A = #ROWS_TO_UPDATE.A AND YOUR_TABLE.B = #ROWS_TO_UPDATE.B;
DROP TABLE #ROWS_TO_UPDATE;
以上代码转换以下数据......
A B
1 1
1 2
1 3
1 4
......对此:
A B
1 4
1 2
1 3
1 1