【问题标题】:Unique constraint calling user defined function调用用户定义函数的唯一约束
【发布时间】:2014-10-30 10:47:11
【问题描述】:

我有两张桌子:

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) )

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

例如

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

然后给secondarytable添加一个唯一约束:

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

但是,我在此 Incorrect syntax near '('. 上收到错误消息

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

是否有我需要知道的语法技巧,或者我该如何以另一种方式完成?

【问题讨论】:

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


    【解决方案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 );
    

    【讨论】:

    • 也可以通过触发器检查...不确定哪个更好。
    猜你喜欢
    • 1970-01-01
    • 2018-01-19
    • 2011-10-02
    • 2020-08-22
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    相关资源
    最近更新 更多