USE bankDB
GO
IF EXISTS(SELECT * FROM sysobjects WHERE NAME='proc_takeMoney')
DROP PROCEDURE proc_takeMoney
GO
CREATE PROCEDURE proc_takeMoney
(
@card VARCHAR(30), --卡号
@COURSE VARCHAR(20), --交易的类型
@INMONEY MONEY, --存入的金额
@OUTMONEY MONEY, --取出的金额
@PWD VARCHAR(10), --密码
@NOMONEY INT=0 OUTPUT --定义余额不够得标志
)
AS
BEGIN TRAN
DECLARE @YMONEY MONEY --卡上的余额
DECLARE @PASSWORD VARCHAR(10) --保存搜索的真实密码
DECLARE @SUMERROR INT; --定义错误
SET @SUMERROR=0
IF @COURSE='存钱'
BEGIN
PRINT 'A交易正在进行,请稍后……'
UPDATE cardAID SET balance=balance+@INMONEY WHERE cardID=@card
SET @SUMERROR=@SUMERROR+@@ERROR;
IF @SUMERROR<>0
BEGIN
PRINT '交易失败!'
SELECT @YMONEY=balance FROM cardAID WHERE cardID=@card
PRINT '卡号:'+@card+'  余额:'+CONVERT(VARCHAR,@YMONEY)
ROLLBACK TRAN
SET @NOMONEY=1
RETURN; END
ELSE
BEGIN
PRINT '交易成功!'
SELECT @YMONEY=balance FROM cardAID WHERE cardID=@card
PRINT '卡号:'+@card+'  余额:'+CONVERT(VARCHAR,@YMONEY)
SET @NOMONEY=0
COMMIT TRAN
RETURN
END
END
ELSE --扣钱交易
BEGIN
PRINT 'B交易正在进行,请稍后……'
SELECT @PASSWORD=pass FROM cardAID WHERE cardID=@card
DECLARE @TRUEMONEY MONEY;
SELECT @TRUEMONEY=balance FROM dbo.cardAID WHERE cardID=@card
IF @PASSWORD=@PWD --验证密码
BEGIN
IF @TRUEMONEY>@OUTMONEY+1--余额大于要转账的金额
BEGIN
UPDATE cardAID SET balance=balance-@OUTMONEY WHERE cardID=@card
SET @SUMERROR=@SUMERROR+@@ERROR;
IF @SUMERROR<>0
BEGIN
PRINT '交易失败!请重试……'
SELECT @YMONEY=balance FROM cardAID WHERE cardID=@card
PRINT '卡号:'+@card+'  余额:'+CONVERT(VARCHAR,@YMONEY)
ROLLBACK TRAN
SET @NOMONEY=1
RETURN;
END
ELSE
BEGIN
PRINT '交易成功!'
SELECT @YMONEY=balance FROM cardAID WHERE cardID=@card
PRINT '卡号:'+@card+'  余额:'+CONVERT(VARCHAR,@YMONEY)
COMMIT TRAN
SET @NOMONEY=0
RETURN;
END
END
ELSE --余额小于要转账的金额
BEGIN
PRINT '交易失败,对不起,您的余额不够!'
SELECT @YMONEY=balance FROM cardAID WHERE cardID=@card
PRINT '卡号:'+@card+'  余额:'+CONVERT(VARCHAR,@YMONEY)
PRINT '@@@@@@@@@@@@---------@@@@@@@@@@@@@@'
SET @NOMONEY=1
ROLLBACK TRAN
print '2222222222'
RETURN;
END
END
ELSE --密码错误
BEGIN
PRINT '您输入的密码有错误!'
SET @NOMONEY=1
ROLLBACK TRAN
RETURN;
END
END
GO
SELECT * FROM cardAID
EXEC proc_takeMoney '1010 3577 0989 7654','取钱',0,23,'888888'
--创建事务实现转账功能
USE bankDB
GO
IF EXISTS(SELECT * FROM sysobjects WHERE NAME='proc_transfer')
DROP PROCEDURE proc_transfer
GO
CREATE PROCEDURE proc_transfer
(
@incard1 VARCHAR(20),
@outcard2 VARCHAR(20),
@outMoney MONEY
)
AS
BEGIN TRANSACTION
DECLARE @SUMERROR INT;
DECLARE @FAN   INT;
SET @SUMERROR=0;
EXEC proc_takeMoney @outcard2,'去钱',0,@outMoney,'888888',@FAN OUTPUT
print '33333333333333'
SET @SUMERROR=@SUMERROR+@@ERROR;
PRINT CONVERT(VARCHAR,@FAN)+'!!!!!!!!!!!!'
IF @FAN=0
BEGIN
EXEC proc_takeMoney @incard1,'存钱',@outMoney,0,'888888'
SET @SUMERROR=@SUMERROR+@@ERROR;
END
ELSE
BEGIN
SET @SUMERROR=1
END
IF (@SUMERROR<>0)
BEGIN
PRINT '转账失败!'
PRINT CONVERT(VARCHAR,@SUMERROR)
ROLLBACK TRANSACTION
PRINT '&&&&&&&&&&&&&&&&&&&'
END
ELSE 
BEGIN
PRINT '转账成功!'
COMMIT TRANSACTION
END
GO
执行过程
PRINT '转账前各自的金额'
SELECT cardID,balance FROM cardAID
SET NOCOUNT ON
EXEC proc_transfer '1010 3577 0989 7654','1010 3577 2978 7492',1000
PRINT '转账后各自的金额'
SELECT cardID,balance FROM cardAID
输出
转账前各自的金额
cardID                                             balance
-------------------------------------------------- ---------------------
1010 3577 0989 7654                                1500.00
1010 3577 2978 7492                                500.00
1010 3577 3965 3808                                1000.00
1010 3577 4964 7396                                1000.00
1010 3577 6507 2024                                1000.00
1010 3577 7010 2926                                1234.00
1010 3577 9252 1548                                1234.00B交易正在进行,请稍后……
交易失败,对不起,您的余额不够!
卡号:1010 3577 2978 7492  余额:500.00
@@@@@@@@@@@@---------@@@@@@@@@@@@@@
2222222222
消息 266,级别 16,状态 2,过程 proc_takeMoney,第 0 行
EXECUTE 后的事务计数指示缺少了 COMMIT 或 ROLLBACK TRANSACTION 语句。上一计数 = 1,当前计数 = 0。
33333333333333
1!!!!!!!!!!!!
转账失败!
1
消息 3903,级别 16,状态 1,过程 proc_transfer,第 29 行
ROLLBACK TRANSACTION 请求没有对应的 BEGIN TRANSACTION。
&&&&&&&&&&&&&&&&&&&
转账后各自的金额
cardID                                             balance
-------------------------------------------------- ---------------------
1010 3577 0989 7654                                1500.00
1010 3577 2978 7492                                500.00
1010 3577 3965 3808                                1000.00
1010 3577 4964 7396                                1000.00
1010 3577 6507 2024                                1000.00
1010 3577 7010 2926                                1234.00
1010 3577 9252 1548                                1234.00
把1000改为100
PRINT '转账前各自的金额'
SELECT cardID,balance FROM cardAID
SET NOCOUNT ON
EXEC proc_transfer '1010 3577 0989 7654','1010 3577 2978 7492',100
PRINT '转账后各自的金额'
SELECT cardID,balance FROM cardAID
输出没有报错
转账前各自的金额
cardID                                             balance
-------------------------------------------------- ---------------------
1010 3577 0989 7654                                1500.00
1010 3577 2978 7492                                500.00
1010 3577 3965 3808                                1000.00
1010 3577 4964 7396                                1000.00
1010 3577 6507 2024                                1000.00
1010 3577 7010 2926                                1234.00
1010 3577 9252 1548                                1234.00B交易正在进行,请稍后……
交易成功!
卡号:1010 3577 2978 7492  余额:400.00
33333333333333
0!!!!!!!!!!!!
A交易正在进行,请稍后……
交易成功!
卡号:1010 3577 0989 7654  余额:1600.00
转账成功!
转账后各自的金额
cardID                                             balance
-------------------------------------------------- ---------------------
1010 3577 0989 7654                                1600.00
1010 3577 2978 7492                                400.00
1010 3577 3965 3808                                1000.00
1010 3577 4964 7396                                1000.00
1010 3577 6507 2024                                1000.00
1010 3577 7010 2926                                1234.00
1010 3577 9252 1548                                1234.00

解决方案 »

  1.   

    對你的tran 加上名字試試
    好長啊
      

  2.   

    tran都加上名字,
    commit,rollback也加上
    估计是这个引起的
      

  3.   

    lz没理解透Rollback tran的用法.
    联机帮助中的说明:
    In stored procedures, ROLLBACK TRANSACTION statements without a savepoint_name or transaction_name roll back all statements to the outermost BEGIN TRANSACTION.
      

  4.   

    试试这个USE bankDB
    GO
    IF EXISTS(SELECT * FROM sysobjects WHERE NAME='proc_takeMoney')
        DROP PROCEDURE proc_takeMoney
    GO
    CREATE PROCEDURE proc_takeMoney
    (
        @card        VARCHAR(30),        --卡号
        @COURSE        VARCHAR(20),        --交易的类型
        @INMONEY    MONEY,                --存入的金额
        @OUTMONEY    MONEY,                --取出的金额
        @PWD        VARCHAR(10),        --密码
        @NOMONEY    INT=0    OUTPUT        --定义余额不够得标志
    )
    AS
    BEGIN TRAN 
    SAVE TRAN takemoney_point DECLARE @YMONEY MONEY                --卡上的余额
    DECLARE @PASSWORD VARCHAR(10)        --保存搜索的真实密码
    DECLARE @SUMERROR INT;                --定义错误
    SET @SUMERROR=0
    IF @COURSE='存钱'
        BEGIN
            PRINT 'A交易正在进行,请稍后……'
            UPDATE cardAID SET balance=balance+@INMONEY WHERE cardID=@card
            SET @SUMERROR=@SUMERROR+@@ERROR;
            IF @SUMERROR<>0
                BEGIN
                    PRINT '交易失败!'
                    SELECT @YMONEY=balance FROM cardAID WHERE cardID=@card
                    PRINT '卡号:'+@card+'  余额:'+CONVERT(VARCHAR,@YMONEY)
                    ROLLBACK TRAN  takemoney_point
                    SET @NOMONEY=1
                    GOTO End_tran;
                END
            ELSE
                BEGIN
                    PRINT '交易成功!'
                    SELECT @YMONEY=balance FROM cardAID WHERE cardID=@card
                    PRINT '卡号:'+@card+'  余额:'+CONVERT(VARCHAR,@YMONEY)
                    SET @NOMONEY=0
    GOTO End_tran
                END
        END
    ELSE    --扣钱交易
        BEGIN
            PRINT 'B交易正在进行,请稍后……'
            SELECT @PASSWORD=pass FROM cardAID WHERE cardID=@card
            DECLARE @TRUEMONEY MONEY;
            SELECT @TRUEMONEY=balance FROM dbo.cardAID WHERE cardID=@card
            IF @PASSWORD=@PW    --验证密码
                BEGIN
                    IF @TRUEMONEY>@OUTMONEY+1--余额大于要转账的金额
                        BEGIN
                            UPDATE cardAID SET balance=balance-@OUTMONEY WHERE cardID=@card
                            SET @SUMERROR=@SUMERROR+@@ERROR;
                            IF @SUMERROR<>0
                                BEGIN
                                    PRINT '交易失败!请重试……'
                                    SELECT @YMONEY=balance FROM cardAID WHERE cardID=@card
                                    PRINT '卡号:'+@card+'  余额:'+CONVERT(VARCHAR,@YMONEY)
                                    ROLLBACK TRAN takemoney_point
                                    SET @NOMONEY=1
                                    GOTO End_tran
                                END
                            ELSE            
                                BEGIN
                                    PRINT '交易成功!'
                                    SELECT @YMONEY=balance FROM cardAID WHERE cardID=@card
                                    PRINT '卡号:'+@card+'  余额:'+CONVERT(VARCHAR,@YMONEY)
                                    SET @NOMONEY=0
                                    GOTO End_tran
                                END
                        END
                    ELSE            --余额小于要转账的金额
                        BEGIN
                            PRINT '交易失败,对不起,您的余额不够!'
                            SELECT @YMONEY=balance FROM cardAID WHERE cardID=@card
                            PRINT '卡号:'+@card+'  余额:'+CONVERT(VARCHAR,@YMONEY)
                            PRINT '@@@@@@@@@@@@---------@@@@@@@@@@@@@@'
                            SET @NOMONEY=1
                            ROLLBACK TRAN takemoney_point
    print '2222222222'
                            GOTO End_Tran
                        END
                END
            ELSE    --密码错误
                BEGIN
                    PRINT '您输入的密码有错误!'
                    SET @NOMONEY=1
                    ROLLBACK TRAN takemoney_point
                    GOTO End_tran
                END
        END
    End_tran:
    COMMIT TRAN
    GO