我正在将一个主键列引入一个尚未拥有的列。在我添加了一个默认值为0的普通字段Id
(int)之后,我尝试使用以下更新语句为每条记录创建唯一值:
update t1
set t1.id = (select count(*) from mytable t2 where t2.id <> t1.id)
from mytable t1
我希望每行都能执行子查询,因为我引用了t1
。每次执行子查询时,计数应少一个,但不起作用。
结果是Id在每条记录中仍为0。我以前在其他DBMS上使用过这个成功的。我在这里使用SQL Server 2008。
如何为每条记录生成唯一值并更新Id字段?
答案 0 :(得分:4)
尝试解释为什么它不能按预期工作:
我希望每行都能执行子查询,因为我引用了t1。
执行它会影响所有行。但UPDATE
stetement是一个语句,它作为一个语句执行,影响整个表(如果你有一个WHERE
子句,则会影响它的一部分。)
每次执行子查询时,计数应少一个,但不起作用。
您期望通过每行对子查询进行一次评估来执行UPDATE
。但它是首先评估的一个语句 - 对于所有受影响的行 - 然后更改(更新)行。 (DBMS可能会这样做,但结果应该好像它正是这样做的。)
结果是Id在每条记录中仍为0。
当执行前所有行具有相同的0
值时,这是此语句的正确和预期行为。 COUNT(*)
为0
。
我以前在其他DBMS上使用过此功能。
我的“疯狂”猜测是你在MySQL中使用它。 (更正/更新:我的猜测错了,Update的这种语法对MySQL无效,显然查询在Firebird中“正确”工作)。 UPDATE
在DBMS中以标准方式不起作用。它可以 - 正如您所了解的那样 - 逐行,而不是全表。
我在这里使用SQL Server 2008。
此DBMS与UPDATE
一起正常运行。您可以编写一个具有所需结果的不同Update语句,或者更好地使用自动生成的IDENTITY
列,正如其他人所建议的那样。
答案 1 :(得分:1)
SQL正在使用ID不等于0的记录数更新每一行。由于所有行ID等于0,因此没有不等于0的行,因此没有任何更新。
试着在这里查看这个答案: