1

我有一个有 2 列(A as boolB as text)的表,这些列可以是:

  1. 两者都是空的
  2. 如果 A 为 False,则 B 应为空
  3. 如果 A 为 True,则 B 不应为空

有规则。我想创建一个存储过程或函数来在添加或更新行时检查这些规则(通过触发器)。存储过程或函数哪个更好?如果是函数,是什么类型?一般来说,哪个变体是最好的(返回布尔值或其他方式等)?

4

2 回答 2

11

我认为您在使用CHECKConstraint

例子:

ALTER TABLE Xxx
  ADD CONSTRAINT chk_Xxx 
  CHECK ( (A IS NULL AND B IS NULL) 
       OR (A = 0 AND B IS NULL) 
       OR (A = 1 AND B IS NOT NULL)
        ) ;
于 2013-02-21T16:26:40.843 回答
2

我会使用连接到 UDF 的 CHECK CONSTRAINT。
这是一个愚蠢的例子,验证如果你插入一个人,他们的年龄将大于 17。

if NOT exists (select *  from sysobjects 
    where id = object_id('dbo.udfOlderThan17Check') and sysstat & 0xf = 0)
    BEGIN
        print 'Creating the stubbed version of dbo.udfOlderThan17Check'
        EXEC ( 'CREATE FUNCTION dbo.udfOlderThan17Check ( @j as smallint ) RETURNS bit AS BEGIN RETURN 0 END')
    END
GO


ALTER FUNCTION dbo.udfOlderThan17Check ( @Age smallint  )
    RETURNS bit AS
    BEGIN
        declare @exists int

        select @exists = 0

        if ( @Age IS NULL )
            BEGIN
                select @exists = 1 -- NULL VALUES SHOULD NOT BLOW UP THE CONSTRAINT CHECK   
            END

        if ( @exists = 0 )

        BEGIN

            if @Age > 17
                begin
                    select @exists = 1
                end     

            END

        return @exists
    END



GO



IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[Person]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    BEGIN
        DROP TABLE [dbo].[Person]
    END
GO


CREATE TABLE [dbo].[Person]
(
      PersonUUID [UNIQUEIDENTIFIER] NOT NULL DEFAULT NEWSEQUENTIALID()
    , Age smallint not null
)

GO


ALTER TABLE dbo.Person ADD CONSTRAINT PK_Person
PRIMARY KEY NONCLUSTERED (PersonUUID)
GO


ALTER TABLE dbo.Person
ADD CONSTRAINT [CK_Person_AgeValue] CHECK ([dbo].[udfOlderThan17Check]( [Age] ) != 0)
GO

以下是一些“测试”:

INSERT INTO dbo.Person (Age) values (33)
INSERT INTO dbo.Person (Age) values (16)

INSERT INTO dbo.Person (Age) select 333 UNION select 58
INSERT INTO dbo.Person (Age) select 444 UNION select 4

select * from dbo.Person
于 2013-02-21T16:29:16.977 回答