在多列上创建FOREIGN KEY约束,其中一列是常量值

时间:2018-01-20 14:37:49

标签: sql-server tsql foreign-keys constraints

当我从2列开始使用带PRIMARY KEY的表时:

CREATE TABLE SizeTypes 
(
    TypeID          tinyint NOT NULL,
    SizeID          tinyint NOT NULL,
    Name            varchar(100) NOT NULL,

    CONSTRAINT PK_SizeType 
        PRIMARY KEY (TypeID, SizeID)
)

如何使用具有第一个常量值和第二个列的外键创建第二个表,如下所示:

CREATE TABLE Something 
(
    ID INT IDENTITY(1,1) PRIMARY KEY,
    SizeTypeID_1 TINYINT,
    SizeTypeID_2 TINYINT,
    SizeTypeID_3 TINYINT,

    CONSTRAINT FK_Something_SizeTypes_1 
        FOREIGN KEY (1, SizeTypeID_1)
        REFERENCES SizeTypes(TypeID, SizeID),
    CONSTRAINT FK_Something_SizeTypes_2 
        FOREIGN KEY (2, SizeTypeID_2)
        REFERENCES SizeTypes(TypeID, SizeID),
    CONSTRAINT FK_Something_SizeTypes_3 
        FOREIGN KEY (3, SizeTypeID_3)
        REFERENCES SizeTypes(TypeID, SizeID)
)

这可以使用FOREIGN KEY完成,如果是,那么如何?

如果没有那么我还有其他方法吗? INSERT和UPDATE对表格的触发器和对表格SizeTypes的DELETE触发器?我还有其他选择吗?

1 个答案:

答案 0 :(得分:1)

看起来以下代码可以让您通过单独的函数实现检查来创建合适的检查约束:

-- Create the first table.
create table SizeTypes(
  TypeId TinyInt not NULL,
  SizeId TinyInt not NULL,
  Name VarChar(100) not NULL,
  constraint PK_SizeType primary key ( TypeId, SizeId ) );
go

-- Create a function to implement the logic for the check constraint.
create function CheckSizeTypeId(
  @TypeId TinyInt, @SizeId TinyInt )
  returns Int
  as begin
  -- Replace the following statement with the logic for your check.
  if @SizeId >= 0 and @SizeId <= ( select SizeId from SizeTypes where TypeID = @TypeID )
    return 1;
  return 0;    
  end;
go

-- Create the second table with the check constraints.
create table Something(
  Id Int identity(1,1) primary key,
  SizeTypeId_1 TinyInt,
  SizeTypeId_2 TinyInt,
  SizeTypeId_3 TinyInt,
  constraint Check_SizeTypeId_1 check ( dbo.CheckSizeTypeId( 1, SizeTypeId_1 ) = 1 ),
  constraint Check_SizeTypeId_2 check ( dbo.CheckSizeTypeId( 2, SizeTypeId_2 ) = 1 ),
  constraint Check_SizeTypeId_3 check ( dbo.CheckSizeTypeId( 3, SizeTypeId_3 ) = 1 ) );
go

-- Houseclean.
drop table SizeTypes;
drop table Something;
drop function CheckSizeTypeId;

请注意,约束会限制您对Something中的值所执行的操作。 SizeTypes中的更改不会重新验证Something中的数据,但可以在SizeTypes的触发器中实现。