Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Tambahkan batasan unik ke kombinasi dua kolom

Setelah Anda menghapus duplikat Anda:

ALTER TABLE dbo.yourtablename
  ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);

atau

CREATE UNIQUE INDEX uq_yourtablename
  ON dbo.yourtablename(column1, column2);

Tentu saja, seringkali lebih baik untuk memeriksa pelanggaran ini terlebih dahulu, sebelum membiarkan SQL Server mencoba menyisipkan baris dan mengembalikan pengecualian (pengecualian mahal).

  • Dampak kinerja dari berbagai teknik penanganan kesalahan

  • Memeriksa potensi pelanggaran batasan sebelum memasuki TRY/CATCH

Jika Anda ingin mencegah pengecualian agar tidak meluap ke aplikasi, tanpa membuat perubahan pada aplikasi, Anda dapat menggunakan INSTEAD OF pemicu:

CREATE TRIGGER dbo.BlockDuplicatesYourTable
 ON dbo.YourTable
 INSTEAD OF INSERT
AS
BEGIN
  SET NOCOUNT ON;

  IF NOT EXISTS (SELECT 1 FROM inserted AS i 
    INNER JOIN dbo.YourTable AS t
    ON i.column1 = t.column1
    AND i.column2 = t.column2
  )
  BEGIN
    INSERT dbo.YourTable(column1, column2, ...)
      SELECT column1, column2, ... FROM inserted;
  END
  ELSE
  BEGIN
    PRINT 'Did nothing.';
  END
END
GO

Tetapi jika Anda tidak memberi tahu pengguna bahwa mereka tidak melakukan penyisipan, mereka akan bertanya-tanya mengapa data tidak ada dan tidak ada pengecualian yang dilaporkan.

EDIT berikut adalah contoh yang melakukan persis seperti yang Anda minta, bahkan menggunakan nama yang sama dengan pertanyaan Anda, dan membuktikannya. Anda harus mencobanya sebelum berasumsi bahwa ide-ide di atas hanya memperlakukan satu kolom atau yang lain sebagai lawan dari kombinasi...

USE tempdb;
GO

CREATE TABLE dbo.Person
(
  ID INT IDENTITY(1,1) PRIMARY KEY,
  Name NVARCHAR(32),
  Active BIT,
  PersonNumber INT
);
GO

ALTER TABLE dbo.Person 
  ADD CONSTRAINT uq_Person UNIQUE(PersonNumber, Active);
GO

-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
  VALUES(N'foo', 1, 22);
GO

-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
  VALUES(N'foo', 0, 22);
GO

-- fails:
INSERT dbo.Person(Name, Active, PersonNumber)
  VALUES(N'foo', 1, 22);
GO

Data dalam tabel setelah semua ini:

ID   Name   Active PersonNumber
---- ------ ------ ------------
1    foo    1      22
2    foo    0      22

Pesan kesalahan pada sisipan terakhir:

Msg 2627, Level 14, State 1, Line 3Pelanggaran batasan KUNCI UNIK 'uq_Person'. Tidak dapat menyisipkan kunci duplikat di objek 'dbo.Person'.Pernyataan telah dihentikan.

Saya juga baru-baru ini membuat blog tentang solusi untuk menerapkan batasan unik ke dua kolom dalam urutan apa pun :

  • Terapkan Batasan Unik Saat Ketertiban Tidak Penting


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server PIVOT mungkin?

  2. 6 Cara Menggabungkan String dan Angka di SQL Server

  3. 3 Cara Mendapatkan Skema Hasil yang Ditetapkan di SQL Server

  4. Bagaimana saya bisa mencadangkan database SQL Server jarak jauh ke drive lokal?

  5. Pemeriksaan Kesehatan SQL Server Proaktif, Bagian 5:Statistik Tunggu