Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当SQL中只有一条记录时,游标会多次运行_Sql_Sql Server_Tsql_Database Cursor - Fatal编程技术网

当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
不是光标正在读取的索引中的键列,则不会发生这种情况。