更新表SET字段

时间:2010-06-09 21:49:14

标签: sql-server-2005

这是我的第一篇帖子!忍受我。 我有一个更新声明,我试图了解SQL Server如何处理它。

UPDATE a
    SET a.vField3 = b.vField3
FROM tableName a
    INNER JOIN tableName b on a.vField1 = b.vField1
        AND b.nField2 = a.nField2 – 1

这是我最简单的查询。

vField1 is a Varchar
nField2 is an int (autonumber)
vField3 is a Varchar

我已经离开了WHERE子句,所以理解有逻辑,否则会使这成为一个nessessity。

假设vField1是客户编号,而该客户有3条记录 nField2中的值连续为1,2和3。 vField3是状态

当更新到达a.nField2 = 1时,没有a.nField2 -1,所以它继续 当更新到达a.nField2 = 2时,b.nField2 = 1 当更新到达a.nField2 = 3时,b.nField2 = 2

因此,当更新位于a.nField2 = 2时,别名b反映了先前行上的内容(b.nField2 = 1) 它设置了a.vField3 = b.vField3

的Varchar值

当更新位于a.nField2 = 3时,别名b反映了先前行上的内容(b.nField2 = 2) 它(应该)设置a.vField3 = b.vField3

的Varchar值

当进程完成时 - 三条记录中的第二条按预期显示 - 第二条记录的vField3中的值反映了第一条记录中vField3中的值

但是,第三条记录的vField3没有反映第二条记录中vField3中的值。

我认为这表明SQL Server可能正在生成某种事务,然后进行更新。

问题:如何在每次交易后让数据库更新,以便我可以引用每笔交易产生的值?

谢谢。 davlyo

2 个答案:

答案 0 :(得分:3)

首先,最重要的是,你错误地认为交易会在逻辑上实现某种定义的循环,因为你的记录是“连续”保存的。实际上,您的数据库中记录的顺序是未定义根本根据这种有序的方式考虑您的表存储是没有意义的。事实上,你应该试着完全摆脱它,否则它会引导你陷入各种各样的陷阱和坏习惯。请尝试逻辑地考虑以set(在数学意义上)操作而不是光标遍历执行的语句。

在大多数关系数据库中,没有ORDER BY子句的SELECT将检索记录的顺序当然是按插入顺序排列的,但这是一个实现问题,实际上永远不应该依赖于任何逻辑(如果您关心订单,请始终使用ORDER BY子句检索数据)。为了强调,根据ANSI SQL,没有ORDER BY子句就没有定义从数据库中检索记录的顺序 - 从技术上讲,它甚至不必在顺序执行相同的SELECT语句时保持一致。

因此,为了使关系数据库上的UPDATE操作产生一致的结果,任何查询都必须作为单个事务运行。该事务抓取它将更新的记录的快照,以一致的原子方式更新它们,然后将结果应用回数据。没有逻辑概念的SQL循环记录或其他任何东西。

答案 1 :(得分:1)

整个更新查询是一个操作 - 如果这是事务中的唯一事务,则是一个事务。因此,查询不会看到它自己的结果。查询在没有任何隐含顺序的情况下运行 - 几乎就像一次性发生一样。

另外请记住,这是一个自联接,所以最初的第二个/第三个记录不会在查询运行之后。一条记录将“丢失” - 原始的第三条记录,而值为1的记录重复。

E.g。首先是Customer,aField2,aField3

mdma    1     A
mdma    2     B
mdma    3     C

运行更新后,值将为

mdma    1    A
mdma    2    A
mdma    3    B

这是你所看到/期待的吗?