SQL 基于其他列的唯一列

SQL unique column based on other columns

我有一个 SQL 服务器数据库 table,我正在尝试修复它而不必求助于使用前端代码来确定研究所名称是否唯一。我正在为所有插入设置 Linq to SQL 代码库。

这是我要设置的新 table:

CREATE TABLE [dbo].[institution]
(
    [institutionID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [typeID] [tinyint] NOT NULL REFERENCES [dbo].[institutiontype]([institutiontypeID]),
    [name] [varchar](255) NOT NULL UNIQUE,
    [cityID] [int] NULL REFERENCES [dbo].[city]([cityID]),
    [stateID] [int] NULL REFERENCES [dbo].[stateprovince]([stateID]),
    [countryID] [int] NULL REFERENCES [dbo].[country]([countryID]),
    [createby] [int] NOT NULL REFERENCES [dbo].[ipamuser]([ipamuserID]),
    [createdatetime] [datetime] NOT NULL DEFAULT (GETDATE()),
    [modifyby] [int] NULL REFERENCES [dbo].[ipamuser]([ipamuserID]),
    [modifydatetime] [datetime] NULL,
    [dataversion] [int] NOT NULL DEFAULT (0)
)

问题是,仅当 cityID、stateID 和 countryID 相同时,institutionname 才需要是唯一的。将 table 设置为唯一的 institutename 不能满足需求,因为有时相同的名称可能存在于不同的城市、州或国家/地区。

我该如何解决这个问题

您需要在 table 中编写一个复杂的约束条件。定义一个用户定义的函数,如果满足所需条件,则 returns 为真(BIT 中为 1),否则为假。 将此约束放入具有 CHECK 约束的 table 模式中。

CREATE FUNCTION dbo.fnIsNameUnique (
  @name [varchar](255),
  @cityID int,
  @stateID int,
  @countryID int,
)
RETURNS tinyint
AS
BEGIN
  DECLARE @Result tinyint
  IF EXISTS(SELECT * FROM institution WHERE name = @name AND cityID = @cityID AND stateID = @stateID AND countryID = @countryID)
    SET @Result= 0
  ELSE 
    SET @Result= 1
  RETURN @Result
END

CREATE TABLE [dbo].[institution]
(
    [institutionID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [typeID] [tinyint] NOT NULL REFERENCES [dbo].[institutiontype]([institutiontypeID]),
    [name] [varchar](255) NOT NULL UNIQUE,
    [cityID] [int] NULL REFERENCES [dbo].[city]([cityID]),
    [stateID] [int] NULL REFERENCES [dbo].[stateprovince]([stateID]),
    [countryID] [int] NULL REFERENCES [dbo].[country]([countryID]),
    [createby] [int] NOT NULL REFERENCES [dbo].[ipamuser]([ipamuserID]),
    [createdatetime] [datetime] NOT NULL DEFAULT (GETDATE()),
    [modifyby] [int] NULL REFERENCES [dbo].[ipamuser]([ipamuserID]),
    [modifydatetime] [datetime] NULL,
    [dataversion] [int] NOT NULL DEFAULT (0),
    CONSTRAINT ckValidName CHECK (
    dbo.fnIsNameUnique(name, cityID, stateID, countryID) = 1)
  )
)

我不知道你为什么需要这么复杂的东西,只要在 ([name], CityID, StateID, CountryID) 上放置一个 UNIQUE 约束或索引就可以满足你的要求。