sql - 无法在 READ ONLY 游标上指定 FOR UPDATE

标签 sql sql-server t-sql sql-server-2000

我正在使用游标更新表中的单个字段,并尝试在选择文本中使用 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/

相关文章:

sql - 我出错了--- -“Invalid truncate option - missing STORAGE keyword”

sql-server - 我的查询中出现“将 int 转换为数据类型 numeric 时出现算术溢出错误”错误

sql-server - 在 Sql Profiler 中看不到语句文本

json - 如果列名称包含APOSTROPHE(),则无法在SQLSERVER中插入JSON数据

sql - 无法对 SQL Server 中的所有行应用计算

sql - 如何连接多行?

sql-server - 选择跨列的前 n 个值并求平均值

java - HQL 是否有 Restrictions.ilike 的等效项(用于不区分大小写的匹配)?

Mysql Sum 条件

c# - 从格式化的文本框字段将日期时间添加到 SQL 数据库