sql >> データベース >  >> RDS >> Sqlserver

複数テーブルのチェック制約を作成するにはどうすればよいですか?

    データの整合性を強化するのに最適な場所はデータベースです。一部の開発者は、意図的であろうとなかろうと、一貫性のないものをデータベースに忍び込ませる方法を見つけるので安心してください!

    チェック制約のある例を次に示します。

    CREATE FUNCTION dbo.SignupMismatches()
    RETURNS int
    AS BEGIN RETURN (
        SELECT count(*)
        FROM Shift s
        LEFT JOIN EventVolunteer ev
        ON ev.EventId = s.EventId
        AND ev.VolunteerId = s.VolunteerId
        WHERE ev.Id is null
    ) END
    go
    ALTER TABLE Shift ADD CONSTRAINT chkSignup CHECK (dbo.SignupMismatches() = 0);
    go
    CREATE FUNCTION dbo.OverlapMismatches()
    RETURNS int
    AS BEGIN RETURN (
        SELECT count(*)
        FROM Shift a
        JOIN Shift b
        ON a.id <> b.id
        AND a.Start < b.[End]
        AND a.[End] > b.Start
        AND a.VolunteerId = b.VolunteerId
    ) END
    go
    ALTER TABLE Shift ADD CONSTRAINT chkOverlap CHECK (dbo.OverlapMismatches() = 0);
    

    新しいデータ整合性チェックのテストは次のとおりです。

    insert into Volunteer (name) values ('Dubya')
    insert into Event (name) values ('Build Wall Around Texas')
    
    -- Dubya tries to build a wall, but Fails because he's not signed up
    insert into Shift (VolunteerID, EventID, Description, Start, [End]) 
        values (1, 1, 'Dunbya Builds Wall', '2010-01-01', '2010-01-02')
    
    -- Properly signed up?  Good
    insert into EventVolunteer (VolunteerID, EventID) 
        values (1, 1)
    insert into Shift (VolunteerID, EventID, Description, Start, [End]) 
        values (1, 1, 'Dunbya Builds Wall', '2010-01-01', '2010-01-03')
    
    -- Fails, you can't start the 2nd wall before you finished the 1st
    insert into Shift (VolunteerID, EventID, Description, Start, [End]) 
        values (1, 1, 'Dunbya Builds Second Wall', '2010-01-02', '2010-01-03')
    

    テーブルの定義は次のとおりです。

    set nocount on
    if OBJECT_ID('Shift') is not null
        drop table Shift
    if OBJECT_ID('EventVolunteer') is not null
        drop table EventVolunteer
    if OBJECT_ID('Volunteer') is not null
        drop table Volunteer
    if OBJECT_ID('Event') is not null
        drop table Event
    if OBJECT_ID('SignupMismatches') is not null
        drop function SignupMismatches
    if OBJECT_ID('OverlapMismatches') is not null
        drop function OverlapMismatches
    
    create table Volunteer (
        id int identity primary key
    ,   name varchar(50)
    )
    create table Event (
        Id int identity primary key
    ,   name varchar(50)
    )
    create table Shift (
        Id int identity primary key
    ,   VolunteerId int foreign key references Volunteer(id)
    ,   EventId int foreign key references Event(id)
    ,   Description varchar(250)
    ,   Start datetime
    ,   [End] datetime
    )
    create table EventVolunteer (
        Id int identity primary key
    ,   VolunteerId int foreign key references Volunteer(id)
    ,   EventId int foreign key references Event(id)
    ,   Location varchar(250)
    ,   [Day] datetime
    ,   Description varchar(250)
    )
    


    1. 「PostgreSQL9.0HighPerformance」の本が出ました

    2. oracleのMODIFYCOLUMN-null許容に設定する前に、列がnull許容かどうかを確認するにはどうすればよいですか?

    3. Oracleで連結文字列を生成する高速な方法

    4. SQL Serverのビューの列を参照する外部キーを使用できますか?