我有两张桌子:
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
- 约束中的函数,所以显然我不能用唯一约束这样做吗?
我只需要知道一种语法技巧,或者我该如何以另一种方式实现?
答案 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 );