我正在使用游标更新表中的单个字段,并尝试在选择文本中使用 ORDER BY
声明游标。
我有以下示例数据:
testTable:
RecordGuid RecordID DupeParentID
---------- -------- ------------
[guid] A Y
[guid] A N
[guid] A N
[guid] A N
[guid] B Y
[guid] B N
[guid] B N
[guid] C Y
[guid] C N
[guid] C N
和脚本:
DECLARE @allcounter INT
SET @allcounter = 1
SELECT RecordID, count(*) as [NumberDupes]
INTO #RecordGroupCounts
FROM testTable
GROUP BY RecordID
DECLARE @temp VARCHAR(500)
DECLARE @current VARCHAR(500)
DECLARE c1 CURSOR
FOR
SELECT RecordID FROM testTable WHERE RecordID IN (SELECT RecordID FROM testTable WHERE DupeParentID = 'Y')
ORDER BY RecordID
FOR UPDATE OF RecordID
OPEN c1
FETCH NEXT FROM c1 INTO @current
FETCH NEXT FROM c1 INTO @current
WHILE @@fetch_status = 0
BEGIN
UPDATE testTable
SET RecordID = RecordID + '-' + cast(@allcounter AS VARCHAR)
WHERE CURRENT OF c1
IF (@allcounter + 1) = (SELECT [NumberDupes] FROM #RecordGroupCounts WHERE RecordID = @current)
BEGIN
FETCH NEXT FROM c1 INTO @current
SET @allcounter = 0
END
SET @allcounter = @allcounter + 1
FETCH NEXT FROM c1 INTO @current
END
CLOSE c1
DEALLOCATE c1
所有这些的期望输出是:
RecordGuid RecordID DupeParentID
---------- -------- ------------
[guid] A Y
[guid] A-1 N
[guid] A-2 N
[guid] A-3 N
[guid] B Y
[guid] B-1 N
[guid] B-2 N
[guid] C Y
[guid] C-1 N
[guid] C-2 N
我正在使用 SQL Server 2000,因此没有可用的 ROW_NUMBER()
- 我知道执行此操作的常见方法是使用循环,但我绝不是 DBA,如果我在游标声明中删除我的 ORDER BY RecordID
,这当前是有效的。
对于我当前的测试表来说,这似乎工作得很好,但我尝试订购它的原因是,我相当确定如果 RecordID 不按顺序,它就会中断(通过RecordID ASC, DupeParentID DESC
),我打算半定期地在更大的记录集上使用它。有没有办法定义游标更新的顺序?光标是否以某种方式自动排序?如果没有,是否有更简单(或更快)的方法为 SQL Server 2000 编写此代码?
最佳答案
select recordid, max(recordguid)
from testable
where DupeParentID = 'N'
group by recordID
上面的语句应该为每个 recordID 返回 1 行,并带有该 recordID 的 max(guID)。呵呵,拼写检查不断改变引导引导。现在我们可以用 1 来增加所有这些。
update testtable
set recordID = recordID + '-1'
where recordguid in (select recordguid from ( select recordid, max(recordguid) recordguid
from testable
where DupeParentID = 'N'
group by recordID) a)
明白这里的逻辑了吗?我们正在做的是使用 max recordguid 作为“第一个”的标识符来获取第一个重复 ID...任意,我们可以使用 min,只要它为每个 recordID 返回一个 guID。如果您对于哪条记录被称为 -1 与 -2 有其他逻辑,您可以将其包含在此处。
这将创建所有 recordID-1 (A-1,B-1) 并保留其余部分。现在你应该能够循环这个并根据需要增加 -1...或者你可以重复运行它,手动增加 -1 如果这是一次性修复...你在那里调用。
让我知道它是如何进行的...逻辑应该可以工作,并且比一次遍历每个 recordID 更快。
关于sql - 无法在 READ ONLY 游标上指定 FOR UPDATE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8495283/