2011-08-26 53 views
1

第二編輯:對於所涉及的功能的源代碼如下:簡單檢查約束不是那麼簡單

ALTER FUNCTION [Fileserver].[fn_CheckSingleFileSource] (@fileId INT) 
RETURNS INT 
AS 
    BEGIN 
     -- Declare the return variable here 
     DECLARE @sourceCount INT ; 

     -- Add the T-SQL statements to compute the return value here 
     SELECT @sourceCount = COUNT(*) 
     FROM Fileserver.FileUri 
     WHERE FileId = @fileId 
       AND FileUriTypeId = Fileserver.fn_Const_SourceFileUriTypeId() ; 

     -- Return the result of the function 
     RETURN @sourceCount ; 

    END 

編輯:示例表是一種簡化。我需要它作爲Scaler Function/CHECK CONSTRAINT操作。現實世界的安排並不那麼簡單。

原始的問題:假設命名了fileURI

FileUriId,FILEID,FileTypeId

下表我需要寫一個檢查約束這樣的fileid是唯一爲1,你可以插入一個FileTypeId同樣的fileid只要你想多了,但只有一行,其中FileTypeId爲1

的方法沒有奏效:

1)dbo.fn_CheckFileType ID返回INT具有以下邏輯:SELECT Count(FileId) FROM FileUri WHERE FileTypeId = 1

2)ALTER TABLE FileUri ADD CONSTRAINT CK_FileUri_FileTypeId CHECK dbo.fn_CheckFileTypeId(FileId) <= 1

當我插入FILEID 1,FileTypeId 1兩次,第二插入件是允許的。

謝謝!

回答

4

您需要創建一個過濾唯一索引(SQL Server 2008中)

CREATE UNIQUE NONCLUSTERED INDEX ix ON YourTable(FileId) WHERE FileTypeId=1 

或索引視圖(2000和2005)

CREATE VIEW dbo.UniqueConstraintView 
WITH SCHEMABINDING 
AS 
SELECT FileId 
FROM dbo.YourTable 
WHERE FileTypeId = 1 

GO 
CREATE UNIQUE CLUSTERED INDEX ix ON dbo.UniqueConstraintView(FileId) 
+0

這是爲了這個評論。樣本是一種簡化,我應該說明。我很抱歉。真實世界的實例需要作爲檢查約束來工作。 –

+0

@Eric - 那麼[除非你使用快照隔離](http://sqlblog.com/blogs/hugo_kornelis/archive/2006/09/15/Snapshot-and-integrity-part-4.aspx)你的一般方法在問題中建議看起來應該起作用,儘管不如基於索引的約束有效。你使用快照嗎?如果不是,你確定函數代碼沒有錯誤嗎?你有沒有單獨測試? –

+0

我(可以預見)能夠稍微修改我的模式並使用您建議的簡單唯一約束方法。點頭。 –

1

爲什麼不讓FieldTypeID和Field都是表的主鍵?

或者表上至少有一個唯一索引。這應該可以解決你的問題。

+0

的OP只關心重複WHERE FileTypeId模擬這個= 1 –

+0

@馬丁史密斯,謝謝,我誤解了這個問題。 – Icarus

+0

Upvote for effort。你是沿着正確的路線,謝謝! –