Menambahkan identitas ke kolom yang ada

445

Saya perlu mengubah kunci utama tabel ke kolom identitas, dan sudah ada sejumlah baris dalam tabel.

Saya punya skrip untuk membersihkan ID untuk memastikan mereka berurutan mulai dari 1, berfungsi dengan baik pada database pengujian saya.

Apa perintah SQL untuk mengubah kolom untuk memiliki properti identitas?

Kirschstein
sumber

Jawaban:

482

Anda tidak dapat mengubah kolom yang ada untuk identitas.

Anda memiliki 2 opsi,

  1. Buat tabel baru dengan identitas & jatuhkan tabel yang ada

  2. Buat kolom baru dengan identitas & jatuhkan kolom yang ada

Pendekatan 1. ( Tabel baru ) Di sini Anda dapat menyimpan nilai data yang ada di kolom identitas yang baru dibuat.

CREATE TABLE dbo.Tmp_Names
    (
      Id int NOT NULL
             IDENTITY(1, 1),
      Name varchar(50) NULL
    )
ON  [PRIMARY]
go

SET IDENTITY_INSERT dbo.Tmp_Names ON
go

IF EXISTS ( SELECT  *
            FROM    dbo.Names ) 
    INSERT  INTO dbo.Tmp_Names ( Id, Name )
            SELECT  Id,
                    Name
            FROM    dbo.Names TABLOCKX
go

SET IDENTITY_INSERT dbo.Tmp_Names OFF
go

DROP TABLE dbo.Names
go

Exec sp_rename 'Tmp_Names', 'Names'

Pendekatan 2 ( Kolom baru ) Anda tidak dapat mempertahankan nilai data yang ada pada kolom identitas yang baru dibuat, kolom identitas akan menyimpan urutan angka.

Alter Table Names
Add Id_new Int Identity(1, 1)
Go

Alter Table Names Drop Column ID
Go

Exec sp_rename 'Names.Id_new', 'ID', 'Column'

Lihat posting Forum Microsoft SQL Server berikut untuk detail lebih lanjut:

Bagaimana mengubah kolom menjadi identitas (1,1)

John Sansom
sumber
49
Jika data tabel kecil, opsi ini berfungsi baik. Jika tabel besar, ada opsi lain yang saya sukai: gunakan ALTER TABLE ... SWITCH untuk mengganti skema tabel dengan versi lain dengan kolom IDENTITAS tetapi skema yang identik. Keuntungan dari ALTER TABLE .... Pendekatan SWITCH adalah ia menyelesaikan dengan cepat (di bawah 5 detik untuk satu miliar baris tabel) karena tidak ada data tabel yang perlu disalin atau diubah. Ada peringatan dan batasannya. Lihat jawaban saya di bawah untuk detailnya.
Justin Grant
7
@Justin Grat: Alternatif yang sangat menarik dan satu yang belum saya pertimbangkan! Alasan ini berhasil adalah karena IDENTITY adalah properti kolom dan bukan tipe data, sehingga metode SWITCH memvalidasi skema antara dua tabel (lama dan baru) sebagai dapat diidentifikasi terlepas dari perbedaan IDENTITAS. Terima kasih telah berbagi!
John Sansom
Jika Anda tidak memiliki banyak data, maka "membuat tabel" dapat dicapai dengan membuat skrip dari SSMS. Klik kanan tabel> Skrip Tabel sebagai> Buat TABEL ke> (editor kueri baru?). Lalu jatuhkan, dan di dalam skrip itu Anda dapat menambahkan IDENTITY(1, 1)bagian dengan kolom kunci utama
goamn
Satu juga dapat menggunakan SSMS untuk menegakkan ini. Buka Alat> Opsi> Desainer> Hapus centang "Cegah penyimpanan perubahan yang memerlukan pembuatan ulang tabel". BTW ini tidak direkomendasikan untuk tabel yang cukup besar.
Zafar
Di PostgreSQL Anda dapat menambahkan identitas ke kolom bilangan bulat yang ada dengan perintah: alter table {table_name} ubah kolom {column_name} tambah selalu dihasilkan sebagai identitas (mulai ulang dengan {number});
Andrew Mackie
209

Di SQL 2005 dan di atas, ada trik untuk menyelesaikan masalah ini tanpa mengubah halaman data tabel. Ini penting untuk tabel besar di mana menyentuh setiap halaman data dapat memakan waktu beberapa menit atau jam. Triknya juga berfungsi bahkan jika kolom identitas adalah kunci utama, adalah bagian dari indeks berkerumun atau tidak berkerumun, atau gotcha lainnya yang dapat meningkatkan solusi "tambah / hapus / ganti nama kolom" yang lebih sederhana.

Inilah triknya: Anda dapat menggunakan ALTER TABLE SQL Server ... Pernyataan SWITCH untuk mengubah skema tabel tanpa mengubah data, artinya Anda bisa mengganti tabel dengan IDENTITAS dengan skema tabel yang identik, tetapi tanpa kolom IDENTITAS. Trik yang sama berfungsi untuk menambahkan IDENTITAS ke kolom yang ada.

Biasanya, ALTER TABLE ... SWITCH digunakan untuk secara efisien mengganti partisi penuh dalam tabel dipartisi dengan partisi kosong baru. Tetapi juga bisa digunakan dalam tabel non-partisi juga.

Saya telah menggunakan trik ini untuk mengonversi, dalam waktu kurang dari 5 detik, kolom dari tabel baris 2,5 miliar dari IDENTITY ke non-IDENTITY (untuk menjalankan kueri multi-jam yang rencana kuerinya bekerja lebih baik untuk non-IDENTITY kolom), dan kemudian mengembalikan pengaturan IDENTITY, lagi dalam waktu kurang dari 5 detik.

Berikut ini contoh kode cara kerjanya.

 CREATE TABLE Test
 (
   id int identity(1,1),
   somecolumn varchar(10)
 );

 INSERT INTO Test VALUES ('Hello');
 INSERT INTO Test VALUES ('World');

 -- copy the table. use same schema, but no identity
 CREATE TABLE Test2
 (
   id int NOT NULL,
   somecolumn varchar(10)
 );

 ALTER TABLE Test SWITCH TO Test2;

 -- drop the original (now empty) table
 DROP TABLE Test;

 -- rename new table to old table's name
 EXEC sp_rename 'Test2','Test';

 -- update the identity seed
 DBCC CHECKIDENT('Test');

 -- see same records
 SELECT * FROM Test; 

Ini jelas lebih terlibat daripada solusi dalam jawaban lain, tetapi jika meja Anda besar ini bisa menjadi penyelamat nyata. Ada beberapa peringatan:

  • Sejauh yang saya tahu, identitas adalah satu-satunya hal yang dapat Anda ubah tentang kolom tabel Anda dengan metode ini. Menambahkan / menghapus kolom, mengubah nullability, dll. Tidak diperbolehkan.
  • Anda harus melepaskan kunci foriegn sebelum Anda beralih dan mengembalikannya setelah.
  • Sama dengan fungsi, tampilan, dll.
  • indeks tabel baru harus sama persis (kolom yang sama, urutan yang sama, dll.)
  • Tabel lama dan baru harus berada di filegroup yang sama.
  • Hanya berfungsi di SQL Server 2005 atau lebih baru
  • Saya sebelumnya percaya bahwa trik ini hanya berfungsi pada edisi SQL Server untuk Enterprise atau Developer (karena partisi hanya didukung di versi Enterprise dan Developer), tetapi Mason G. Zhwiti dalam komentarnya di bawah mengatakan bahwa trik ini juga berfungsi dalam SQL Standard Edition. Saya berasumsi ini berarti bahwa pembatasan untuk Perusahaan atau Pengembang tidak berlaku untuk ALTER TABLE ... SWITCH.

Ada artikel bagus tentang TechNet yang merinci persyaratan di atas.

UPDATE - Eric Wu punya komentar di bawah ini yang menambahkan info penting tentang solusi ini. Menyalinnya di sini untuk memastikannya mendapat lebih banyak perhatian:

Ada peringatan lain di sini yang layak disebut. Meskipun tabel baru akan dengan senang hati menerima data dari tabel lama, dan semua baris baru akan dimasukkan mengikuti pola identitas, mereka akan mulai dari 1 dan berpotensi pecah jika kolom tersebut adalah kunci utama. Pertimbangkan menjalankan DBCC CHECKIDENT('<newTableName>')segera setelah beralih. Lihat msdn.microsoft.com/en-us/library/ms176057.aspx untuk info lebih lanjut.

Jika tabel diperpanjang secara aktif dengan baris baru (artinya Anda tidak memiliki banyak jika ada waktu henti antara menambahkan IDENTITY dan menambahkan baris baru, maka alih-alih DBCC CHECKIDENTAnda akan ingin menetapkan nilai seed identitas secara manual dalam skema tabel baru menjadi lebih besar dari ID terbesar yang ada dalam tabel, mis IDENTITY (2435457, 1). Anda mungkin dapat memasukkan transaksi ALTER TABLE...SWITCHdan yang DBCC CHECKIDENTdalam (atau tidak - belum menguji ini) tetapi sepertinya menetapkan nilai seed secara manual akan lebih mudah dan aman.

Jelas, jika tidak ada baris baru yang ditambahkan ke tabel (atau mereka hanya ditambahkan sesekali, seperti proses ETL harian) maka kondisi balapan ini tidak akan terjadi, jadi DBCC CHECKIDENTtidak masalah.

Justin Grant
sumber
5
Jika ingatan saya benar, saya mendapat ide dari artikel ini: sqlservercentral.com/articles/T-SQL/61979
Justin Grant
2
FYI, ini tampaknya juga berfungsi pada versi standar SQL 2008 R2. Mungkin mereka mengaktifkan fitur ini seperti sekarang mereka telah mengaktifkan kemampuan untuk mengaktifkan kompresi cadangan.
Mason G. Zhwiti
3
@ jbatista - pertanyaan OP menyatakan bahwa dia sudah memiliki kunci utama di atas meja dan sudah dapat memastikan nilai yang benar, tetapi dia hanya ingin mengubahnya menjadi kolom IDENTITAS. Jawaban saya di atas terfokus pada kasus penggunaan yang sempit: bagaimana cara menambahkan IDENTITY ke kolom tanpa benar-benar mengubah data apa pun. Pendekatan yang saya dokumentasikan di atas adalah penghemat waktu yang sangat besar untuk tabel besar. Jika Anda perlu mengubah data, maka Anda harus menggunakan solusi lain.
Justin Grant
3
Ada peringatan lain di sini yang layak disebut. Meskipun tabel baru akan dengan senang hati menerima data dari tabel lama, dan semua baris baru akan dimasukkan mengikuti pola identitas, mereka akan mulai dari 1 dan berpotensi pecah jika kolom tersebut adalah kunci utama. Pertimbangkan menjalankan DBCC CHECKIDENT('<newTableName>')segera setelah beralih. Lihat msdn.microsoft.com/en-us/library/ms176057.aspx untuk info lebih lanjut.
Eric Wu
3
Ini jawaban yang bagus! Perhatikan juga bahwa nullability kolom harus sama. Jadi, jika Anda perlu mengubah nullability kolom, Anda harus melakukannya di langkah selanjutnya. Hal yang sama berlaku untuk kendala PK. Saya juga mengubah nilai identitas dalam pembuatan tabel agar sesuai dengan maksimum saat ini: IDENTITY (maksimal +1, 1)
Philippe
71

Anda tidak dapat mengubah kolom menjadi kolom IDENTITAS. Yang perlu Anda lakukan adalah membuat kolom baru yang didefinisikan sebagai IDENTITAS dari awal, lalu letakkan kolom lama, dan ganti nama yang baru dengan nama lama.

ALTER TABLE (yourTable) ADD NewColumn INT IDENTITY(1,1)

ALTER TABLE (yourTable) DROP COLUMN OldColumnName

EXEC sp_rename 'yourTable.NewColumn', 'OldColumnName', 'COLUMN'

Marc

marc_s
sumber
Parameter \ @objname tidak jelas atau diklaim \ @objtype (COLUMN) salah.
Jenny O'Reilly
1
@ JennyO'Reilly: masukkan itu ke pertanyaan yang terpisah, dan tunjukkan kami perintah lengkap yang Anda gunakan!
marc_s
2
Itu adalah prosedur sp_rename yang gagal. Saya menemukan solusi pada stackoverflow dengan mencari teks kesalahan. Tampaknya ada beberapa aturan sintaksis yang ketat dengan tanda kurung, meskipun meja saya tidak memiliki karakter khusus dalam namanya.
Jenny O'Reilly
1
atau bisa juga seperti: 'ALTER TABLE (yourTable) DROP COLUMN OldColumnName' dan 'ALTER TABLE (yourTable) ADD OldColumnName INT IDENTITY (1,1)', mengapa ganti nama: p
RK Sharma
Marc, saya mencoba perintah yang tepat ini di atas meja besar (~ baris 300mln), tapi saya menghentikan proses setelah ~ 10 menit
Naomi
14

Ada solusi keren yang dijelaskan di sini: SQL SERVER - Tambah atau Hapus Properti Identitas pada Kolom

Singkatnya edit secara manual tabel Anda di SQL Manager, alihkan identitas, JANGAN HEMAT perubahan, cukup tunjukkan skrip yang akan dibuat untuk perubahan, salin dan gunakan nanti.

Ini adalah penghemat waktu yang sangat besar, karena itu (skrip) berisi semua kunci asing, indeks, dll yang terkait dengan tabel yang Anda ubah. Menulis ini secara manual ... Ya ampun.

Greenoldman
sumber
ini adalah solusi yang saya gunakan - SSMS menghasilkan T-SQL untuk melakukan perubahan ... ia melakukannya dengan membuat tabel temp baru dari desain skema yang sama, kemudian menyalin semua baris ke dalamnya, menghapus orig, dan mengubah nama . dapat mengambil sedikit waktu untuk berjalan sepenuhnya tetapi itu bekerja dengan sempurna.
mdelvecchio
Saya tidak berpikir Pinal Dave benar-benar mengatakan Anda perlu menjalankan skrip yang Anda hasilkan, itu hanya untuk menunjukkan apa yang membuat perubahan melalui UI lakukan untuk Anda ...
Zack
Fasilitas scripting ini dalam SSMS (tentang mengubah definisi tabel) sebenarnya satu-satunya fasilitas yang benar ketika mendokumentasikan tabel partisi. 'Tugas' lokasi paling tepat -> 'tabel skrip' selalu lupa untuk skrip fungsi pemartisian!
Martijn van der Jagt
1
Semoga bermanfaat bagi seseorang. Untuk mendapatkan Script Perubahan setelah perubahan. Klik kanan tabel dalam mode desain pada SSMS dan pilih opsi "Hasilkan Ubah Skrip" dan simpan skrip di drive Lokal
Vijai
11

Pertimbangkan untuk menggunakan URUTAN alih-alih IDENTITAS .

DI sql server 2014 (saya tidak tahu tentang versi yang lebih rendah) Anda bisa melakukan ini secara sederhana, menggunakan urutan.

CREATE SEQUENCE  sequence_name START WITH here_higher_number_than_max_existed_value_in_column INCREMENT BY 1;

ALTER TABLE table_name ADD CONSTRAINT constraint_name DEFAULT NEXT VALUE FOR sequence_name FOR column_name

Dari sini: Urutan sebagai nilai default untuk sebuah kolom

Oto Shavadze
sumber
6

Penjelasan sederhana

Ganti nama kolom yang ada menggunakan sp_RENAME

EXEC sp_RENAME 'Table_Name.Existing_ColumnName', 'New_ColumnName', 'COLUMN'

Contoh untuk Ganti Nama:

Kolom yang ada UserID diganti nama menjadi OldUserID

EXEC sp_RENAME 'AdminUsers.UserID' , 'OldUserID', 'COLUMN'

Kemudian tambahkan kolom baru menggunakan ubah kueri untuk ditetapkan sebagai kunci utama dan nilai identitas

ALTER TABLE TableName ADD Old_ColumnName INT NOT NULL PRIMARY KEY IDENTITY(1,1)

Contoh untuk Set kunci Utama

Nama kolom yang baru dibuat adalah UserID

ALTER TABLE Users ADD UserID INT NOT NULL PRIMARY KEY IDENTITY(1,1)

kemudian Jatuhkan Kolom yang Diubah Nama

ALTER TABLE Table_Name DROP COLUMN Renamed_ColumnName

Contoh untuk Drop berganti nama kolom

ALTER TABLE Users DROP COLUMN OldUserID

Sekarang kami telah menambahkan kunci primer dan identitas ke kolom yang ada di tabel.

Sathish Chelladurai
sumber
5

Saya seorang pengembang java yang kebetulan bergabung dalam tim tanpa DBA dan di mana sebagai pengembang, saya tidak bisa mendapatkan hak DBA. Saya ditugaskan untuk memindahkan seluruh skema antara dua database, jadi tanpa memiliki DBA, saya harus melakukannya dan melakukannya dengan menjalankan skrip, tidak dapat menggunakan GUI di SQL Server 2008 karena saya tidak memiliki hak admin.

Namun, semuanya dipindahkan tanpa masalah, ketika menjalankan prosedur tersimpan pada skema baru. Pada tabel, saya menemukan saya kehilangan bidang identitas dalam sebuah tabel. Saya mengecek skrip yang membuat tabel dan itu ada di sana, namun, SQL Server tidak mendapatkannya ketika saya menjalankan skrip. Saya kemudian diberitahu oleh DBA bahwa dia telah melihat masalah yang sama sebelumnya.

Bagaimanapun, untuk SQL Server 2008, ini adalah langkah-langkah yang saya ambil untuk menyelesaikan masalah ini dan mereka bekerja, jadi saya memposting ini di sini dengan harapan ini akan membantu seseorang. Inilah yang saya lakukan karena saya memiliki dependensi FK pada tabel lain yang membuat ini lebih sulit:

Saya menggunakan kueri ini untuk memverifikasi identitas memang hilang dan untuk melihat dependensi pada tabel.

1.) Temukan statistik di atas meja:

exec sp_help 'dbo.table_name_old';

2.) Buat duplikat, tabel baru yang identik, kecuali tambahkan bidang identitas pada bidang PK di tempat sebelumnya.

3.) Nonaktifkan identitas untuk memindahkan data.

SET IDENTITY_INSERT dbo.table_name ON 

4.) Transfer data.

INSERT INTO dbo.table_name_new
(
field1, field2, etc...
)
SELECT 
field1, field2, etc...
FROM 
dbo.table_name_old;

5.) Verifikasi data yang ada.

SELECT * FROM dbo.table_name_new

6.) Aktifkan kembali identitas.

SET IDENTITY_INSERT ToyRecP.ToyAwards.lkpFile_New OFF

7.) Ini adalah skrip terbaik yang saya temukan untuk mendapatkan semua hubungan FK untuk memverifikasi tabel mana yang merujuk tabel asli sebagai dependensi dan saya menemukan banyak, jadi itu adalah penjaga!

SELECT f.name AS ForeignKey,
   OBJECT_NAME(f.parent_object_id) AS TableName,
   COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName,
   OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
   COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
   ON f.OBJECT_ID = fc.constraint_object_id
   ORDER BY ReferenceTableName;

8.) Pastikan Anda memiliki semua skrip PK dan FK untuk semua tabel yang terlibat, sebelum langkah berikutnya.

9.) Anda dapat mengklik kanan pada setiap kunci dan skrip ini menggunakan SQL Server 2008

10.) Jatuhkan FK dari tabel dependensi menggunakan sintaks ini:

ALTER TABLE [dbo].[table_name] DROP CONSTRAINT [Name_of_FK]

11.) Jatuhkan meja asli:

DROP TABLE dbo.table_name_old;

13.) Langkah-langkah selanjutnya bergantung pada skrip yang Anda buat di SQL Server 2008 di langkah 9.

--Tambahkan PK ke tabel baru.

--Tambahkan FK ke tabel baru.

--Tambahkan FK kembali ke tabel ketergantungan.

14.) Verifikasi semuanya benar dan lengkap. Saya menggunakan GUI untuk melihat tabel.

15.) Ubah nama tabel baru menjadi nama tabel asli.

exec sp_RENAME '[Schema_Name.OldTableName]' , '[NewTableName]';

Akhirnya, semuanya berhasil!

James Drinkard
sumber
4

Anda tidak dapat melakukannya seperti itu, Anda perlu menambahkan kolom lain, letakkan kolom asli dan ganti nama kolom baru atau buat tabel baru, salin data dan letakkan tabel lama diikuti dengan mengubah nama tabel baru ke yang lama meja

Jika Anda menggunakan SSMS dan mengatur properti identitas ke ON di perancang di sini adalah apa yang SQL Server lakukan di belakang layar. Jadi jika Anda memiliki tabel bernama [pengguna] inilah yang terjadi jika Anda membuat UserID dan identitas

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
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

GO
CREATE TABLE dbo.Tmp_User
    (
    UserID int NOT NULL IDENTITY (1, 1),
    LastName varchar(50) NOT NULL,
    FirstName varchar(50) NOT NULL,
    MiddleInitial char(1) NULL

    )  ON [PRIMARY]
GO

SET IDENTITY_INSERT dbo.Tmp_User ON
GO
IF EXISTS(SELECT * FROM dbo.[User])
 EXEC('INSERT INTO dbo.Tmp_User (UserID, LastName, FirstName, MiddleInitial)
    SELECT UserID, LastName, FirstName, MiddleInitialFROM dbo.[User] TABLOCKX')
GO
SET IDENTITY_INSERT dbo.Tmp_User OFF
GO

GO
DROP TABLE dbo.[User]
GO
EXECUTE sp_rename N'dbo.Tmp_User', N'User', 'OBJECT'
GO
ALTER TABLE dbo.[User] ADD CONSTRAINT
    PK_User PRIMARY KEY CLUSTERED 
    (
    UserID
    ) ON [PRIMARY]

GO
COMMIT

Setelah mengatakan bahwa ada cara untuk meretas tabel sistem untuk mencapainya dengan menetapkan nilai bitwise tetapi itu tidak didukung dan saya tidak akan melakukannya

SQLMenace
sumber
4

Seperti yang saya pahami dalam kasus normal, kami membuat tabel dengan kunci Primer yang memiliki properti Identity.
Jadi Ganti Nama atau Hapus kolom yang terkait dengan batasan Kunci Utama tidak akan mungkin karena Aturan kendala memvalidasi struktur kolom. Untuk mencapai ini, kita harus memproses beberapa langkah dengan cara berikut: Mari kita asumsikan TableName = 'Karyawan' dan ColumnName = 'EmployeeId' 1. Tambahkan kolom baru 'EmployeeId_new' di tabel 'Employee' ALTER TABLE Karyawan ADD EmployeeId_new INT IDENTITY ( 1,1)




  1. Sekarang hapus kolom 'EmployeeId' dari tabel 'Employee'
    ALTER TABLE Employee DROP COLUMN EmployeeId

  2. Ini akan menimbulkan kesalahan karena aturan Kendala Kunci Utama berlaku dan memvalidasi struktur kolom.
    * ### ' Msg 5074, Level 16, State 1, Line 1 Objek [PK_dbo.Employee] bergantung pada colmn [EmployeeId].' ###

  3. Jadi kita harus menghapus batasan Primary Key terlebih dahulu dari tabel 'Employee' lalu kita dapat menghapus kolom
    ALTER TABLE batasan DROP Karyawan [PK_dbo.Employee]

  4. Sekarang kita dapat menghapus kolom 'EmployeeId' dari tabel 'Employee' seperti pada langkah sebelumnya di mana kita mendapatkan kesalahan.
    ALTER TABLE DROP COLUMN EmployeeId

  5. Sekarang Kolom 'EmployeeId' dihapus dari tabel Jadi kami akan Ganti nama kolom baru yang baru ditambahkan 'EmployeeId_new' dengan 'EmployeeId'
    sp_rename 'Employee.EmployeeId', 'EmployeeId_new', 'COLUMN'

  6. Untuk mengatur ulang tabel dalam bentuk yang sama seperti itu, kita harus menambahkan Batasan Kunci Primer untuk kolom 'EmployeeId'
    ALTER TABLE Karyawan menambahkan kendala [PK_dbo.Employee] primary key (EmployeeId)

8. Sekarang tabel 'Karyawan' dengan 'EmployeeId' dimodifikasi untuk aturan Identitas bersama dengan batasan kunci utama yang ada

Nagendra Upwanshi
sumber
3

Dengan desain tidak ada cara sederhana untuk menghidupkan atau mematikan fitur identitas untuk kolom yang ada. Satu-satunya cara bersih untuk melakukan ini adalah membuat kolom baru dan menjadikannya kolom identitas atau membuat tabel baru dan memigrasikan data Anda.

Jika kita menggunakan SQL Server Management Studio untuk menghilangkan nilai identitas pada kolom "id", tabel sementara baru dibuat, data dipindahkan ke tabel sementara, tabel lama dihapus dan tabel baru diganti namanya.

Gunakan Management Studio untuk melakukan perubahan dan kemudian klik kanan pada desainer dan pilih "Generate Change Script".

Anda akan melihat bahwa inilah yang dilakukan SQL server di latar belakang.

Raj
sumber
2

Sayangnya, tidak ada satu; properti IDENTITY milik tabel dan bukan kolom.

Cara yang lebih mudah adalah melakukannya di GUI, tetapi jika ini bukan pilihan, Anda dapat menyalin data, menjatuhkan kolom, menambahkannya kembali dengan identitas, dan mengembalikan data.

Lihat di sini untuk akun pukulan demi pukulan.

Jeremy Smyth
sumber
2

Klik kanan pada nama tabel di Object Explorer. Anda akan mendapatkan beberapa opsi. Klik pada 'Desain'. Tab baru akan dibuka untuk tabel ini. Anda dapat menambahkan batasan Identitas di sini di 'Properti Kolom'.

vamsi_874
sumber
2

Untuk memodifikasi properti identitas untuk kolom:

  • Di Server Explorer, klik kanan tabel dengan properti identitas yang ingin Anda ubah dan klik Buka Definisi Tabel. Tabel terbuka di Desainer Tabel.
  • Kosongkan kotak centang Izinkan nol untuk kolom yang ingin Anda ubah.
  • Di tab Properti Kolom, rentangkan properti Spesifikasi Identitas.
  • Klik sel kisi untuk properti anak Isity Identity dan pilih Ya dari daftar turun bawah.
  • Ketikkan nilai dalam sel Benih Identitas. Nilai ini akan diberikan ke baris pertama dalam tabel. Nilai 1 akan ditetapkan secara default.

Itu dia, dan itu berhasil untuk saya

Ken.Fukizi
sumber
2

Jika Anda kebetulan menggunakan Visual Studio 2017+

  1. Di Server Object Explorer klik kanan pada tabel Anda dan pilih "view code"
  2. Tambahkan pengubah "IDENTITY" ke kolom Anda
  3. Memperbarui

Ini akan melakukan semuanya untuk Anda.

jdisla
sumber
Iya! Terima kasih telah menyarankan ini! Saya tidak memiliki versi SSMS di kotak Windows 7 saya yang memungkinkan saya untuk membuat perubahan Desain ke tabel di server Produksi saya karena ini 2017, SSMS saya 2014, dan 2017 SSMS membutuhkan Windows 10. Anda membuat hari saya. Pergi ke VS 2017> Server Explorer> membuat koneksi baru untuk produksi SQL Server> klik kanan pada tabel> "Open Table Definition"> Wala!
JustJohn
Sebenarnya, saya menemukan Anda dapat mengklik kanan pada bidang dan pilih Properties dan membuat Identity di sana memilih Ya atau Tidak.
JustJohn
1

Jika poster asli sebenarnya ingin mengatur kolom yang ada menjadi PRIMARY KEYuntuk tabel dan sebenarnya tidak perlu kolom menjadi IDENTITYkolom (dua hal berbeda) maka ini dapat dilakukan melalui t-SQL dengan:

ALTER TABLE [YourTableName]
ADD CONSTRAINT [ColumnToSetAsPrimaryKey] PRIMARY KEY ([ColumnToSetAsPrimaryKey])

Perhatikan tanda kurung di sekitar nama kolom setelah PRIMARY KEYopsi.

Meskipun posting ini sudah tua dan saya membuat asumsi tentang kebutuhan pemohon, saya merasa informasi tambahan ini dapat membantu pengguna yang menemukan utas ini karena saya yakin percakapan dapat membuat orang percaya bahwa kolom yang ada tidak dapat disetel menjadi kunci primer tanpa menambahkannya sebagai kolom baru terlebih dahulu yang tidak benar.

A. Omalley
sumber
1

Sesuai kondisi saya saat ini, saya mengikuti pendekatan ini. Saya ingin memberikan identitas ke tabel utama setelah data dimasukkan melalui skrip.

Karena saya ingin menambahkan identitas, maka selalu mulai dari 1 hingga Akhir jumlah catatan yang saya inginkan.

--first drop column and add with identity
ALTER TABLE dbo.tblProductPriceList drop column ID 
ALTER TABLE dbo.tblProductPriceList add ID INT IDENTITY(1,1)

--then add primary key to that column (exist option you can ignore)
IF  NOT EXISTS (SELECT * FROM sys.key_constraints  WHERE object_id = OBJECT_ID(N'[dbo].[PK_tblProductPriceList]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblProductPriceList]'))
    ALTER TABLE [tblProductPriceList] ADD PRIMARY KEY (id)
GO

Ini akan membuat kolom kunci utama yang sama dengan identitas

Saya menggunakan tautan ini: https://blog.sqlauthority.com/2014/10/11/sql-server-add-auto-incremental-identity-column-to-table-after-creating-table/

Tambahkan kunci utama ke tabel yang ada

Ajay2707
sumber
0

Saya tidak percaya Anda dapat mengubah kolom yang ada menjadi kolom identitas menggunakan tsql. Namun, Anda dapat melakukannya melalui tampilan desain Enterprise Manager.

Atau Anda bisa membuat baris baru sebagai kolom identitas, letakkan kolom lama, lalu ganti nama kolom baru Anda.

ALTER TABLE FooTable
ADD BarColumn INT IDENTITY(1, 1)
               NOT NULL
               PRIMARY KEY CLUSTERED
William Edmondson
sumber
2
perlu diingat bahwa jika Anda melakukannya melalui SSMS / Enterprise Manager - Anda akan membuat tabel baru, menyalin data, menjatuhkan tabel lama, dan mengganti nama yang baru. Itu bisa sangat mahal ketika Anda memiliki meja besar ...
Scott Ivey
0

Pada dasarnya ada empat langkah logis.

  1. Buat kolom Identity baru. Aktifkan Sisipkan Identitas untuk kolom baru ini.

  2. Masukkan data dari kolom sumber (kolom yang ingin Anda konversi ke Identity) ke kolom baru ini.

  3. Matikan Sisipkan Identitas untuk kolom baru.

  4. Jatuhkan kolom sumber Anda & ganti nama kolom baru dengan nama kolom sumber.

Mungkin ada beberapa kompleksitas seperti bekerja di beberapa server dll.

Silakan merujuk artikel berikut untuk langkah-langkahnya (menggunakan ssms & T-sql). Langkah-langkah ini dimaksudkan untuk pemula dengan sedikit pegangan pada T-SQL.

http://social.technet.microsoft.com/wiki/contents/articles/23816.how-to-convert-int-column-to-identity-in-the-ms-sql-server.aspx

Shivalik Chakravarty
sumber
0

menghasilkan skrip untuk semua tabel dengan primary key = bigint yang tidak memiliki set identitas; ini akan mengembalikan daftar skrip yang dihasilkan dengan setiap tabel;

SET NOCOUNT ON;

declare @sql table(s varchar(max), id int identity)

DECLARE @table_name nvarchar(max),
        @table_schema nvarchar(max);

DECLARE vendor_cursor CURSOR FOR 
SELECT
  t.name, s.name
FROM sys.schemas AS s
INNER JOIN sys.tables AS t
  ON s.[schema_id] = t.[schema_id]
WHERE EXISTS (
    SELECT
    [c].[name]
    from sys.columns [c]
    join sys.types [y] on [y].system_type_id = [c].system_type_id
    where [c].[object_id] = [t].[object_id] and [y].name = 'bigint' and [c].[column_id] = 1
) and NOT EXISTS 
(
  SELECT 1 FROM sys.identity_columns
    WHERE [object_id] = t.[object_id]
) and exists (
    select 1 from sys.indexes as [i] 
    inner join sys.index_columns as [ic]  ON  i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
    where object_name([ic].[object_id]) = [t].[name]
)
OPEN vendor_cursor

FETCH NEXT FROM vendor_cursor 
INTO @table_name, @table_schema

WHILE @@FETCH_STATUS = 0
BEGIN

DELETE FROM @sql

declare @pkname varchar(100),
    @pkcol nvarchar(100)

SELECT  top 1
        @pkname = i.name,
        @pkcol = COL_NAME(ic.OBJECT_ID,ic.column_id)
FROM    sys.indexes AS [i]
INNER JOIN sys.index_columns AS [ic] ON  i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
WHERE   i.is_primary_key = 1 and OBJECT_NAME(ic.OBJECT_ID) = @table_name

declare @q nvarchar(max) = 'SELECT  '+@pkcol+' FROM ['+@table_schema+'].['+@table_name+'] ORDER BY '+@pkcol+' DESC'

DECLARE @ident_seed nvarchar(max) -- Change this to the datatype that you are after
SET @q = REPLACE(@q, 'SELECT', 'SELECT TOP 1 @output = ')
EXEC sp_executeSql @q, N'@output bigint OUTPUT', @ident_seed OUTPUT

insert into  @sql(s) values ('BEGIN TRANSACTION')
insert into  @sql(s) values ('BEGIN TRY')

-- create statement
insert into  @sql(s) values ('create table ['+@table_schema+'].[' + @table_name + '_Temp] (')

-- column list
insert into @sql(s) 
select 
    '  ['+[c].[name]+'] ' +
    y.name + 

    (case when [y].[name] like '%varchar' then
    coalesce('('+(case when ([c].[max_length] < 0 or [c].[max_length] >= 1024) then 'max' else cast([c].max_length as varchar) end)+')','')
    else '' end)

     + ' ' +
    case when [c].name = @pkcol then 'IDENTITY(' +COALESCE(@ident_seed, '1')+',1)' else '' end + ' ' +
    ( case when c.is_nullable = 0 then 'NOT ' else '' end ) + 'NULL ' + 
    coalesce('DEFAULT ('+(
        REPLACE(
            REPLACE(
                LTrim(
                    RTrim(
                        REPLACE(
                            REPLACE(
                                REPLACE(
                                    REPLACE(
                                        LTrim(
                                            RTrim(
                                                REPLACE(
                                                    REPLACE(
                                                        object_definition([c].default_object_id)
                                                    ,' ','~')
                                                ,')',' ')
                                            )
                                        )
                                    ,' ','*')
                                ,'~',' ')
                            ,' ','~')
                        ,'(',' ')
                    )
                )
            ,' ','*')
        ,'~',' ')
    ) +
    case when object_definition([c].default_object_id) like '%get%date%' then '()' else '' end
    +
    ')','') + ','
 from sys.columns c
 JOIN sys.types y ON y.system_type_id = c.system_type_id
  where OBJECT_NAME(c.[object_id]) = @table_name and [y].name != 'sysname'
 order by [c].column_id


 update @sql set s=left(s,len(s)-1) where id=@@identity

-- closing bracket
insert into @sql(s) values( ')' )

insert into @sql(s) values( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@table_name+'_Temp] ON')

declare @cols nvarchar(max)
SELECT @cols = STUFF(
    (
        select ',['+c.name+']'
        from sys.columns c
        JOIN sys.types y ON y.system_type_id = c.system_type_id
        where c.[object_id] = OBJECT_ID(@table_name)
        and [y].name != 'sysname'
        and [y].name != 'timestamp'
        order by [c].column_id
        FOR XML PATH ('')
     )
    , 1, 1, '')

insert into @sql(s) values( 'IF EXISTS(SELECT * FROM ['+@table_schema+'].['+@table_name+'])')
insert into @sql(s) values( 'EXEC(''INSERT INTO ['+@table_schema+'].['+@table_name+'_Temp] ('+@cols+')')
insert into @sql(s) values( 'SELECT '+@cols+' FROM ['+@table_schema+'].['+@table_name+']'')')

insert into @sql(s) values( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@table_name+'_Temp] OFF')


insert into @sql(s) values( 'DROP TABLE ['+@table_schema+'].['+@table_name+']')

insert into @sql(s) values( 'EXECUTE sp_rename N''['+@table_schema+'].['+@table_name+'_Temp]'', N'''+@table_name+''', ''OBJECT''')

if ( @pkname is not null ) begin
    insert into @sql(s) values('ALTER TABLE ['+@table_schema+'].['+@table_name+'] ADD CONSTRAINT ['+@pkname+'] PRIMARY KEY CLUSTERED (')
    insert into @sql(s)
        select '  ['+COLUMN_NAME+'] ASC,' from information_schema.key_column_usage
        where constraint_name = @pkname
        GROUP BY COLUMN_NAME, ordinal_position
        order by ordinal_position

    -- remove trailing comma
    update @sql set s=left(s,len(s)-1) where id=@@identity
    insert into @sql(s) values ('  )')
end

insert into  @sql(s) values ('--Run your Statements')
insert into  @sql(s) values ('COMMIT TRANSACTION')
insert into  @sql(s) values ('END TRY')
insert into  @sql(s) values ('BEGIN CATCH')
insert into  @sql(s) values ('        ROLLBACK TRANSACTION')
insert into  @sql(s) values ('        DECLARE @Msg NVARCHAR(MAX)  ')
insert into  @sql(s) values ('        SELECT @Msg=ERROR_MESSAGE() ')
insert into  @sql(s) values ('        RAISERROR(''Error Occured: %s'', 20, 101,@msg) WITH LOG')
insert into  @sql(s) values ('END CATCH')

declare @fqry nvarchar(max)

-- result!
SELECT @fqry = (select char(10) + s from @sql order by id FOR XML PATH (''))


SELECT @table_name as [Table_Name], @fqry as [Generated_Query]
PRINT 'Table: '+@table_name
EXEC sp_executeSql @fqry

    FETCH NEXT FROM vendor_cursor 
    INTO @table_name, @table_schema
END 
CLOSE vendor_cursor;
DEALLOCATE vendor_cursor;
Kyle Gibbar
sumber