【问题标题】:Check result of transaction before updating table更新表前检查事务结果
【发布时间】:2013-10-10 07:33:50
【问题描述】:

我有以下存储过程:

CREATE PROCEDURE [dbo].[vRpt_VolunteerPaymentsAll]
@startdate DATETIME = NULL ,
@enddate DATETIME = NULL ,
@user NVARCHAR(50)
AS /*  This procedure generates Team Events that have been audtied  */
DECLARE @sd DATETIME
DECLARE @ed DATETIME

/* Ensure that the start and end dates covert whole days */
SET @sd = CONVERT(VARCHAR(10), @startdate, 120) + ' 00:00:00'
SET @ed = CONVERT(VARCHAR(10), @enddate, 120) + ' 23:59:59'



DECLARE @id INT

INSERT  INTO vVolunteerPaymentEvents
        ( StartDate ,
          EndDate ,
          Verifier ,
          DatePaid ,
          RecordsPaid ,
          UnDone ,
          Comments ,
          Flags
        )
VALUES  ( @startdate ,
          @enddate ,
    /*Get the users initials*/
          ( SELECT  dbo.vUsers.Initials
            FROM    dbo.vUsers
            WHERE   dbo.vUsers.UserID = @user
          ) ,
          GETDATE() ,
    /* Count how many records are going ot be affected*/
          ( SELECT  COUNT(*)
            FROM    dbo.vVolunteerPayments
            WHERE   dbo.vVolunteerPayments.PaymentEventID = 0
                    AND ( dbo.vVolunteerPayments.DateCreated BETWEEN @sd
                                                          AND
                                                          @ed )
          ) ,
          0 ,
          '' ,
          0
        )
/*Set the id of the payment event id for the volunteer payments*/
SET @id = SCOPE_IDENTITY() ;

--get the totals for the payment based on the 
--@id value just inserted above 
UPDATE  dbo.vVolunteerPayments
SET     dbo.vVolunteerPayments.PaymentEventID = @id ,
        dbo.vVolunteerPayments.DatePaid = GETDATE()
WHERE   dbo.vVolunteerPayments.PaymentEventID = 0
        AND dbo.vVolunteerPayments.DateCreated BETWEEN @sd
                                               AND     @ed

SELECT * FROM 
(SELECT  VOLSACCT.volunteerid ,
        ISNULL(VOLS.Forename, '') + ' ' + ISNULL(VOLS.Surname, '') AS Name ,
        VOLSACCT.SortCode ,
        VOLSACCT.AccountName ,
        VOLSACCT.AccountNumber ,
        SUM(CASE [Type]
              WHEN 1001
              THEN CASE WHEN PMTS.DateCreated BETWEEN @sd AND @ed

                             --AND PMTS.PaymentEventID = 0
                             --AND PMTS.VolunteerId = @volunteerid
                        THEN Amount
                   END
              ELSE 0
            END) AS Reimbursements ,
        SUM(CASE [Type]
              WHEN 1002
              THEN CASE WHEN PMTS.DateCreated BETWEEN @sd AND @ed

                             --AND PMTS.PaymentEventID = 0
                             --AND PMTS.VolunteerId = @volunteerid
                        THEN Amount
                   END
              ELSE 0
            END) AS MobilePhoneCharges ,
        SUM(CASE [Type]
              WHEN 1003
              THEN CASE WHEN PMTS.DateCreated BETWEEN @sd AND @ed
                             --AND PMTS.PaymentEventID = 0
                             --AND PMTS.VolunteerId = @volunteerid
                        THEN Amount
                   END
              ELSE 0
            END) AS GPContributions ,
        SUM(CASE [Type]
              WHEN 12
              THEN CASE WHEN PMTS.DateCreated BETWEEN @sd AND @ed
                             --AND PMTS.PaymentEventID = 0
                             --AND PMTS.VolunteerId = @volunteerid
                        THEN Amount
                   END
              ELSE 0
            END) AS GPExpenses ,
        SUM(CASE [Type]
              WHEN 137
              THEN CASE WHEN PMTS.DateCreated BETWEEN @sd AND @ed
                             --PaymentEventID = 0
                             --AND PMTS.VolunteerId = @volunteerid
                        THEN Amount
                   END
              ELSE 0
            END) AS Expenses ,
        SUM(CASE WHEN PMTS.DateCreated BETWEEN @sd AND @ed

                      --AND PMTS.PaymentEventID = 0
                      --AND PMTS.VolunteerId = @volunteerid
                       THEN Mileage
                 ELSE 0
            END) AS TotalMileageWeek ,
        VOLSACCT.BACS,
        PMTS.ChargeRate

FROM    dbo.vVolunteerPayments PMTS
        INNER JOIN dbo.vVolunteerAccounts VOLSACCT ON PMTS.VolunteerId = VOLSACCT.VolunteerID
        INNER JOIN dbo.vVolunteers VOLS ON PMTS.VolunteerId = VOLS.VolunteerID
WHERE   PMTS.PaymentEventID = @id
GROUP BY VOLSACCT.volunteerid ,
        VOLSACCT.AccountName ,
        VOLSACCT.AccountNumber ,
        VOLSACCT.BACS ,
        VOLSACCT.SortCode ,
        VOLS.Forename ,
        VOLS.Surname,
        PMTS.ChargeRate) AS A
        WHERE 
        GPContributions >0
        OR GPExpenses > 0
        OR MobilePhoneCharges > 0
        OR Expenses > 0
        OR Reimbursements > 0 
        OR Expenses > 0
        OR TotalMileageWeek >0
        ORDER BY Name

它基本上将受影响交易的摘要记录插入到一​​个表中 (volunteerpaymentevent),更新另一个表的现有记录 (volunteerpayments(datepaid and payment event id)),然后在连接中返回汇总值的记录集

但是我发现如果连接失败或根本没有连接(因此没有任何输出),那么过程的更新部分仍然会更新记录

有没有办法在更新志愿者支付表中的记录之前检查内连接的结果 干杯

【问题讨论】:

    标签: sql tsql sql-update inner-join


    【解决方案1】:

    您需要将代码放入事务中:

    ALTER PROCEDURE [dbo].[vRpt_VolunteerPaymentsAll]
    @startdate DATETIME = NULL ,
    @enddate DATETIME = NULL ,
    @user NVARCHAR(50)
    AS 
    
    begin transaction
    
    your procedure code
    
    commit transaction
    

    有关交易的更多信息,请参阅MSDN

    【讨论】:

    • 对于第二部分(如果您的联接为空),您可以从联接表中选择记录数,然后如果返回零记录,则运行rollback transaction
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 2013-08-05
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多