Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.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
Sql server 2005 更新表集字段_Sql Server 2005 - Fatal编程技术网

Sql server 2005 更新表集字段

Sql server 2005 更新表集字段,sql-server-2005,Sql Server 2005,这是我的第一篇帖子!请容忍我。 我有一个Update语句,我试图理解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

这是我的第一篇帖子!请容忍我。 我有一个Update语句,我试图理解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子句,因此理解了逻辑,否则这是必要的

假设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

整个更新查询是一个操作,如果事务中只有一个操作,那么它就是一个事务。因此,查询不会看到自己的结果。查询的操作没有任何隐含的顺序——几乎就像它同时发生一样

还请记住,这是一个自连接,因此在运行查询后,原本是第二条/第三条记录的内容将不会出现。一条记录将“丢失”-原始的第三条记录,值为1的记录将被复制

例如,您从、客户、aField2、aField3开始

mdma    1     A
mdma    2     B
mdma    3     C
运行更新后,这些值将

mdma    1    A
mdma    2    A
mdma    3    B

这就是您所看到/期望的吗?

首先,最重要的是,您错误地认为事务将在逻辑上实现某种定义的循环,因为您的记录是“连续”保存的。事实上,数据库中记录的顺序是未定义的,以这种顺序考虑表存储是毫无意义的。事实上,你应该试着彻底摆脱它,否则它会让你陷入各种陷阱和坏习惯。试着从逻辑上把执行语句看作是set(在数学意义上)操作,而不是游标遍历

的确,在大多数关系数据库中,SELECT在没有order by子句的情况下检索记录的顺序是插入顺序,但这是一个实现问题,事实上在任何逻辑中都不应该依赖它(如果关心顺序,请始终使用order by子句检索数据)。需要强调的是,根据ANSI SQL,如果没有order BY子句,从数据库检索记录的顺序是未定义的——从技术上讲,它甚至不必在同一SELECT语句的顺序执行上保持一致


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

“但是,第三条记录的vField3并没有反映第二条记录的vField3中的值。”您得到了什么?你指的是第二条记录的新值还是原始值?你从完全错误的角度来看这一点,并从游标而不是逻辑集操作的角度来思考-去读一本书,探索差异,但别担心,这是程序员第一次处理SQL时的一个非常常见的陷阱。我假设“tablename a”和“tablename b”实际上是两个不同的表,而不是一个有两个不同别名的表?(这将使它成为一个自连接,并且有点无意义)实际上,在大多数关系数据库中,如果未指定order BY,记录将按聚集索引的顺序检索,因此即使是实现细节也不支持FIFO记录顺序的概念,除非您没有聚集索引(坏主意)或总是以与聚集索引相同的顺序插入(只有当索引位于
标识列上时才正确)。@Aaronaught是的,您是正确的,尽管在我使用的大多数数据库中,对于大多数表,聚集索引是标识列,因此它实际上是插入顺序,但正如您指出的,这也是一个伪制品。