Sql约束方法返回false值

时间:2011-11-25 09:25:43

标签: sql sql-server function tsql sql-server-2012

我在sql中遇到了一个约束方法的问题。

这是我的表

CREATE TABLE [relations].[CompoundKey_Contacts](
    [compoundId] [varchar](32) NOT NULL,
    [companyId] [varchar](32) NULL,
    [personId] [varchar](32) NULL,
    [contactInfoId] [varchar](32) NOT NULL)

当您向此表添加行时,应检查该表中是否已存在此人员和公司的组合。为此我使用约束函数

约束

ALTER TABLE [relations].[CompoundKey_Contacts]  WITH NOCHECK ADD  CONSTRAINT [CK_CompoundKey_Contacts] CHECK  (([relations].[doesThisCompoundKeyExist]([personId],[companyId])='NO'))
GO

ALTER TABLE [relations].[CompoundKey_Contacts] CHECK CONSTRAINT [CK_CompoundKey_Contacts]
GO

功能

CREATE function [relations].[doesThisCompoundKeyExist](
    @personId varchar(32),
    @companyId varchar(32)
)
returns varchar(3)
as
begin
    declare @exists varchar(32)

    if(@companyId is null and @personId is null)
      set @exists = 'YES'
    else if(@personId is null)
        if exists(select compoundId from relations.CompoundKey_Contacts where personId is null AND companyId = @companyId)
            set @exists = 'YES' 'This is where to code enters, but it should come to the else and return 'NO'
        else
            set @exists = 'NO'
    else if(@companyId is null)
        if exists(select compoundId from relations.CompoundKey_Contacts where personId = @personId AND companyId is null)
            set @exists = 'YES'
        else
            set @exists = 'NO'
    else if exists(
        select compoundId from relations.CompoundKey_Contacts where personId = @personId AND companyId = @companyId
        )
        set @exists = 'YES'
    else
        set @exists = 'NO'
    return @exists
end;

我的插入语句失败

insert into relations.CompoundKey_Contacts (companyId, contactInfoId, personId, compoundId) values ('COM-000015945', 'INF-000144406', null, 'CPK-000000067');

问题是这个。当我使用唯一插入在表上运行插入时,它仍然失败。我当然检查它依赖于select语句是唯一的。这是有趣的部分。当我调试它并检查它失败的地方并分解该代码部分并在不使用函数的情况下自由运行时它的行为应该如此,所以如果它不在函数中运行,则以下代码可以工作

if exists(select compoundId from relations.CompoundKey_Contacts where personId is null AND companyId = 'COM-000015945')
                print 'YES'
            else
                print 'NO' 'Returns NO as it should.

这是我收到的错误消息

The INSERT statement conflicted with the CHECK constraint "CK_CompoundKey_Contacts". The conflict occurred in database "domas", table "relations.CompoundKey_Contacts".
The statement has been terminated.

我在Sql Server 2012和Sql Server'DENALI'CTP3

上运行它

2 个答案:

答案 0 :(得分:4)

在检查约束中使用UDF将无法正常工作,如您所见

如果需要额外的逻辑

,请对计算列使用唯一约束
ALTER TABLE CompoundKey_Contacts
    ADD CompoundKey AS ISNULL(personID, 'NOPERSONID') + ISNULL(companyId, 'NOCOMPANYID');
ALTER TABLE CompoundKey_Contacts WITH CHECK
    ADD CONSTRAINT UQ_CompoundKey_Contacts_CompoundKey UNIQUE (CompoundKey);

或简单的唯一约束

ALTER TABLE CompoundKey_Contacts WITH CHECK
    ADD CONSTRAINT UQ_CompoundKey_OtherUnique UNIQUE (personID, companyId);

答案 1 :(得分:2)

personId,companyId上创建唯一约束或唯一索引。

不要尝试对UDF使用检查约束,因为它效率低且无论如何都很难纠正。