sql >> Databasteknik >  >> RDS >> Mysql

Begränsa med villkorad värdekontroll i MySQL

Enligt dokumentationen ,

Så att ta bort not null -constraint från Status och lägga till ett unikt index på (ContactId,PhoneId,Status) kommer att fungera som du vill om du använder null istället för 0 för inaktiv rekord.

Om du inte vill eller inte kan använda null för din Status kolumn, vill se till att både Status=0 och Status=null bete sig identiskt, eller t.ex. vill behandla Status=2 som aktiv (och upprätthålla unikhet) också kan du lägga till en dummy-kolumn som kommer att beräknas från Status .

Om du använder MySQL 5.7+ kan du göra detta med en genererad kolumn:

CREATE TABLE IF NOT EXISTS `ContactPhone` (
  `ContactPhoneId` int(10) unsigned NOT NULL auto_increment primary key,
  `ContactId` int(11) NOT NULL,
  `PhoneId` smallint(5) unsigned NOT NULL,
  `Status` tinyint(1) NOT NULL DEFAULT '1',
  `StatusUnq` tinyint(1) as (if(Status <> 0, 1, null)) stored null,
  constraint unique (ContactId, PhoneId, StatusUnq)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
values (1, 1, 1, 1);
insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
values (2, 1, 1, 1);
-- Duplicate key error 
insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
values (3, 1, 1, 0);
insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
values (4, 1, 1, 0);
update ContactPhone set Status = 1 where ContactPhoneId = 4;
-- Duplicate key error 

Annars kan du använda en normal kolumn och använda triggers för att beräkna värdet på kolumnen, t.ex.:

create trigger trbi_contactPhoneUnique before insert on ContactPhone 
for each row
  set new.StatusUnq = if(new.Status <> 0, 1, null);

create trigger trbu_contactPhoneUnique before update on ContactPhone 
for each row
  set new.StatusUnq = if(new.Status <> 0, 1, null);

Du kan givetvis byta formeln till t.ex. if(new.Status <> 0, new.Status, null); om du vill tillåta olika värden för Status för.




  1. Infogar variabel i SQL-fråga från Java

  2. Jag måste skicka kolumnnamn med variabel i select-satsen i Store Procedure men jag kan inte använda dynamisk fråga

  3. Flera möjligheter för LINES TERMINATED BY och FIELDS TERMINATED BY - MySQL

  4. Saknar artefakt com.microsoft.sqlserver:sqljdbc4:jar:4.0