1

我有一段脚本使用光标对表中的行进行排序。例如,表格如下所示,SSN、Kid_SSN、Kid_DOB、Seq# 列出每个有 1 个或多个孩子的人。我想根据出生日期更新 Seq# 以将每个孩子标记为 1、2、3...。我使用游标进行更新以在 SQL Server 2008 中成功完成。我目前的问题是这个相同的脚本在 sql server 2012 中无法按预期运行。问题在于 SQL 2012 游标一次获取 NEXT 超过 1 行. 所以问题是我在哪里可以设置游标获取大小?我四处寻找,但没有找到好的答案。这里的任何人都可以解释一下吗?谢谢。

脚本如下所示:

DECLARE @SocialSecurity varchar(9), @PersonID int, @Dep_SSN varchar(9)
DECLARE @LastName varchar(20), @FirstName varchar(20), @BirthDate datetime, 
    @Number int

DECLARE @ssn varchar(9) = '000000000'
DECLARE @Mem int = 1
DECLARE cur cursor
FOR SELECT * FROM kids
FOR UPDATE OF Number;

OPEN cur;

FETCH NEXT FROM cur INTO @SocialSecurity, @PersonID, @Dep_SSN, @LastName, @FirstName, 
    @BirthDate, @Number;

WHILE @@FETCH_STATUS = 0
BEGIN

IF @SocialSecurity = @ssn
BEGIN

UPDATE kids
SET Number = @Mem+1
WHERE CURRENT OF cur
SET @Mem = @Mem+1
END;
ELSE
BEGIN
SET @ssn = @SocialSecurity
SET @Mem = 1
END;
FETCH NEXT FROM cur INTO @SocialSecurity, @PersonID, @Dep_SSN, @LastName, @FirstName, 
    @BirthDate, @Number;
END;
CLOSE cur;
DEALLOCATE cur;

有关此问题的更多信息。kids 是由 'SELECT .. INTO' 生成的临时表,简化集如下所示

SSN       Kid_SSN        DOB        Seq#
123123123 987987987      1/1/2000   1
123123123 987987988      1/1/2003   1
123123125 890890890      2/3/2002   1

所以所有 seq# 都初始化为 1。通过上面的脚本后,我希望 table kids 看起来像这样

SSN       Kid_SSN        DOB        Seq#
123123123 987987987      1/1/2000   1
123123123 987987988      1/1/2003   2
123123125 890890890      2/3/2002   1

该脚本在服务器 2008 R2 上完美运行以实现此目的,但在服务器 2012 上却没有。此外,我发现它只更新了第 88 行、第 176 行等(如果适用)。这就是为什么我认为游标一次获取 88 行。但在服务器 2008 上,它显然一次获取 1 行,正如我预期的那样。希望这能解释我遇到的问题。我想强制游标一次获取 1 行以使其在服务器 2012 上工作,尽管它效率不高。或者,如何在不使用光标的情况下进行排序?谢谢。

4

2 回答 2

2

将整个脚本替换为对函数的排名是否可行?

就像是

select *, rank() over (partition by SSN, Kid_DOB order by Kid_SSN) as SeqNum
from kids

我认为这应该可以工作,如果没有,您可以调整分区并按顺序使其工作。

于 2012-10-23T21:34:36.560 回答
1

您的脚本要求光标kids按相同的 SSN 对记录进行分组。但是没有 ORDER BY 可以强制执行此操作。因此,记录以某种随机顺序返回,这会弄乱@Mem计数器。

这不是 SQL 2012 与 2008 的问题。我相信您只是幸运地使用了 SQL 2008,并且记录已经按照您想要的方式排序,或者 SQL 2008 在选择无序结果方面具有不同的行为,或者您定义了 pk 和索引不同。

于 2012-10-24T01:43:38.280 回答