使用Try Catch:为什么每次查询结果设置不一致

时间:2013-12-13 23:43:29

标签: sql-server tsql

当我运行以下代码时,我得到的数字不一致,有时会关闭1个记录,其他时候会关闭5个记录。

我正在尝试从临时表中获取数据到最终或新表。临时表中的数据包含每个成员的多个记录。每次成员访问时,都会使用memberID将新count number插入到表中。这是INT数据类型。如果一个成员访问10次,那么他们将有1到10的数字,其中10个是最近的访问。

我正在尝试获取最近的访问并插入到新表中,但如果发生错误,我需要回滚。

注意:我是Raising Error,因为此代码将放在SSIS TSQL Task中,如果代码失败,则引发错误将使任务停止。

USE MyDB;

GO

BEGIN TRY
    BEGIN TRANSACTION;

    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    WITH Member
         AS (SELECT [MemberID],
                    [LocationID],
                    [CancelledDate],
                    [VisitCount],
                    [VisitDate],
                    ROW_NUMBER() OVER (PARTITION BY MemberID 
                                           ORDER BY [VisitDate] DESC) AS RowNumber
             FROM   [MySchema].[TempMemberTable]
             WHERE  MemberID IS NOT NULL
                    AND LocationID = '121')
    INSERT INTO [MySchema].[NewMemberTable]
                ([MemberID],
                 [LocationID],
                 [CancelledDate],
                 [VisitCount],
                 [VisitDate])
    SELECT [MemberID],
           [LocationID],
           [CancelledDate],
           [VisitCount],
           [VisitDate]
    FROM   Member
    WHERE  RowNumber = 1
           AND [CancelledDate] > GETDATE();

    COMMIT TRANSACTION
END TRY

BEGIN CATCH
    IF @@ERROR > 0
      BEGIN
          ROLLBACK TRANSACTION;
      END

    SELECT @ErrorMessage = ERROR_MESSAGE(),
           @ErrorSeverity = ERROR_SEVERITY(),
           @ErrorState = ERROR_STATE();

    RAISERROR (@ErrorMessage,@ErrorSeverity,@ErrorState );
END CATCH; 

为什么结果不一致,即使源数据没有改变?

1 个答案:

答案 0 :(得分:1)

您在QUERY中有一个日期。您确定没有添加其他行,因为WHERE子句可能会在时间运行时添加数据吗?

此外,其他隔离级别具有脏读,不可重复读和幻像读。这一切都与其他人在您抓住数据时更改数据有关。你不是一个人在系统上!

请参阅本文中的矩阵。

http://technet.microsoft.com/en-us/library/ms378149.aspx

如果打开快照隔离并发生相同的不一致,则它是TSQL代码中的日期或某些内容。但是,它看起来很直接。

SELECT语句的逻辑顺序。

http://technet.microsoft.com/en-us/library/ms189499.aspx

1-FROM
2-ON
3-JOIN
4-WHERE
5-GROUP BY
6-WITH CUBE or WITH ROLLUP
7-HAVING
8-SELECT
9-DISTINCT
10-ORDER BY
11-TOP

使用派生表实现相同的逻辑。该表包含会员ID和最大访问日期。完整联接会带回最新记录。

-- Run Select Statemnt 5 Times
SELECT 
 [MemberID]
,[LocationID]
,[CancelledDate]
,[VisitCount]
,[VisitDate]
FROM [MySchema].[TempMemberTable] as T
JOIN
(
    SELECT MemberID as var_MemberID, Max([VisitDate]) as var_VisitDate
    FROM [MySchema].[TempMemberTable] 
    WHERE LocationID = '121'
) as D
WHERE T.[MemberID] = D.var_MemberID and T.[VisitDate] = D.var_VisitDate
GO 5

此查询执行5次会给您带来不同的结果吗?

我故意不再使用这个额外的过滤器

AND T. [CancelledDate]> GETDATE();