web-dev-qa-db-ja.com

テーブルの行の最大数を1に制限する方法

SQL Serverデータベースに構成テーブルがあり、このテーブルには1行しかありません。今後の開発者がこれを理解できるように、複数行のデータが追加されないようにしたいと思います。以下のように、これにトリガーを使用することを選択しました...

ALTER TRIGGER OnlyOneConfigRow
    ON [dbo].[Configuration]
    INSTEAD OF INSERT
AS
BEGIN
    DECLARE @HasZeroRows BIT;
    SELECT  @HasZeroRows = CASE
        WHEN COUNT (Id) = 0 THEN 1
        ELSE 0
    END
    FROM
        [dbo].[Configuration];

    IF EXISTS(SELECT [Id] FROM inserted) AND @HasZeroRows = 0
    BEGIN
        RAISERROR ('You should not add more than one row into the config table. ', 16, 1)    
    END
END

これはエラーをスローしませんが、最初の行が入ることを許可していません。

また、これよりもテーブルに挿入できる行の数を1つに制限するより効果的で自己説明的な方法はありますか? SQL Serverの組み込み機能が不足していますか?

23
Dib

これらの2つの制約は次のようになります。

CREATE TABLE dbo.Configuration
( ConfigurationID TINYINT NOT NULL DEFAULT 1,
  -- the rest of the columns
  CONSTRAINT Configuration_PK 
    PRIMARY KEY (ConfigurationID),
  CONSTRAINT Configuration_OnlyOneRow 
    CHECK (ConfigurationID = 1)
) ;

両方が必要ですPRIMARY KEY(またはUNIQUE制約)したがって、同じID値を持つ2つの行はありません。また、CHECK制約により、すべての行に同じID値があります。 (任意に1)。
組み合わせて、2つのほぼ反対の制約により、行数が0または1に制限されます。


0列で構成される主キーを許可する架空のDBMS(現在のSQL実装ではこの構成は許可されていません)では、これも解決策になります。

CREATE TABLE dbo.Configuration
( -- no ConfigurationID needed at all
  -- the rest of the columns
  CONSTRAINT Configuration_PK 
    PRIMARY KEY ()                -- 0 columns!
) ;
53
ypercubeᵀᴹ

IDを定数値に評価される計算列として定義し、その列が一意であることを宣言できます。

CREATE TABLE dbo.Configuration
(
  ID AS CAST(1 AS tinyint),  -- or: AS bit
  ...  -- other columns
  CONSTRAINT UQ_Configuration_ID UNIQUE (ID)
);
24
Andriy M

トリガーを使用することもできます。

create trigger LimitTable
on YourTableToLimit
after insert
as
    declare @tableCount int
    select @tableCount = Count(*)
    from YourTableToLimit

    if @tableCount > 50
    begin
        rollback
    end
go
9
user98113

少し奇妙な要件のようですが、冗談です:)テーブルに制約を設定して、テーブルへの更新(挿入または削除は不可)のみを許可することができますか?

CREATE TABLE dbo.Config (
    ID INT identity(1,1), 
    CONFIGURATION VARCHAR(MAX),
    constraint ck_limitrows CHECK (ID <=1) 
    );

それはそれを行うための少し厄介な方法ですが、このすべてのロジックを処理できるストアドプロシージャを通じて構成の変更を強制するだけの方が良いでしょうか?

1
Mat