当我运行以下代码时,我得到的数字不一致,有时会关闭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;
为什么结果不一致,即使源数据没有改变?
答案 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();