sql >> Databáze >  >> RDS >> Sqlserver

Přidejte jedinečné omezení ke kombinaci dvou sloupců

Jakmile odstraníte duplikáty:

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

nebo

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

Samozřejmě může být často lepší nejprve zkontrolovat toto porušení, než necháte SQL Server, aby se pokusil vložit řádek a vrátil výjimku (výjimky jsou drahé).

  • Vliv různých technik zpracování chyb na výkon

  • Kontrola potenciálního porušení omezení před zadáním TRY/CATCH

Pokud chcete zabránit probublávání výjimek do aplikace, aniž byste v aplikaci prováděli změny, můžete použít INSTEAD OF spoušť:

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

Ale pokud uživateli neřeknete, že vložení neprovedl, bude se divit, proč tam data nejsou a nebyla hlášena žádná výjimka.

UPRAVIT zde je příklad, který dělá přesně to, co požadujete, a to i pomocí stejných jmen jako vaše otázka, a dokazuje to. Měli byste si to vyzkoušet předtím, než předpokládáte, že výše uvedené nápady zacházejí pouze s jedním nebo druhým sloupcem, nikoli s kombinací...

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

Údaje v tabulce po tom všem:

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

Chybová zpráva u posledního vložení:

Zpráva 2627, úroveň 14, stav 1, řádek 3 Porušení omezení UNIQUE KEY 'uq_Person'. Do objektu 'dbo.Person' nelze vložit duplicitní klíč. Příkaz byl ukončen.

Nedávno jsem také blogoval o řešení použití jedinečného omezení na dva sloupce v libovolném pořadí :

  • Uplatněte jedinečné omezení tam, kde na pořadí nezáleží


  1. Aktualizujte hodnotu sloupce nahrazením části řetězce

  2. Jak vypočítat procento sloupce v MySQL

  3. Top 5 nástrojů pro modelování dat pro SQL Server

  4. Replikace MySQL s ProxySQL na serverech WHM/cPanel:Část druhá