如何在SQL Server中的两个表中强制执行唯一操作

时间:2014-10-17 15:03:08

标签: sql sql-server tsql database-design

要求

  1. 每位员工都有一个唯一的ID。 (EPID)
  2. 员工只能是以下任何一个,
    • FT - 全职
    • PT - 兼职
  3. 任何员工都不可能同时是FT和PT。
  4. FT& PT有许多不同的领域可供捕捉。
  5. 实施

    Create Table EmpFT( EPID int primary key,  F1, F2, etc)
    Create Table EmpPT( EPID int primary key,  P1, P2, etc)
    --This does not prevent same EPID on both EmpFT and EmpPT.
    

    如何在数据库中实现第3名?

    我正在使用SQL Server 2012标准版。

4 个答案:

答案 0 :(得分:4)

试试这个方法:

CREATE TABLE Emp(EPID INT PRIMARY KEY,
    t CHAR(2) NOT NULL, UNIQUE (EPID,t));

CREATE TABLE EmpFT(EPID INT PRIMARY KEY, ... other columns
    t CHAR(2) NOT NULL CHECK (t = 'FT'),
    FOREIGN KEY (EPID,t) REFERENCES Emp (EPID,t));

CREATE TABLE EmpPT(EPID INT PRIMARY KEY, ... other columns
    t CHAR(2) NOT NULL CHECK (t = 'PT'),
    FOREIGN KEY (EPID,t) REFERENCES Emp (EPID,t));

答案 1 :(得分:2)

您可以添加检查约束。这两个表都是这样的

ALTER TABLE EmpFT
ADD CONSTRAINT chk_EmpFT_EPID CHECK (dbo.CHECK_EmpPT(EPID)= 0)
ALTER TABLE EmpPT
ADD CONSTRAINT chk_EmpPT_EPID CHECK (dbo.CHECK_EmpFT(EPID)= 0)

功能如此:

CREATE FUNCTION CHECK_EmpFT(@EPID int)
RETURNS int
AS
BEGIN
DECLARE @ret int;   
SELECT @ret = count(*) FROM EmpFT WHERE @EPID = EmpFT.EPID
RETURN @ret;
END
GO


CREATE FUNCTION CHECK_EmpPT(@EPID int)
RETURNS int
AS
BEGIN
DECLARE @ret int;   
SELECT @ret = count(*) FROM EmpPT WHERE @EPID = EmpPT.EPID
RETURN @ret;
END
GO

进一步阅读:

答案 2 :(得分:0)

您可以为所有员工创建组合表。 FT和PT表可以使用外键到employee表。

答案 3 :(得分:0)

您不能让主键跨越表。因此,一种方法是使用适当的约束创建表employee。这可能如下所示:

create table employee (
    EPID int not null identity(1, 1) primary key,
    FTID int references empft(empftid),
    PTID int references emppt(empptid),
    CHECK (FTID is not null and PTID is null or FTID is null and PTID is not null),
    UNIQUE (FTID),
    UNIQUE (PTID)
    . . .
);

create table empft (
    EmpFTId int not null identity(1, 1) primary key,
    . . .
);

create table emppt (
    EmpPTId int not null identity(1, 1) primary key,
    . . .
);

当然,如果你愿意,也可以使用触发器。