SQL唯一列基于其他列

时间:2016-06-03 04:19:15

标签: sql sql-server tsql unique-constraint

我有一个SQL Server数据库表,我试图修复,而不必使用前端代码来确定该机构的名称是否唯一。我正在为所有插入设置Linq to SQL代码库。

这是我要设置的新表:

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相同时,该机构名才需要是唯一的。将学院名称设置为唯一的表格将无法满足需求,因为有时候在不同的城市,州或国家/地区可能存在相同的名称。

我将如何解决此问题

2 个答案:

答案 0 :(得分:1)

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

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)
  )
)

答案 1 :(得分:0)

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