我想通过批量更新来更改表的序列。
由于更新不包含order by,我使用了CTE,with子句,制作了数据集并对结果发布了更新,期望它会按照我的意愿执行。
但它不是由我订购的套装更新
这次更新出了什么问题?
CREATE TABLE [dbo].[Test](
[Id] [int] NOT NULL,
[Serial] [nvarchar](10) NOT NULL
)
insert into Test values
(1, 1001),
(2, 1002),
(3, 1003),
(4, 1004),
(5, 1005),
(6, 1006),
(7, 1003)
declare @serial int, @Id int
set @Id =3
select @serial = Serial from Test WHERE Id=@Id
declare @new_serial nvarchar(10);
select @new_serial = cast(@serial as nvarchar(10));
;with Records as
(
Select Id, Serial
, ROW_NUMBER() over
(
order by serial
) as RN
FROM [Test]
where Id>@Id
)
UPDATE Records set
[Serial] = cast(@new_serial as int),
@new_serial = cast(@new_serial as int)+1
以下是插入后的内容:
+--+----+
|1 |1001|
|2 |1002|
|3 |1003|
|4 |1004|
|5 |1005|
|6 |1006|
|7 |1003|
以下是我们的需求:
+--+----+
|1 |1001|
|2 |1002|
|3 |1003|
|4 |1005|
|5 |1006|
|6 |1007|
|7 |1004|
答案 0 :(得分:1)
您的更新声明有误。您正在更新cte,然后将值设置为局部变量。我猜你期望更新将逐行执行,从而将每行Serial
的值设置为前一个值+ 1.但是,这不是sql的工作方式。
要从您提供的输入中获得所需的输出,您不需要cte,也不需要使用row_number
。你可以这样做:
DECLARE @Id int = 3
UPDATE Test
SET [Serial] = cast(Serial as int) + 1
WHERE Id > @Id
检查:
SELECT Id, Serial
FROM Test
结果:
Id Serial
1 1001
2 1002
3 1003
4 1005
5 1006
6 1007
7 1004
答案 1 :(得分:1)
您可以先计算表格中的行数,然后使用变量或为TOP选择一个大数字来选择整个表格,然后按顺序排序:
;with Records as
(
Select TOP 100000
Id
, Serial
FROM [Test]
where Id>@Id
ORDER BY Serial
)
答案 2 :(得分:0)
但它不是由我的有序集更新。这有什么问题 更新
您的代码中没有有序集。 CTE不是也不能“订购”。
您应该在更新中使用计算出的RN,否则,您的代码根本不依赖于row_number():
public sealed partial class MainPage : Page
{
ObservableCollection<Data> Products;
public MainPage()
{
this.InitializeComponent();
Products = new ObservableCollection<Data>()
{
new Data { Product = "Milk", Stock = true },
new Data { Product = "Cheese", Stock = false },
new Data { Product = "Bread", Stock = false },
new Data { Product = "Chocolate", Stock = true }
};
this.DataContext = Products;
}
}
public class Data
{
public string Product { get; set; }
public bool Stock { get; set; }
}