Kami memiliki tabel 5GB (hampir 500 juta baris) dan kami ingin menghapus properti identitas di salah satu kolom, tetapi ketika kami mencoba melakukan ini melalui SSMS - waktu habis.
Bisakah ini dilakukan melalui T-SQL?
Kami memiliki tabel 5GB (hampir 500 juta baris) dan kami ingin menghapus properti identitas di salah satu kolom, tetapi ketika kami mencoba melakukan ini melalui SSMS - waktu habis.
Bisakah ini dilakukan melalui T-SQL?
Jawaban:
Anda tidak dapat menghapus IDENTITY
spesifikasi setelah disetel.
Untuk menghapus seluruh kolom:
ALTER TABLE yourTable
DROP COLUMN yourCOlumn;
Informasi tentang ALTER TABLE di sini
Jika Anda perlu menyimpan data, tetapi menghapus IDENTITY
kolomnya, Anda perlu:
IDENTITY
kolom yang ada ke kolom baruIDENTITY
kolom yang ada .identity
kolom ini digunakan sebagai bagian dari a foreign key
di tabel lain, Anda harus menghapus pembatas terlebih dahulu, lalu mengambil tindakan seperti yang disebutkan @AdamWenger tentang penghapusan identitas attribute/property
.. Anda juga dapat melihat link ini untuk lebih jelasnya tentang menghapus atribut saja: blog.sqlauthority.com/2009/05/03/… ..Semoga berhasil!
Jika Anda ingin melakukan ini tanpa menambah dan mengisi kolom baru , tanpa menyusun ulang kolom , dan hampir tidak ada waktu henti karena tidak ada data yang berubah pada tabel, mari lakukan keajaiban dengan fungsionalitas partisi (tetapi karena tidak ada partisi yang digunakan, Anda tidak akan melakukannya) t perlu edisi Enterprise):
ALTER TABLE [Original] SWITCH TO [Original2]
exec sys.sp_rename
untuk mengganti nama berbagai objek skema kembali ke nama aslinya, dan kemudian Anda dapat membuat ulang kunci asing Anda.Misalnya, diberikan:
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';
Anda dapat melakukan hal berikut:
--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;
Ini menjadi berantakan dengan kendala kunci asing dan kunci utama, jadi inilah beberapa skrip untuk membantu Anda dalam perjalanan:
Pertama, buat kolom duplikat dengan nama sementara:
alter table yourTable add tempId int NOT NULL default -1;
update yourTable set tempId = id;
Selanjutnya, dapatkan nama batasan kunci utama Anda:
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'yourTable';
Sekarang coba lepaskan kendala kunci utama untuk kolom Anda:
ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
Jika Anda memiliki kunci asing, itu akan gagal, jadi jika demikian jatuhkan batasan kunci asing. TERUS LACAK DARI TABEL YANG ANDA JALANKAN INI SEHINGGA ANDA DAPAT MENAMBAHKAN BATAS KEMBALI DI NANTI !!!
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'otherTable';
alter table otherTable drop constraint fk_otherTable_yourTable;
commit;
..
Setelah semua batasan kunci asing Anda dihapus, Anda akan dapat menghapus batasan PK, menghapus kolom itu, mengganti nama kolom temp Anda, dan menambahkan batasan PK ke kolom itu:
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;
Terakhir, tambahkan kembali batasan FK:
alter table otherTable add constraint fk_otherTable_yourTable foreign key (yourTable_id) references yourTable(id);
..
El Fin!
Select t.name 'Table', i.name 'Index', c.name 'Column', i.is_primary_key, i.is_unique From sys.tables t Inner Join sys.indexes i On i.object_id = t.object_id Inner Join sys.index_columns ic ON ic.object_id = i.object_id And i.index_id = ic.index_id Inner Join sys.columns c ON ic.object_id = c.object_id and ic.column_id = c.column_id Where t.name = 'tableName' Order By t.name, i.name, i.index_id, ic.index_column_id
Saya baru saja mengalami masalah yang sama. 4 pernyataan di SSMS daripada menggunakan GUI dan itu sangat cepat.
Buat kolom baru
alter table users add newusernum int;
Salin nilai
update users set newusernum=usernum;
Jatuhkan kolom lama
alter table users drop column usernum;
Ubah nama kolom baru menjadi nama kolom lama
EXEC sp_RENAME 'users.newusernum' , 'usernum', 'COLUMN';
Skrip berikut menghapus bidang Identitas untuk kolom bernama 'Id'
Semoga membantu.
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
Kode di bawah berfungsi dengan baik, ketika kita tidak tahu nama kolom identitas .
Perlu menyalin data ke tabel temp baru seperti Invoice_DELETED
. dan lain kali kami menggunakan:
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
Untuk penjelasan lebih lanjut lihat: https://dba.stackexchange.com/a/138345/101038
ALTER TABLE tablename add newcolumn int
update tablename set newcolumn=existingcolumnname
ALTER TABLE tablename DROP COLUMN existingcolumnname;
EXEC sp_RENAME 'tablename.oldcolumn' , 'newcolumnname', 'COLUMN'
Namun kode di atas hanya berfungsi jika tidak ada hubungan kunci asing-primer
Hanya untuk seseorang yang memiliki masalah yang sama dengan saya. Jika Anda hanya ingin membuat beberapa penyisipan sekali saja, Anda dapat melakukan sesuatu seperti ini.
Misalkan Anda memiliki tabel dengan dua kolom
ID Identity (1,1) | Name Varchar
dan ingin menyisipkan baris dengan ID = 4. Jadi Anda Ulangi ke 3 jadi yang berikutnya adalah 4
DBCC CHECKIDENT([YourTable], RESEED, 3)
Buat Sisipan
INSERT INTO [YourTable]
( Name )
VALUES ( 'Client' )
Dan dapatkan seed Anda kembali ke ID tertinggi, misalkan adalah 15
DBCC CHECKIDENT([YourTable], RESEED, 15)
Selesai!
Saya memiliki persyaratan yang sama, dan Anda dapat mencoba cara ini, yang secara pribadi saya rekomendasikan, desain tabel Anda secara manual dan buat skripnya, dan apa yang saya lakukan di bawah ini adalah mengganti nama tabel lama dan juga batasannya untuk cadangan.
/* 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
Di SQL Server, Anda dapat mengaktifkan dan menonaktifkan penyisipan identitas seperti ini:
SET IDENTITY_INSERT table_name ON
- jalankan pertanyaan Anda di sini
NONAKTIFKAN nama_tabel IDENTITY_INSERT