sql >> Database teknologi >  >> RDS >> Sqlserver

Tilføj unik begrænsning til kombination af to kolonner

Når du har fjernet dine dubletter:

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

eller

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

Selvfølgelig kan det ofte være bedre at tjekke for denne overtrædelse først, før du bare lader SQL Server forsøge at indsætte rækken og returnere en undtagelse (undtagelser er dyre).

  • Effektiviteten af ​​forskellige fejlhåndteringsteknikker

  • Kontrollerer for potentielle overtrædelser af begrænsninger, før du går ind i TRY/CATCH

Hvis du vil forhindre undtagelser i at boble op til applikationen uden at foretage ændringer i applikationen, kan du bruge en INSTEAD OF trigger:

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

Men hvis du ikke fortæller brugeren, at de ikke udførte indsættelsen, vil de undre sig over, hvorfor dataene ikke er der, og ingen undtagelse blev rapporteret.

REDIGER her er et eksempel, der gør præcis, hvad du beder om, endda ved at bruge de samme navne som dit spørgsmål, og beviser det. Du bør prøve det, før du antager, at ovenstående ideer kun behandler den ene eller den anden kolonne i modsætning til kombinationen...

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 i tabellen efter alt dette:

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

Fejlmeddelelse på sidste indsættelse:

Meddelelse 2627, niveau 14, tilstand 1, linje 3 Overtrædelse af UNIQUE KEY-begrænsning 'uq_Person'. Kan ikke indsætte dubletnøgle i objektet 'dbo.Person'. Udsagnet er blevet afsluttet.

Jeg bloggede også for nylig om en løsning til at anvende en unik begrænsning på to kolonner i begge rækkefølge :

  • Håndhæv en unik begrænsning, hvor rækkefølgen ikke betyder noget


  1. Sådan øges maksimale forbindelser i PostgreSQL

  2. Hvordan får man sidste dag i sidste uge i sql?

  3. En introduktion til Hadoop og Big Data

  4. Hvordan gemmer man arrays i MySQL?