是这样,
首先得到符合条件的多行中的一行,
然后把该行中标志位字段置为1,
如果成功,提交事务,并返回该行一字段的值,
不成功则回滚可我在程序中执行sql语句正常却无法获得该字段值(在sql server分析器里面执行可以)
试了事务+存储过程也没成功,偶对数据库不太在行,请大侠指点大致的意思:
BEGIN TRAN zMDFC_TypeCode
DECLARE @V_VIPath VARCHAR(32)
SELECT TOP 1 @V_VIPath = VIPath FROM VIPool WHERE bFlag = 0
UPDATE VIPool SET bFlag = 1 WHERE VIPath = @V_VIPath
SELECT @V_VIPath
IF @@ERROR = 0
COMMIT TRAN zMDFC_TypeCode
IF @@ERROR <> 0
ROLLBACK TRAN zMDFC_TypeCode执行成功,返回为空。试了几次,发现如果没有UPDATE语句可以返回记录集。

解决方案 »

  1.   

    默认事务隔离级别下select 只加共享锁, 并且在select完成后, 锁就释放掉了, 跟事务是否结束没有关系.
    所以不清楚你加事务想保障什么, 在默认的事务隔离级别下, 你加的事务是没有意义的.而且一般不会对select用事务, 事务一般主要用于保证数据处理(新增/修改/删除)的一致性.
      

  2.   

    至于 update , 如果只从你的处理语句考虑, 则事务只对update有效, 但你只有一条update语句, sql会对每条这样的处理语句自动加事务.所以 udpate 要么成功, 要么失败, 实在没有手工加事务的必要性.
      

  3.   

    再说返回的问题, 你的 update 和 select 是会向程序报告 update 和 selct 影响了多少行, 所以你的程序首先得到的是这个信息, 而不是 select @V_VIPath 的结果.你可以加 set nocount on 屏蔽掉无关输出信息就可以正确得到结果了.
    SET NOCOUNT ON
    BEGIN TRAN zMDFC_TypeCode
    DECLARE @V_VIPath VARCHAR(32)
    SELECT TOP 1 @V_VIPath = VIPath FROM VIPool WHERE bFlag = 0
    UPDATE VIPool SET bFlag = 1 WHERE VIPath = @V_VIPath
    SELECT @V_VIPath
    IF @@ERROR = 0
    COMMIT TRAN zMDFC_TypeCode
    IF @@ERROR <> 0
    ROLLBACK TRAN zMDFC_TypeCode
    SET NOCOUNT OFF
      

  4.   

    你的查询肯定没有返回记录集
    应该是你的表里的就没有bflag的值就没有为0的。 
      

  5.   

    那如果不用事务,如何保证得到的这个VIPath值之后,设置标志位bFlag之前,没有其它的并发也得到这个VIPath值呢?
    比如
    DECLARE @V_VIPath VARCHAR(32)
    SELECT TOP 1 @V_VIPath = VIPath FROM VIPool WHERE bFlag = 0
    UPDATE VIPool SET bFlag = 1 WHERE VIPath = @V_VIPath
    如果执行完第二句后,还没来得及执行第三句,另外一个程序调用执行到
    SELECT TOP 1 @V_VIPath = VIPath FROM VIPool WHERE bFlag = 0
    会不会得到同样的VIPath
      

  6.   

    那如果不用事务,如何保证得到的这个VIPath值之后,设置标志位bFlag之前,没有其它的并发也得到这个VIPath值呢?我前面已经说过了, select 的锁在select完成后即释放, 因此加了事务等于没有加事务, 都达不到你上面的这个要求.
      

  7.   

    -- 正确的方法, 加锁提示, 把锁保持到事务结束SET NOCOUNT ON
    BEGIN TRAN zMDFC_TypeCode
    DECLARE @V_VIPath VARCHAR(32)
    SELECT TOP 1 @V_VIPath = VIPath FROM VIPool (UPDLOCK) -- 正确的方法, 加锁提示, 把锁保持到事务结束
    WHERE bFlag = 0
    UPDATE VIPool SET bFlag = 1 WHERE VIPath = @V_VIPath
    SELECT @V_VIPath
    IF @@ERROR = 0
    COMMIT TRAN zMDFC_TypeCode
    IF @@ERROR <> 0
    ROLLBACK TRAN zMDFC_TypeCode
    SET NOCOUNT OFF
      

  8.   

    或者将事务隔离级别设置为
    REPEATABLE READ
    SERIALIZABLE
    这两种之一
      

  9.   

    呵呵,我记得事务默认得隔离级别是最严格的SERIALIZABLE,不用另外设了吧?
    多谢多谢楼上,以后多多指点!!