简单的CHECK约束并不那么简单

时间:2011-08-26 21:21:57

标签: sql-server check-constraints

第二次编辑:所涉及功能的源代码如下:

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对于FileTypeId为1是唯一的。您可以根据需要插入相同的FileId,但只能插入FileTypeId为1的单行。

无法正常工作的方法:

1)dbo.fn_CheckFileTypeId返回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两次时,允许第二次插入。

非常感谢!

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

为什么不将FieldTypeID和Field都作为表的主键?

或至少表上的唯一索引。这应该可以解决你的问题。