高手请略过~
以前知道这种写法,但没分析过原理!--想实现效果:同时修改ID与OK,OK字段依附于ID
DECLARE @T1 INT
DECLARE @T TABLE(ID INT,OK INT)
INSERT @T SELECT 1,1
UNION ALL SELECT 2,1
--第一种方法错误
UPDATE @T
SET ID=3,OK=ID
WHERE ID=2
--第二种方法正确
UPDATE @T
SET @T1=3, OK=@T1,ID=3
WHERE ID=2
SELECT * FROM @T个人观点:
推理:在更新时,由于先更新的字段ID被加上排它锁,导致OK不能正常更新

解决方案 »

  1.   

    以下是个人观点:不对请指正!
    今天由于用到事务,仔细分析了一下:
    SET XACT_ABORT与BEGIN TRANS的分析
    BEGIN TRANS:
    创建还原点,在执行过程中遇到问题,人工捕获,触发ROLLBACK TRANS。注:该ROLLBACK TRANS为手工添写。SET XACT_ABORT ON :
    需要手工创建还原点,执行时遇到问题,可自动执行ROLLBACK TRANS。注:该ROLLBACK TRANS为系统自动执行。不要把事务想得那么神秘,其实事务只有二个功能:
    第一:创建故障还原点。
    第二:锁定所占资源。
    二个事务可以并行处理的充要条件为二者互无依赖的资源。这里的资源特指锁资源。
    例1:
    create table table1(id int primary key)BEGIN TRY
    begin tran//创建还原点
    insert into table1 values (1)
    insert into table1 values (1)
    insert into table1 values (2)
    commit tran//提交数据
    END TRY
    BEGIN CATCH
      ROLLBACK//遇到问题,捕获后回滚到还原点
    END CATCH例2:
    create table table1(id int primary key)
    set xact_abort on
    begin tran//创建还原点
    insert into table1 values (1)
    insert into table1 values (1)
    insert into table1 values (2)
    commit tran//提交数据
    例3:
    create table table1(id int primary key)
    begin tran//创建还原点
    insert into table1 values (1)
    insert into table1 values (1)
    insert into table1 values (2)
    commit tran//提交数据
    毫无意义。起不到事务完整性保护的作用。当然,也没有人这么用,这里仅是说明begin tran的作用。
      

  2.   

    2.关于锁
    二个事务可以并行处理的充要条件为二者互无依赖的资源。这里的资源特指锁资源。 
    解释一下上述这句话:
    除了共享锁或不是硬性指定某种锁(HOLDLOCK)的作用域,其它的锁的生存期与事务共存亡。
    当一个事务在处理某字段时,如果另一个事务也要处理字段,因为它没有资源,故需要等待。故就
    会导致一个事务等待另一个事务处理完毕(即等待锁资源),会使某事务(即DBMS中的线程)出现SUSPENDED状态。
    如果对线程同步有了解的朋友肯定对此不陌生。如果一个线程等待另一个线程结束会用信号量或系统事件的方式进行等待资源,即WaitforsingleObject(Handle,INIFINATE),这样在一个事务中未释放锁的前提下,另一个事务(线程)就会无限期等待。
      

  3.   

    在sql2005下,两种结果是一样的...
      

  4.   

    set nocount on
    DECLARE @T1 INT
    DECLARE @T TABLE(ID INT,OK INT)
    INSERT @T SELECT 1,1
    UNION ALL SELECT 2,1
    SELECT * FROM @T
    --第一种方法错误
    UPDATE @T
    SET ID=3,OK=ID
    WHERE ID=2
    SELECT * FROM @T
    --第二种方法正确
    UPDATE @T
    SET @T1=3, OK=@T1,ID=3
    WHERE ID=2
    SELECT * FROM @T
    set nocount off/*
    ID          OK
    ----------- -----------
    1           1
    2           1ID          OK
    ----------- -----------
    1           1
    3           2ID          OK
    ----------- -----------
    1           1
    3           2
    */
      

  5.   

    JJ大哥,是2条独立的语句,应该单独运行。 
    否则第一个错误的语句处理完毕后对第二条的结果有影响!:)
    可能是我说的不清楚!
    测试环境MSSQL 2005--第一种方法错误
    DECLARE @T TABLE(ID INT,OK INT)
    INSERT @T SELECT 1,1
    UNION ALL SELECT 2,1
    UPDATE @T
    SET ID=3,OK=ID
    WHERE ID=2
    SELECT * FROM @T
    1 1
    3 2
    --第二种方法
    DECLARE @T1 INT
    DECLARE @T TABLE(ID INT,OK INT)
    INSERT @T SELECT 1,1
    UNION ALL SELECT 2,1
    UPDATE @T
    SET @T1=3, OK=@T1,ID=3
    WHERE ID=2
    SELECT * FROM @T
    1 1
    3 3
      

  6.   

     版主好强哦,学习学习.....______________________________________________________________________-
    企业邮局/域名注册/服务器等服务;
    网址 www.acedog.com 热电:0592-2526666-8803  QQ:271822104 王
      

  7.   

    應該是同時更新的吧。
    UPDATE @T
    SET ID=3,OK=ID
    WHERE ID=2
    SELECT * FROM @T
    結果和下面的一樣﹕
    UPDATE @T
    SET OK=ID,ID=3
    WHERE ID=2
    SELECT * FROM @T
    說明更新的時候都是從old這個表中取數
      

  8.   

    vxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      

  9.   

    多谢lz!怎么没有delphi的。我最近在学习delphi就是找不到好的学习视频。
      

  10.   

    asdasdasdasd
    asd
    asd
    asd
    asd
    asd
      

  11.   

    在sqlserver2000下,结果是一样的我的理解是:
    UPDATE @T
    SET ID=3,OK=ID
    WHERE ID=2
    此时OK的值取的还是ID旧值,并没有取ID的新值,因此结果是
    ID          OK          
    ----------- ----------- 
    1           1
    3           2而
    UPDATE @T
    SET @T1=3, OK=@T1,ID=3
    WHERE ID=2
    变量@T1=3,先赋值,然后又进行了更新,也就是说变量函数运算的优先级高于
    更新赋值的优先级。如果放在一起执行的话,第二次更新实际上是没有执行更新操作,因为此时的
    ID 已经等于 3 了。ID=2已经不存在了。
      

  12.   

    比较赞同SmallHand 的意见~~!
      

  13.   

    ***************************************************************************思想决定行动,行动决定习惯,习惯决定命运.
    程序员在深圳QQ群,交流思想,如饮美酒.部份专业群介绍:
    c++群:  15195967(此群流动性相当大,有时候一个月上百人被迫离群)
    java群: 11878667(此群人数较少,但不知道群主会不会让你进群,进群要求很高)
    英语学习群:  23864353(此群人气一般,交流也车不够活跃)
    c++Ⅱ:  17409451(此群是C++第一群的补充,人气自然差点)
    嵌入式开发群:  37489763(此群高手还是有的,气氛一般)
    移动开发群:  31501597(此群人气和氛围都还可以)
    创业群:  33653422(此群名字就注定了讨论的东西一般没有结果.)
    部份高级程序员群(高级群致力于发现和培养专家,人气最旺,淘汰率高,不自信者不要加入):高级群I:17538442
    高级群II:7120862部份初、中级程序员群:
    第三群:2650485
    第五群:29537639
    第四群:28702746
    第六群:10590618
    第七群:10543585
    第八群:12006492
    第九群:19063074
    第十群:2883885
    第十一群:25460595
    第十二群:9663807深圳程序员QQ群联盟成立2005年,拥有三十个以上的QQ群,人数超三千多人,大量高手,从业于大公司(微软、IBM,SUN,华为)、系统分析员(包括参加过上亿元的项目的架构师)。每个人都自信而上进.推荐:深程高级群I:17538442 深程高级群II:7120862 (深程高级群不欢迎新手,如果在深圳,月薪6K以下的别加入) c++:15195967 java群: 11878667  mobile:31501597嵌入式:37489763   
    —————————————————————————————————————————— 
    如果你不是第一次看到此广告,说明我们最近T了一些人,因为我们要不断提升群的质量,保证名副其实.
    -------------------------------------------------------------------------------------
    在通过电邮、新闻组或者聊天室提出技术问题前,检查你有没有做到: 
          1. 通读手册,试着自己找答案。 
          2. 在FAQ里找答案(一份维护得好的FAQ可以包罗万象:)。 
          3. 在网上搜索(个人推荐google~)。 
          4. 向你身边精于此道的朋友打听。 
    我想我们首先应该靠自己解决问题,然后才是问
    ------------------------------------------------------------------------------------------------------技术QQ群是一个体现群体智慧的地方,无价值的发言会给别人带来噪音和负担,如果不同意以上观点的请勿加入!*****************************************************************************