Con*_*ger 111 sql t-sql sql-server
我们有一个5GB的表(接近5亿行),我们想删除其中一个列上的标识属性,但是当我们尝试通过SSMS执行此操作时 - 它会超时.
这可以通过T-SQL完成吗?
Ada*_*ger 126
IDENTITY
一旦设置,您就无法删除规范.
要删除整个列:
ALTER TABLE yourTable
DROP COLUMN yourCOlumn;
Run Code Online (Sandbox Code Playgroud)
有关ALTER TABLE的信息
如果您需要保留数据,但删除IDENTITY
列,则需要:
IDENTITY
列传输到新列IDENTITY
列.Mar*_*wul 81
如果您想在不添加和填充新列的情况下执行此操作,而无需重新排序列,并且几乎没有停机时间,因为表上没有数据发生变化,让我们使用分区功能做一些魔术(但由于没有使用分区,所以不要需要企业版):
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';
Run Code Online (Sandbox Code Playgroud)
您可以执行以下操作:
--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
IF NOT EXISTS (SELECT * FROM Original) 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;
Run Code Online (Sandbox Code Playgroud)
Bri*_*y37 58
这会受到外键和主键约束的影响,所以这里有一些脚本可以帮助你:
首先,创建一个具有临时名称的重复列:
alter table yourTable add tempId int NOT NULL default -1;
update yourTable set tempId = id;
Run Code Online (Sandbox Code Playgroud)
接下来,获取主键约束的名称:
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'yourTable';
Run Code Online (Sandbox Code Playgroud)
现在尝试删除列的主键约束:
ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
Run Code Online (Sandbox Code Playgroud)
如果你有外键,它将失败,所以如果这样,删除外键约束. 保持记录,你可以运行这个,因为你可以在以后加入限制!
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'otherTable';
alter table otherTable drop constraint fk_otherTable_yourTable;
commit;
..
Run Code Online (Sandbox Code Playgroud)
删除所有外键约束后,您将能够删除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;
Run Code Online (Sandbox Code Playgroud)
最后,添加FK约束:
alter table otherTable add constraint fk_otherTable_yourTable foreign key (yourTable_id) references yourTable(id);
..
Run Code Online (Sandbox Code Playgroud)
El Fin!
小智 17
我刚遇到同样的问题.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';
blu*_*dot 10
以下脚本删除名为"Id"的列的标识字段
希望能帮助到你.
BEGIN TRAN
BEGIN TRY
EXEC sp_rename '[SomeTable].[Id]', 'OldId';
ALTER TABLE [SomeTable] ADD Id int NULL
EXEC ('UPDATE [SomeTable] SET Id = OldId')
ALTER TABLE [SomeTable] NOCHECK CONSTRAINT ALL
ALTER TABLE [SomeTable] DROP CONSTRAINT [PK_constraintName];
ALTER TABLE [SomeTable] DROP COLUMN OldId
ALTER TABLE [SomeTable] ALTER COLUMN [Id] INTEGER NOT NULL
ALTER TABLE [SomeTable] ADD CONSTRAINT PK_JobInfo PRIMARY KEY (Id)
ALTER TABLE [SomeTable] CHECK CONSTRAINT ALL
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
SELECT ERROR_MESSAGE ()
END CATCH
Run Code Online (Sandbox Code Playgroud)
当我们不知道标识列名称时,波纹管代码可以正常工作。
需要将数据复制到新的临时表中,例如Invoice_DELETED
. 下次我们使用:
insert into Invoice_DELETED select * from Invoice where ...
SELECT t1.*
INTO Invoice_DELETED
FROM Invoice t1
LEFT JOIN Invoice ON 1 = 0
--WHERE t1.InvoiceID = @InvoiceID
Run Code Online (Sandbox Code Playgroud)
更多解释请参见:https : //dba.stackexchange.com/a/138345/101038
小智 5
在 SQL Server 中,您可以像这样打开和关闭身份插入:
SET IDENTITY_INSERT 表名 ON
-- 在这里运行您的查询
SET IDENTITY_INSERT 表名 OFF
归档时间: |
|
查看次数: |
252788 次 |
最近记录: |