SQL集检查约束

时间:2015-01-02 10:32:27

标签: sql sql-server tsql

我在设置检查约束时遇到问题。我有一个表策略,其中主键设置在(Policy_id, History_id) +其他列和表格报告中,其中包含Policy_id和一些其他列。

如何在报告表上设置检查约束语句以检查策略表中是否存在policy_id?

我无法使用外键约束,因为Report没有history_id列

报告不能包含Policy_id的记录,如果它在Policy表中不存在,因此无法执行插入报告

3 个答案:

答案 0 :(得分:0)

如果Policy_idHistory_id是复合主键,则引用表上的外键也必须包含两列。

如果你真的需要只检查其中一个(policy_id),我猜你必须手动完成,这不是一个好主意。

如果Report表有2个外键并且policy_idhistory_id都是单个主键,那会更好。

答案 1 :(得分:0)

您可以仅为此外键约束的目的创建一个单独的表,然后使用触发器来维护此数据:

CREATE TABLE ExistingPolicies (
    PolicyID int not null,
    PolicyCount int not null,
    constraint PK_ExistingPolicies PRIMARY KEY (PolicyID)

然后是触发器:

CREATE TRIGGER T_Policy_I
on Policy
instead of insert
as
     ;With totals as (
         select PolicyID,COUNT(*) as cnt from inserted
         group by PolicyID
     )
     merge into ExistingPolicies t
     using totals s
     on
        t.PolicyID = s.PolicyID
     when matched then update set PolicyCount = PolicyCount + s.cnt
     when not matched then insert (PolicyID,PolicyCount) values (s.PolicyID,s.cnt);
go
CREATE TRIGGER T_Policy_D
on Policy
instead of delete
as
     ;With totals as (
         select PolicyID,COUNT(*) as cnt from deleted
         group by PolicyID
     )
     merge into ExistingPolicies t
     using totals s
     on
        t.PolicyID = s.PolicyID
     when matched and t.PolicyCount = s.cnt then delete
     when matched then update set PolicyCount = PolicyCount - s.cnt;
go
CREATE TRIGGER T_Policy_U
on Policy
instead of update
as
     ;With totals as (
         select PolicyID,SUM(cnt) as cnt
         from
            (select PolicyID,1 as cnt from inserted
             union all
             select PolicyID,-1 as cnt from deleted
             ) t
         group by PolicyID
     )
     merge into ExistingPolicies t
     using totals s
     on
        t.PolicyID = s.PolicyID
     when matched and t.PolicyCount = -s.cnt then delete
     when matched then update set PolicyCount = PolicyCount + s.cnt
     when not matched then insert (PolicyID,PolicyCount) values (s.PolicyID,s.cnt);
go

(代码未经测试但应接近正确)

答案 2 :(得分:0)

我认为在这里使用检查约束是个好主意。

编写一个接受Policy_id作为参数的函数,并执行查询以检查策略表中是否存在策略,并返回简单的1(存在)或0(不存在)。

然后将您的报告表格上的检查约束设置为dbo.MyFunction(Policy_Id)=1

那就是它。