是的,我非常清楚后果。但我只想重新排序。从1开始到结束。
如何使用单个查询重新排序键?
它是聚集的主键索引
重新排序
First record Id 1
second record Id 2
主键是 Int
是的,我非常清楚后果。但我只想重新排序。从1开始到结束。
如何使用单个查询重新排序键?
它是聚集的主键索引
重新排序
First record Id 1
second record Id 2
主键是 Int
USE Test
go
if(object_id('IdentityTest') Is not null)
drop table IdentityTest
create table IdentityTest
(
Id int identity not null,
Name varchar(5),
constraint pk primary key (Id)
)
set identity_insert dbo.IdentityTest ON
insert into dbo.IdentityTest (Id,Name) Values(23,'A'),(26,'B'),(34,'C'),(35,'D'),(40,'E')
set identity_insert dbo.IdentityTest OFF
select * from IdentityTest
------------------1. Drop PK constraint ------------------------------------
ALTER TABLE [dbo].[IdentityTest] DROP CONSTRAINT [pk]
GO
------------------2. Drop Identity column -----------------------------------
ALTER table dbo.IdentityTest
drop column Id
------------------3. Re-create Identity Column -----------------------------------
ALTER table dbo.IdentityTest
add Id int identity(1,1)
-------------------4. Re-Create PK-----------------------
ALTER TABLE [dbo].[IdentityTest] ADD CONSTRAINT [pk] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
--------------------------------------------------------------
insert into dbo.IdentityTest (Name) Values('F')
select * from IdentityTest
IDENTITY
columns are not updatable irrespective of SET IDENTITY_INSERT
options.
You could create a shadow table with the same definition as the original except for the IDENTITY
property. Switch into that (this is a metadata only change with no movement of rows that just affects the table's definition) then update the rows and switch back though.
A full worked example going from a situation with gaps to no gaps is shown below (error handling and transactions are omitted below for brevity).
/*Your original table*/
CREATE TABLE YourTable
(
Id INT IDENTITY PRIMARY KEY,
OtherColumns CHAR(100) NULL
)
/*Some dummy data*/
INSERT INTO YourTable (OtherColumns) VALUES ('A'),('B'),('C')
/*Delete a row leaving a gap*/
DELETE FROM YourTable WHERE Id =2
/*Verify there is a gap*/
SELECT *
FROM YourTable
/*Create table with same definition as original but no `IDENTITY`*/
CREATE TABLE ShadowTable
(
Id INT PRIMARY KEY,
OtherColumns CHAR(100)
)
/*1st metadata switch*/
ALTER TABLE YourTable SWITCH TO ShadowTable;
/*Do the update*/
WITH CTE AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY Id) AS RN
FROM ShadowTable
)
UPDATE CTE SET Id = RN
/*Metadata switch back to restore IDENTITY property*/
ALTER TABLE ShadowTable SWITCH TO YourTable;
/*Remove unneeded table*/
DROP TABLE ShadowTable;
/*No Gaps*/
SELECT *
FROM YourTable
CREATE TABLE Table1_Stg (bla bla bla)
INSERT INTO Table1_Stg (Column2, Column3,...) SELECT Column2, Column3,... FROM Table1 ORDER BY Id
这里 Id 列从 SELECT 列列表中排除。
或者,您可以这样做:
SELECT * INTO Table1_Stg FROM Table1 ORDER BY Id
DROP Table1
sp_rename Table1_stg Table1
当我从内存中执行此操作时,请查找 sp_rename 的用法。
希望这可以帮助。
编辑:如果Table1上有任何索引和约束,请保存一个脚本。
EDIT2:添加了创建表和插入表的第二种方法。
UPDATE tbl SET id = (SELECT COUNT(*) FROM tbl t WHERE t.id <= tbl.id);
我认为没有任何方法可以在单个查询中执行此操作。您最好的选择是将数据复制到新表,删除并重新创建原始表(或删除数据并重新设定身份)并使用先前的身份作为排序以原始顺序重新插入数据(但不重新插入它)。
最后这句话是天才。只需首先从表设计中删除主键,并确保在设计选项下标识规范设置为否。运行查询后,请重新设置这些选项。