1

A as bool2 つの列 (と)を持つテーブルがありますB as text。これらの列は次のようになります。

  1. どちらもヌル
  2. A が False の場合、B は null である必要があります
  3. A が True の場合、B は null であってはなりません

ルールがあります。行の追加または更新時にこれらのルールをチェックするストアド プロシージャまたは関数を作成したいと考えています (トリガー経由)。ストアドプロシージャと関数のどちらが優れていますか? 機能する場合、どのタイプですか?一般的に、どのバリアントが最適ですか (ブール値を返すか、その他の方法など)?

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 を使用します。
Person を挿入すると、その年齢が 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 に答える