无论顺序如何,两列的唯一约束

Rya*_*eir 6 sql-server unique-constraint

我有以下表定义:

CREATE TABLE [Car] 
(
   CarID int NOT NULL PRIMARY KEY IDENTITY(1,1),
   FirstColorID int FOREIGN KEY REFERENCES Colors(ColorID),
   SecondColorID int FOREIGN KEY REFERENCES Colors(ColorID),

   UNIQUE(FirstColorID, SecondColorID)
)
Run Code Online (Sandbox Code Playgroud)

我希望两个颜色列是唯一的,无论它们以何种组合出现。

例如尝试:

INSERT INTO Car (FirstColorID, SecondColorID) VALUES (1, 2); --should succeed
Run Code Online (Sandbox Code Playgroud)

但在第一条记录存在且颜色反转后尝试相同的操作应该会失败:

INSERT INTO Car (FirstColorID, SecondColorID) VALUES (2, 1); --should violate constraint/check
Run Code Online (Sandbox Code Playgroud)

我使用高级代码解决了这个问题,但我宁愿直接在数据库中强制执行约束,最好不涉及触发器之类的东西。

谢谢。

Jān*_*nis 2

您也许可以创建计算列,例如:

CREATE TABLE [Car] 
(
   CarID int NOT NULL PRIMARY KEY IDENTITY(1,1),
   FirstColorID int, --FOREIGN KEY REFERENCES Colors(ColorID),
   SecondColorID int, --FOREIGN KEY REFERENCES Colors(ColorID),
   xColor As Cast(Case When FirstColorID > SecondColorID Then FirstColorID Else SecondColorID End as varChar) + ',' + 
        Cast(Case When FirstColorID <= SecondColorID Then SecondColorID Else FirstColorID End as varChar),
   UNIQUE(xColor)
)
Run Code Online (Sandbox Code Playgroud)

更新(你应该之前测试一下,我只是做了非常快速的测试)

主意

整数为 4 个字节。如果我把 2 个整数放在一起 - 我得到 8 个字节。如果我订购它们,我会得到唯一的 BigInt 值(8 个字节)。

所以我做什么:

  1. 我确保它们的顺序正确
  2. 我将 32 位的字节向左移动(所以只需乘以 4294967296 我就得到了我想要的)
  3. 我进行逻辑或 - 所以我得到 8 字节 BigInt 值,它应该始终是唯一的!

所以:

CREATE TABLE [Car] 
(
   CarID int NOT NULL PRIMARY KEY IDENTITY(1,1),
   FirstColorID int, --FOREIGN KEY REFERENCES Colors(ColorID),
   SecondColorID int, --FOREIGN KEY REFERENCES Colors(ColorID),
   xColor As 
       Case When FirstColorID > SecondColorID Then 
            Cast(FirstColorID as BigInt) * Cast(4294967296 as BigInt) | Cast(SecondColorID as BigInt)
        Else 
            Cast(SecondColorID as BigInt) * Cast(4294967296 as BigInt) |  Cast(FirstColorID as BigInt)
        End
  UNIQUE(xColor)
)
Run Code Online (Sandbox Code Playgroud)