如何使用 CURSOR 更新 SQL 中的多行?

Posted

技术标签:

【中文标题】如何使用 CURSOR 更新 SQL 中的多行?【英文标题】:How to Update multiple rows in SQL using a CURSOR? 【发布时间】:2020-06-03 12:25:53 【问题描述】:

下面是我正在尝试但没有工作的 SQL 更新。但它适用于单个记录整数更新,同时使用 @sampids 作为 INT 数据类型。任何帮助将非常感激。谢谢

DECLARE @sampids AS NVARCHAR(1000)='10,20,30'   
DECLARE @sampcursorno AS INT=0

DECLARE sample_cursor CURSOR FOR
SELECT VALUE FROM Split(@sampids,',')
OPEN sample_cursor
FETCH NEXT FROM sample_cursor INTO @sampcursorno

WHILE @@FETCH_STATUS = 0
    BEGIN   

        UPDATE tbl_Testing
        SET SampId = @sampcursorno

        FETCH NEXT FROM sample_cursor INTO @sampcursorno

    END

CLOSE sample_cursor

DEALLOCATE sample_cursor

【问题讨论】:

您使用的是哪个 dbms? (该代码是特定于产品的。) “不工作”是什么意思? 从 STRING_SPLIT(@sampids,',') 中选择值 您的更新没有where 子句。所以游标的每次迭代都会更新所有行。游标完成后,所有行都将使用最后出现的任何值进行更新(顺便说一句,您也无法控制)。 另外,请编辑您的问题以包含预期的输出,在评论中很难阅读 【参考方案1】:

我了解到您想要更新原始表格,将每个 sampId 替换为输入 csv 列表中的每个相应索引。

SQL Server 中没有split() 函数。不能使用string_split(),因为它不保证返回零件的顺序。

一种选择是使用递归查询拆分输入字符串,然后使用生成的数据集进行更新:

declare @sampids as nvarchar(1000)='10,20,30';

with cte as (
    select 
        1 id,
        cast(substring(@sampids, 1, charindex(',', @sampids) - 1) as int) sampid,
        substring(@sampids + ',', charindex(',', @sampids) + 1, len(@sampids)) rest
    union all
    select 
        id + 1,
        cast(substring(rest, 1, charindex(',', rest) - 1) as int),
        substring(rest, charindex(',', rest) + 1, len(rest))
    from cte
    where charindex(',', rest) > 0
)
update t
set sampid = c.id
from tbl_Testing t
inner join cte c on c.sampid = t.sampid

【讨论】:

以上是关于如何使用 CURSOR 更新 SQL 中的多行?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Cursor(游标)--转

如何在 PL/SQL 中使用 BULK COLLECT 和 FORALL 替换 CURSOR FOR LOOP?

如何使用 linq to sql 一次更新多行?

如何使用linq to sql一次更新多行?

如何用变量更新sql表

高效更新 SQL,一条 SQL 语句更新多行,避免循环