我有典型的Invoice / InvoiceItems主/详细信息表(每本书和教程都使用这些表作为示例)。我还有一个" Proforma"包含有时与发票有关的发票的数据的表格。两者都链接到发票中的每个项目,其中一列可选地引用形式表,如下所示:
id | id_invoice | id_proforma | amount ....... and a bunch of irrelevant stuff
-----------------------------------------------
1 | 1 | null | 100
2 | 1 | null | 40
3 | 2 | 3 | 1000
4 | 3 | 4 | 473
5 | 3 | 4 | 139
基本上,发票中的每个项都可以链接到形式表。还有一个业务规则,即每个形式只能在一张发票中使用(在同一张发票中的许多项目中都可以使用它)。
目前该规则在应用程序端实施,但这存在并发问题,因为2个用户可以同时获取相同的形式,系统会让它通过。我的目的是让数据库在一些前端视觉线索之外对此进行验证,但到目前为止,我还没有为这种特殊情况提供方法。
过滤的唯一索引可以很好地发挥作用,除非相同的形式可以在同一发票中使用两次,所以我的问题是,如何让DB服务器强制执行该规则?
数据库引擎可以是SQL 2012或后者以及从快递到企业的任何版本。
答案 0 :(得分:0)
您可以创建用户定义的标量函数,如果形式ID和发票ID组合有效,则返回TRUE。然后在表上放置一个检查约束,要求函数返回true。像这样(调整以适合您的表名称/需求):
-- Here's the function:
create function dbo.svfIsCombinationValid (
@id_invoice int
, @id_proforma int
)
returns bit
as
begin;
declare @return bit = 1;
if exists (
select 1
from dbo.YourInvoiceProformaXRefTable
where id_proforma = @id_proforma
and id_invoice <> @id_invoice
)
begin;
set @return = 0;
end;
return @return;
end;
之后,您可以更改表并添加检查约束:
alter table dbo.YourInvoiceProformaXRefTable
add constraint CK_YourInvoiceProformaXRefTable_UniqueInvoiceProforma
check (dbo.svfIsCombinationValid(id_invoice,id_proforma)=1);
这对于空值是可以的(多个id_invoice可以具有id_proforma NULL值)。但如果两个值都不为null,则组合必须为NEW或与现有行相同。