我不太确定你想要做什么——我已经整理了一个演示,展示了你可能希望事情起作用的一种方式。我们实际上创建了一个包含更多列的表,然后使用几个触发器将其隐藏在视图后面,以确保一切正常。
表格:
create table dbo.CommissionTier (
ID int not null,
MinCommission decimal not null,
MaxCommission decimal not null,
constraint PK_CommissionTier PRIMARY KEY (ID),
constraint UQ_CommissionTier_RangeValidation UNIQUE (ID,MinCommission,MaxCommission) --This is to support our FK below
)
go
create table dbo._LenderCommission (
ID int not null,
Commission decimal not null,
CommissionTier int not null,
_MinCommission decimal not null,
_MaxCommission decimal not null,
constraint PK__LenderCommission PRIMARY KEY (ID),
constraint CK__LenderCommission_InRange CHECK (
_MinCommission < Commission and --Inclusive or exclusive bound? <= or <
Commission < _MaxCommission --Ditto?
),
constraint FK__LenderCommission_Tier
FOREIGN KEY (CommissionTier)
references dbo.CommissionTier (ID), --This FK isn't actually needed
constraint FK__LenderCommission_Tier_Range
FOREIGN KEY (CommissionTier,_MinCommission,_MaxCommission)
references dbo.CommissionTier(ID,MinCommission,MaxCommission) on update cascade
)
视图(从现在起您将其视为原始表):
create view dbo.LenderCommission
with schemabinding
as
select
ID,
Commission,
CommissionTier
from
dbo._LenderCommission
go
您可能不需要这个,但是当视图伪装成表时,我倾向于始终放置索引,并为其赋予与原始主键相同的名称:
create unique clustered index PK_LenderCommission on dbo.LenderCommission(ID)
现在有几个触发器可以进行一些必要的房屋清洁:
create trigger dbo.T_LenderCommission_I
on dbo.LenderCommission
instead of insert
as
set nocount on
insert into dbo._LenderCommission (ID,Commission,CommissionTier,_MinCommission,_MaxCommission)
select i.ID,i.Commission,i.CommissionTier,ct.MinCommission,ct.MaxCommission
from
inserted i
inner join
dbo.CommissionTier ct
on
i.CommissionTier = ct.ID
go
create trigger dbo.T_LenderCommission_U
on dbo.LenderCommission
instead of update
as
set nocount on
update lc
set
Commission = i.Commission,
CommissionTier = i.CommissionTier,
_MinCommission = ct.MinCommission,
_MaxCommission = ct.MaxCommission
from
dbo._LenderCommission lc
inner join
inserted i
on
lc.ID = i.ID
inner join
dbo.CommissionTier ct
on
i.CommissionTier = ct.ID
现在我们填充它们:
insert into CommissionTier(ID,MinCommission,MaxCommission) values
(1,0,1000),
(2,1000,2000),
(3,2000,3000)
go
insert into LenderCommission(ID,Commission,CommissionTier) values
(1,500,1),
(2,750,1),
(3,1500,2)
现在出现一些错误:
--This produces an error:
insert into LenderCommission(ID,Commission,CommissionTier) values
(4,500,2)
go
--This produces an error:
update LenderCommission set Commission = 2500 where ID=2
go
--This *doesn't* produce an error because the new value matches the new tier
update LenderCommission set Commission = 2500,CommissionTier = 3 where ID=2
go
--This is okay, we're adjusting one of the tiers
update CommissionTier set MaxCommission = 1550 where ID = 2
go
--This produces an error, because the cascading foreign key updated the values:
update LenderCommission set Commission = 1600 where ID = 3
作为上述的替代方案CK__LenderCommission_InRange
,您可以创建一个计算列来执行相同的检查并采用合适的值,而不是使用 :
CommissionOutOfRange AS
CASE WHEN Commission < MinCommission THEN -1
CASE WHEN Commission > MaxCommission THEN 1
ELSE 0 END
现在您可以快速在表格中搜索超出范围的值(但没有什么能阻止它们被创建