Sql server 使用Try-Catch:为什么每次查询结果集都不一致
当我运行下面的代码时,我得到了不一致的数字,有时是1条记录,有时是5条记录 我正试图从临时表中获取数据到最终表或新表。temp表中的数据包含每个成员的多条记录。每次成员访问时,都会将一个新的Sql server 使用Try-Catch:为什么每次查询结果集都不一致,sql-server,tsql,Sql Server,Tsql,当我运行下面的代码时,我得到了不一致的数字,有时是1条记录,有时是5条记录 我正试图从临时表中获取数据到最终表或新表。temp表中的数据包含每个成员的多条记录。每次成员访问时,都会将一个新的计数编号插入到带有memberID的表中。这是一种INT数据类型。如果一个成员访问了10次,那么他们的数字从1到10,其中10次是最近的访问 我正在尝试获取最近的访问并插入到新表中,但如果出现错误,我需要回滚 注意:我是引发错误,因为此代码将放置在SSIS TSQL任务中,如果代码失败,则引发错误将使任务停止
计数编号
插入到带有memberID的表中。这是一种INT数据类型。如果一个成员访问了10次,那么他们的数字从1到10,其中10次是最近的访问
我正在尝试获取最近的访问并插入到新表中,但如果出现错误,我需要回滚
注意:我是引发错误
,因为此代码将放置在SSIS TSQL任务中
,如果代码失败,则引发错误将使任务停止
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;
为什么即使源数据没有更改,结果也不一致?查询中有日期。确实没有添加其他行,因为WHERE子句可能会随着时间的推移添加数据 另外,其他隔离级别有脏读、不可重复读和幻象读。这一切都与其他人在您获取数据时更改数据有关。你不是唯一一个在这个系统上的人 请参阅本文中的矩阵 如果启用快照隔离,并且发生了相同的不一致,则是TSQL代码中的日期或其他内容。然而,它看起来很直截了当 SELECT语句的逻辑顺序 使用派生表可以实现相同的逻辑和功能。该表具有成员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次此查询是否会得到不同的结果?
我故意省略了这个额外的过滤器
和T[canceledDate]>GETDATE() 不,没有其他人在操作数据,数据不是活动的,但它位于一个大表中。谢谢基本上,您是按访问日期获取最近的成员,该成员位于位置121中,该位置具有cancel date>getdate()。尝试将行号移动到第一个字段。还有,放一个;在CTE前面。当我点击execute时,结果集中的变化正在发生,每次我都会得到不同数量的记录返回。嘿,我的朋友,我认为这看起来很有希望,但我想进一步测试它。到目前为止,我没有看到相同的行为,但结果集确实发生了变化,但保持不变。你的想法是什么?你是否加回了取消日期。这就是我认为你的问题所在。但是派生表可能更有意义,因为您无论如何都要丢弃rownumber()值。解决问题的方法有很多。每次运行它时,
GETDATE()
都会有所不同。还有MemberID,VisitDate的任何重复值吗?没有实际的重复值,但是有多个具有不同访问计数和日期但具有相同ID的记录实例。每次单击“执行”时,结果都会发生变化,且数据不活动。我还尝试了>CAST(GETDATE()AS DATE)
同样的问题。尝试捕获实际的执行计划。当您得到两个具有不同行数的运行时,请查看计划运算符上的实际行数,并查看它们的不同之处。VisitDate的数据类型是什么?是否包括一天中的时间?是否填写了时间,即不总是午夜?是否有理由不将取消日期条件包括在CTE内而不是之后?
-- 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