调用用户定义函数的唯一约束

时间:2014-10-30 10:47:12

标签: sql sql-server tsql sql-server-2012 unique-constraint

我有两张桌子:

create table primarytable ( value nvarchar(50) not null primary key type not null ) create table secondarytable ( value nvarchar(50) not null, synonym nvarchar(50) not null, constraint pk_secondarytable primary key (value, synonym) )

因此,每个值可以有许多同义词。我想要做的是拒绝添加更多的同义词,如果同义词+ gettypeforvalue(值)不是唯一的。

所以,例如。

primarytable:
-------------
value        | type
-------------|---------
Toyota F-150 | carmake
GMC Canyon   | carmake

secondarytable:
---------------
value        | synonym
-------------|---------------
Toyota F-150 | toyota pickup
GMC Canyon   | gmc pickup

没问题,但是

primarytable:
-------------
value        | type
-------------|----------------
Toyota F-150 | carmake
GMC Canyon   | carmake

secondarytable:
---------------
value        | synonym
-------------|-----
Toyota F-150 | pickup
GMC Canyon   | pickup

不应该没问题(同义词+值的关联类型不是唯一的)。

我尝试过制作一个功能

create function uf_getTypeForValue(@value nvarchar(50))
    returns nvarchar(50)
as
begin
    return (select type from primarytable p where p.value = @value)
end

然后为辅助表添加唯一约束:

alter table secondarytable add constraint uc_secondarytable_synonym_unique_for_type
unique (synonym, uf_getTypeForValue(value))

但是,我在此Incorrect syntax near '('.

上收到错误消息

我之前已经成功调用了check - 约束中的函数,所以显然我不能用唯一约束这样做吗?

我只需要知道一种语法技巧,或者我该如何以另一种方式实现?

1 个答案:

答案 0 :(得分:1)

从语法here,我认为你只能为唯一约束做列。但是,我看到" CHECK"约束可以包含逻辑表达式。所以你可以用它来完成它。在函数内部进行行计数查询,如下所示:

--drop function NumberOfSimilarRows
CREATE FUNCTION NumberOfSimilarRows(@synonymToCheck nvarchar(50), @valueToCheck nvarchar(50))
RETURNS int
AS 
BEGIN
   DECLARE @rowcount int
   SELECT @rowcount = COUNT(*) FROM secondarytable WHERE synonym = @synonymToCheck and value = dbo.uf_getTypeForValue(@valueToCheck)
   RETURN @rowcount
END;

然后你可以在CHECK约束中使用它,如:

ALTER TABLE secondarytable
ADD CONSTRAINT uc_secondarytable_synonym_unique_for_type 
CHECK (dbo.NumberOfSimilarRows(synonym, value) <= 1 );