0

我有两个名为 tbl_1 和 tbl_2 的表,其架构如下

CREATE TABLE tbl_1(id int, disabled bit, qtype int)

CREATE TABLE tbl_2 (qtype int, qname nvarchar(MAX))

我想向 tbl_1 添加一个约束,以便 if (disabled=0 或 disabled 为 null) qtype 必须是 tbl_2.qtype 列中存在的数字?

我尝试创建一个函数并添加了一个检查约束

CREATE FUNCTION fn_Check_qtype(@qtype INT)
RETURNS int 
AS
BEGIN
IF EXISTS(SELECT qtype from tbl_1 where (disabled=0 or disabled is null) and qtype=@qtype)
IF EXISTS (SELECT qtype FROM tbl_2 WHERE qtype is not null and qtype = @qtype)
      return 1
  return 0
END

约束

alter table tbl_1
add constraint ck_qtyppe
check (dbo.fn_Check_qtype(qtype) =1)

但即使没有不匹配的记录,它也会抛出错误

ALTER TABLE 语句与 CHECK 约束“ck_qtypeppe”冲突。冲突发生在数据库“TestDB”、表“dbo.tbl_1”、列“qtype”中。

但是,如果我要从 tbl_1 中删除 qtype null 值,则无论 disabled=0、disabled=、disabled=null 都可以正常工作。

4

1 回答 1

1

首先,外键引用应该是主键,所以让我假设tbl_2定义为:

CREATE TABLE tbl_2 (
    qtype int primary key,
    qname nvarchar(MAX)
);

然后,您可以在没有用户定义函数的情况下执行此操作。您只需要一个持久的计算列:

CREATE TABLE tbl_1 (
    id int, 
    disabled bit,
    qtype int,
    qtype_enabled as (case when disabled = 1 then qtype end) persisted,
    foreign key (qtype_enabled) references tbl_2 (qtype)
);

是一个 db<>fiddle。

于 2021-03-18T12:30:55.347 回答