我们有一个5GB的表(接近5亿行),我们想删除其中一个列上的标识属性,但是当我们尝试通过SSMS执行此操作时 - 它会超时。
可以通过T-SQL完成吗?
答案 0 :(得分:117)
设置后,您无法删除IDENTITY
规范。
要删除整个列:
ALTER TABLE yourTable
DROP COLUMN yourCOlumn;
有关此处ALTER TABLE的信息
如果您需要保留数据,但删除IDENTITY
列,则需要:
IDENTITY
列转移到新列IDENTITY
列。答案 1 :(得分:67)
如果你想这样做而不添加和填充新列,而不重新排序列,几乎没有停机时间,因为没有数据在桌面上发生变化,让我们通过分区功能做一些魔术(但由于没有使用分区,因此您不需要企业版):
ALTER TABLE [Original] SWITCH TO [Original2]
exec sys.sp_rename
,将各种模式对象重命名为原始名称,然后重新创建外键。例如,给定:
CREATE TABLE Original
(
Id INT IDENTITY PRIMARY KEY
, Value NVARCHAR(300)
);
CREATE NONCLUSTERED INDEX IX_Original_Value ON Original (Value);
INSERT INTO Original
SELECT 'abcd'
UNION ALL
SELECT 'defg';
您可以执行以下操作:
--create new table with no IDENTITY
CREATE TABLE Original2
(
Id INT PRIMARY KEY
, Value NVARCHAR(300)
);
CREATE NONCLUSTERED INDEX IX_Original_Value2 ON Original2 (Value);
--data before switch
SELECT 'Original', *
FROM Original
UNION ALL
SELECT 'Original2', *
FROM Original2;
ALTER TABLE Original SWITCH TO Original2;
--data after switch
SELECT 'Original', *
FROM Original
UNION ALL
SELECT 'Original2', *
FROM Original2;
--clean up
DROP TABLE Original;
EXEC sys.sp_rename 'Original2.IX_Original_Value2', 'IX_Original_Value', 'INDEX';
EXEC sys.sp_rename 'Original2', 'Original', 'OBJECT';
UPDATE Original
SET Id = Id + 1;
SELECT *
FROM Original;
答案 2 :(得分:57)
这会受到外键和主键约束的影响,所以这里有一些脚本可以帮助你:
首先,创建一个带有临时名称的重复列:
alter table yourTable add tempId int NOT NULL default -1;
update yourTable set tempId = id;
接下来,获取主键约束的名称:
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'yourTable';
现在尝试删除列的主键约束:
ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
如果你有外键,它将失败,所以如果这样,则删除外键约束。 保持记录表明你已经开始运行,因为你可以在以后加入限制条件!!!
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'otherTable';
alter table otherTable drop constraint fk_otherTable_yourTable;
commit;
..
删除所有外键约束后,您将能够删除PK约束,删除该列,重命名临时列,并将PK约束添加到该列:
ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
alter table yourTable drop column id;
EXEC sp_rename 'yourTable.tempId', 'id', 'COLUMN';
ALTER TABLE yourTable ADD CONSTRAINT PK_yourTable_id PRIMARY KEY (id)
commit;
最后,将FK约束添加回来:
alter table otherTable add constraint fk_otherTable_yourTable foreign key (yourTable_id) references yourTable(id);
..
El Fin!
答案 3 :(得分:16)
我刚遇到同样的问题。 SSMS中的4个语句,而不是使用GUI,速度非常快。
制作新专栏
alter table users add newusernum int;
复制值
update users set newusernum=usernum;
删除旧列
alter table users drop column usernum;
将新列重命名为旧列名称
EXEC sp_RENAME 'users.newusernum' , 'usernum', 'COLUMN';
答案 4 :(得分:10)
以下脚本会删除名为' Id'
的列的标识字段希望它有所帮助。
Parcelable
答案 5 :(得分:3)
Bellow代码工作正常,当我们不知道标识列名称时。
并希望将数据复制到新的临时表中,例如Invoice_DELETED。 下次我们使用:插入Invoice_DELETED select * from Invoice where ...
SELECT t1.*
INTO Invoice_DELETED
FROM Invoice t1
LEFT JOIN Invoice ON 1 = 0
--WHERE t1.InvoiceID = @InvoiceID
特别感谢'Andriy M'
有关详细说明,请参阅: https://dba.stackexchange.com/a/138345/101038
答案 6 :(得分:1)
ALTER TABLE tablename add newcolumn int
update tablename set newcolumn=existingcolumnname
ALTER TABLE tablename DROP COLUMN existingcolumnname;
EXEC sp_RENAME 'tablename.oldcolumn' , 'newcolumnname', 'COLUMN'
但是以上代码仅在没有主外键关系的情况下有效
答案 7 :(得分:0)
对于那些遇到同样问题的人。 如果你只是想做一些插入只是你可以做这样的事情。
假设您有一个包含两列的表
ID Identity (1,1) | Name Varchar
并且想要插入ID = 4的行。所以你将它重新设置为3,以便下一个是4
DBCC CHECKIDENT([YourTable], RESEED, 3)
制作插页
INSERT INTO [YourTable]
( Name )
VALUES ( 'Client' )
让你的种子回到最高ID,假设是15
DBCC CHECKIDENT([YourTable], RESEED, 15)
完成!
答案 8 :(得分:0)
我有同样的要求,你可以尝试这种方式,我个人推荐你,请手动设计你的表并生成脚本,我在下面做的是重命名旧表以及它的备份约束。 / p>
/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.SI_Provider_Profile
DROP CONSTRAINT DF_SI_Provider_Profile_SIdtDateTimeStamp
GO
ALTER TABLE dbo.SI_Provider_Profile
DROP CONSTRAINT DF_SI_Provider_Profile_SIbHotelPreLoaded
GO
CREATE TABLE dbo.Tmp_SI_Provider_Profile
(
SI_lProvider_Profile_ID int NOT NULL,
SI_lSerko_Integrator_Token_ID int NOT NULL,
SI_sSerko_Integrator_Provider varchar(50) NOT NULL,
SI_sSerko_Integrator_Profile varchar(50) NOT NULL,
SI_dtDate_Time_Stamp datetime NOT NULL,
SI_lProvider_ID int NULL,
SI_sDisplay_Name varchar(10) NULL,
SI_lPurchased_From int NULL,
SI_sProvider_UniqueID varchar(255) NULL,
SI_bHotel_Pre_Loaded bit NOT NULL,
SI_sSiteName varchar(255) NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile SET (LOCK_ESCALATION = TABLE)
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile ADD CONSTRAINT
DF_SI_Provider_Profile_SIdtDateTimeStamp DEFAULT (getdate()) FOR SI_dtDate_Time_Stamp
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile ADD CONSTRAINT
DF_SI_Provider_Profile_SIbHotelPreLoaded DEFAULT ((0)) FOR SI_bHotel_Pre_Loaded
GO
IF EXISTS(SELECT * FROM dbo.SI_Provider_Profile)
EXEC('INSERT INTO dbo.Tmp_SI_Provider_Profile (SI_lProvider_Profile_ID, SI_lSerko_Integrator_Token_ID, SI_sSerko_Integrator_Provider, SI_sSerko_Integrator_Profile, SI_dtDate_Time_Stamp, SI_lProvider_ID, SI_sDisplay_Name, SI_lPurchased_From, SI_sProvider_UniqueID, SI_bHotel_Pre_Loaded, SI_sSiteName)
SELECT SI_lProvider_Profile_ID, SI_lSerko_Integrator_Token_ID, SI_sSerko_Integrator_Provider, SI_sSerko_Integrator_Profile, SI_dtDate_Time_Stamp, SI_lProvider_ID, SI_sDisplay_Name, SI_lPurchased_From, SI_sProvider_UniqueID, SI_bHotel_Pre_Loaded, SI_sSiteName FROM dbo.SI_Provider_Profile WITH (HOLDLOCK TABLOCKX)')
GO
-- Rename the primary key constraint or unique key In SQL Server constraints such as primary keys or foreign keys are objects in their own right, even though they are dependent upon the "containing" table.
EXEC sp_rename 'dbo.SI_Provider_Profile.PK_SI_Provider_Profile', 'PK_SI_Provider_Profile_Old';
GO
-- backup old table in case of
EXECUTE sp_rename N'dbo.SI_Provider_Profile', N'SI_Provider_Profile_Old', 'OBJECT'
GO
EXECUTE sp_rename N'dbo.Tmp_SI_Provider_Profile', N'SI_Provider_Profile', 'OBJECT'
GO
ALTER TABLE dbo.SI_Provider_Profile ADD CONSTRAINT
PK_SI_Provider_Profile PRIMARY KEY NONCLUSTERED
(
SI_lProvider_Profile_ID
) WITH( PAD_INDEX = OFF, FILLFACTOR = 90, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT TRANSACTION
答案 9 :(得分:0)
在SQL Server中,您可以像这样打开和关闭标识插入:
SET IDENTITY_INSERT table_name开启
-在此处运行查询
SET IDENTITY_INSERT table_name关闭
答案 10 :(得分:-1)
ALTER TABLE TABLE_NAME MODIFY (COLUMN_NAME DROP IDENTITY);