当SQL中只有一条记录时,游标会多次运行
我遇到了一个游标的问题,在某些情况下,游标只填充了一个值,而不是直接存在,在我的例子中,它一直持续到崩溃 代码如下:当SQL中只有一条记录时,游标会多次运行,sql,sql-server,tsql,database-cursor,Sql,Sql Server,Tsql,Database Cursor,我遇到了一个游标的问题,在某些情况下,游标只填充了一个值,而不是直接存在,在我的例子中,它一直持续到崩溃 代码如下: DECLARE @positionID as INT DECLARE position_cursor CURSOR FOR SELECT positionUniqueNumber FROM position WHERE position.Employee
DECLARE @positionID as INT
DECLARE position_cursor CURSOR FOR
SELECT positionUniqueNumber
FROM position
WHERE position.EmployeeID = @EmployeeID
OPEN position_cursor
FETCH NEXT FROM position_cursor INTO @positionID
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE position
SET positionFromDate = DATEADD(day,@days, positionFromDate)
WHERE position.positionUniqueNumber = @positionID
FETCH NEXT FROM position_cursor INTO @positionID
END
CLOSE position_cursor
DEALLOCATE position_cursor
如果“position_cursor”只有一个值,我希望光标在运行一次后仍然存在,相反,它会一直运行,直到它试图设置一个高于9999的日期,然后崩溃。
对我来说,一个解决方法是检查表中有多少条记录符合条件,并且仅当超过1条时才使用光标,但我希望找到更好的方法。思想?
谢谢这里有一个修复程序被注释掉了。大多数人期望游标具有静态语义,但这不是默认的。如果更新导致该行在光标读取的索引中移动,则该行可以读取同一行两次 只要始终将游标声明为本地静态,就可以避免这些问题
drop table if exists position
go
create table position(positionuniquenumber int primary key nonclustered, EmployeeId int, positionFromDate DateTime)
create unique clustered index cix_position on position(employeeid,positionFromDate,positionuniquenumber)
insert into position(positionuniquenumber,EmployeeId,positionFromDate) values (1,1,getdate())
go
DECLARE @EmployeeID int = 1
declare @Days int = 1
DECLARE @positionID as INT
DECLARE position_cursor CURSOR /*LOCAL STATIC*/ FOR
SELECT positionUniqueNumber
FROM position
WHERE position.EmployeeID = @EmployeeID
OPEN position_cursor
FETCH NEXT FROM position_cursor INTO @positionID
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE position
SET positionFromDate = DATEADD(day,@days, positionFromDate)
WHERE position.positionUniqueNumber = @positionID
FETCH NEXT FROM position_cursor INTO @positionID
END
CLOSE position_cursor
DEALLOCATE position_cursor
用您正在使用的数据库标记您的问题。我正在使用SQL Server 2014这是完整的代码吗?您在哪里申报
@Days
?您的代码似乎没有任何问题,尽管光标似乎完全没有必要,但您只需进行简单的更新即可获得完全相同的结果。-<代码>更新职位集positionFromDate=DATEADD(天、@days、positionFromDate)其中position.EmployeeID=@EmployeeID此代码根据原始员工开始日期和新员工开始日期之间的差异更新position from date=@Day可能有多个职位,这就是我使用游标的原因。您可以使用update
语句一次更新多行。SQL是一种基于集合的语言,如果可能,应该避免使用游标。如果您可以显示完整的代码,包括如何设置@Days
,那么应该有人能够重写您的更新以提高效率,并且只使用一条语句。非常感谢-这似乎已经奏效了!我有一个非常相似的光标后,我已经张贴了,其中一些也有1只记录,但他们的工作良好的一些模糊的原因。根据您所说的,本地静态用于避免获取相同记录的可能性,因为更新可能会更改原始索引-正确吗?是的。在repo更新中,positionFromDate实际上会将行移动到聚集索引中光标尚未读取的位置。如果positionFromDate
不是光标正在读取的索引中的键列,则不会发生这种情况。