更新尚未获取的游标行中的数据 sql 服务器
Update data in a cursor row not yet fetched sql server
在添加唯一约束之前,我需要更新 table 的 "Order" 列,以避免在添加约束时出错。要更新此字段,我正在尝试执行以下 T-SQL 代码:
DECLARE c_x CURSOR FOR
SELECT ID, ISOLD, ISNEW, GROUPID, ORDER, ISENABLED
FROM mytable
OPEN c_x;
FETCH NEXT FROM c_x INTO @ID, @ISOLD, @ISNEW, @GROUPID, @ORDER, @ISENABLED;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @SUMOFROWS = COUNT(*) FROM mytable
WHERE ISOLD = @ISOLD
AND ISNEW = @ISNEW
AND GROUPID = @GROUPID
AND ORDER = @ORDER
AND ISENABLED = @ISENABLED;
IF @SUMOFROWS > 1
BEGIN
UPDATE mytable
SET ORDER = ORDER+ 1
WHERE ISOLD = @ISOLD
AND ISNEW = @ISNEW
AND GROUPID = @GROUPID
AND ISENABLED = @ISENABLED
AND ORDER >= @ORDER
AND ID <> @ID
END
FETCH NEXT FROM CURSOR_TIPOS_AGENDA INTO @ID, @ISOLD, @ISNEW, @GROUPID, @ORDER, @ISENABLED
END
Table数据:
ID ISOLD ISNEW GROUPID ORDER ISENABLED
1 1 0 500 1 1
2 0 0 500 1 1
3 0 0 500 1 1
新的唯一约束
CREATE UNIQUE NONCLUSTERED INDEX [XAK1_mytable] ON mytable([ORDER], [ISENABLED], [ISOLD`], [ISNEW], [GROUPID])
添加唯一约束的错误发生在 ID 为 3 的 TABLE 行中。上面的代码应使用订单 2
更新 ID 为 3 的行
但是此代码也不会更新 table 的行。有人知道如何更新游标中尚未获取的行吗?
您似乎在尝试使每组 GroupId, [Order], IsOld, IsNew, IsEnabled
的 Order
独一无二。
您可以通过使用 common table expression with row_number()
的基于集合的语句来执行此操作
;with cte as (
select
Id
, IsOld
, IsNew
, GroupId
, [Order]
, IsEnabled
, rn = row_number() over (
partition by GroupId, [Order], IsOld, IsNew, IsEnabled
order by [Order]
) - 1
from t
)
--Preview:
--/*
select *, NewOrder = [Order] + rn
from cte
where rn > 0
--*/
/*
--Update
update cte
set [Order] = [Order] + rn
where rn > 0;
--*/
您可以像这样跳过使用 cte
:
update cte
set [Order] = [Order] + rn
from (
select *
, rn = row_number() over (
partition by GroupId, [Order], IsOld, IsNew, IsEnabled
order by [Order]
) - 1
from t
) as cte
where rn > 0
对于上面给出的示例,select 代码将 return:
+----+-------+-------+---------+-------+-----------+----+----------+
| Id | IsOld | IsNew | GroupId | Order | IsEnabled | rn | NewOrder |
+----+-------+-------+---------+-------+-----------+----+----------+
| 3 | 0 | 0 | 500 | 1 | 1 | 1 | 2 |
+----+-------+-------+---------+-------+-----------+----+----------+
在 运行 更新后,table 看起来像这样:
+----+-------+-------+---------+-------+-----------+
| Id | IsOld | IsNew | GroupId | Order | IsEnabled |
+----+-------+-------+---------+-------+-----------+
| 1 | 1 | 0 | 500 | 1 | 1 |
| 2 | 0 | 0 | 500 | 1 | 1 |
| 3 | 0 | 0 | 500 | 2 | 1 |
+----+-------+-------+---------+-------+-----------+
在添加唯一约束之前,我需要更新 table 的 "Order" 列,以避免在添加约束时出错。要更新此字段,我正在尝试执行以下 T-SQL 代码:
DECLARE c_x CURSOR FOR
SELECT ID, ISOLD, ISNEW, GROUPID, ORDER, ISENABLED
FROM mytable
OPEN c_x;
FETCH NEXT FROM c_x INTO @ID, @ISOLD, @ISNEW, @GROUPID, @ORDER, @ISENABLED;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @SUMOFROWS = COUNT(*) FROM mytable
WHERE ISOLD = @ISOLD
AND ISNEW = @ISNEW
AND GROUPID = @GROUPID
AND ORDER = @ORDER
AND ISENABLED = @ISENABLED;
IF @SUMOFROWS > 1
BEGIN
UPDATE mytable
SET ORDER = ORDER+ 1
WHERE ISOLD = @ISOLD
AND ISNEW = @ISNEW
AND GROUPID = @GROUPID
AND ISENABLED = @ISENABLED
AND ORDER >= @ORDER
AND ID <> @ID
END
FETCH NEXT FROM CURSOR_TIPOS_AGENDA INTO @ID, @ISOLD, @ISNEW, @GROUPID, @ORDER, @ISENABLED
END
Table数据:
ID ISOLD ISNEW GROUPID ORDER ISENABLED
1 1 0 500 1 1
2 0 0 500 1 1
3 0 0 500 1 1
新的唯一约束
CREATE UNIQUE NONCLUSTERED INDEX [XAK1_mytable] ON mytable([ORDER], [ISENABLED], [ISOLD`], [ISNEW], [GROUPID])
添加唯一约束的错误发生在 ID 为 3 的 TABLE 行中。上面的代码应使用订单 2
更新 ID 为 3 的行但是此代码也不会更新 table 的行。有人知道如何更新游标中尚未获取的行吗?
您似乎在尝试使每组 GroupId, [Order], IsOld, IsNew, IsEnabled
的 Order
独一无二。
您可以通过使用 common table expression with row_number()
;with cte as (
select
Id
, IsOld
, IsNew
, GroupId
, [Order]
, IsEnabled
, rn = row_number() over (
partition by GroupId, [Order], IsOld, IsNew, IsEnabled
order by [Order]
) - 1
from t
)
--Preview:
--/*
select *, NewOrder = [Order] + rn
from cte
where rn > 0
--*/
/*
--Update
update cte
set [Order] = [Order] + rn
where rn > 0;
--*/
您可以像这样跳过使用 cte
:
update cte
set [Order] = [Order] + rn
from (
select *
, rn = row_number() over (
partition by GroupId, [Order], IsOld, IsNew, IsEnabled
order by [Order]
) - 1
from t
) as cte
where rn > 0
对于上面给出的示例,select 代码将 return:
+----+-------+-------+---------+-------+-----------+----+----------+
| Id | IsOld | IsNew | GroupId | Order | IsEnabled | rn | NewOrder |
+----+-------+-------+---------+-------+-----------+----+----------+
| 3 | 0 | 0 | 500 | 1 | 1 | 1 | 2 |
+----+-------+-------+---------+-------+-----------+----+----------+
在 运行 更新后,table 看起来像这样:
+----+-------+-------+---------+-------+-----------+
| Id | IsOld | IsNew | GroupId | Order | IsEnabled |
+----+-------+-------+---------+-------+-----------+
| 1 | 1 | 0 | 500 | 1 | 1 |
| 2 | 0 | 0 | 500 | 1 | 1 |
| 3 | 0 | 0 | 500 | 2 | 1 |
+----+-------+-------+---------+-------+-----------+