2014-10-30 48 views
1

我有兩個表:唯一約束調用用戶定義的函數

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(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之前,顯然我不能這樣做與獨特的約束?

有沒有簡單的語法技巧我需要知道或者我該如何做到這一點?

回答

0

從語法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); 
+0

它也可以通過觸發檢查...不知道哪更好。 – Anssssss 2014-11-07 23:00:44