테이블의 최대 행 수를 1로 제한하는 방법


22

SQL Server 데이터베이스에 구성 테이블이 있으며이 테이블에는 행이 하나만 있어야합니다. 미래의 개발자가 이것을 이해하도록 돕기 위해 하나 이상의 데이터 행이 추가되는 것을 막고 싶습니다. 아래와 같이 트리거를 사용하기로 선택했습니다 ...

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 기능이 누락 되었습니까?


2
원래 접근 방식이 작동하지 않은 이유에 대한 설명과 마찬가지로 : 대신 트리거를 사용합니다. 즉, insert 문 대신 코드가 실행됩니다. 따라서 삽입이 이루어 지려면 트리거의 일부로 삽입해야합니다.
Scott M

답변:


52

이 두 가지 제약 조건은 다음과 같습니다.

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값을, 그리고 CHECK모든 행이 동일한 그래서 제약 ID값 (임의의로 선택을 1).
조합하여 거의 반대되는 두 제약 조건은 행 수를 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!
) ;

24

ID를 상수 값으로 평가되는 계산 열로 정의하고 해당 열을 고유하게 선언 할 수 있습니다.

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

9

트리거를 사용할 수도 있습니다.

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

    if @tableCount > 50
    begin
        rollback
    end
go

1

조금 이상한 요구 사항이지만 허허 :) 테이블에 제약 조건이 있고 테이블에 대한 업데이트 (삽입 또는 삭제 없음) 만 허용 할 수 있습니까?

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

그것은 그것을하는 약간의 해키 방법입니다. 저장 된 절차를 통해 구성에 변경 사항을 적용 하여이 모든 논리를 처리 할 수 ​​있지 않습니까?


2
아무도 테이블에서 삭제할 수 없도록하십시오. 누군가 삭제 한 다음 다시 삽입하려고하면 허용되지 않는 ID 2로 삽입을 시도합니다.
Mat

5
이것은 ID0또는 음수 값을 갖는 것을 금지하지 않습니다 . 그리고 @Mat이 가리키는 것처럼 첫 번째 행을 삭제하면 다른 행을 삽입하려고하면 실패합니다.
ypercubeᵀᴹ

2
"홀수 요구 사항"인 경우,보다 일반적인 EAV 디자인 대신 단일 행 테이블을 구성 설정에 사용하는 것이 좋습니다 . 전자의 장점은 열을 적절한 데이터 형식으로 만들 수 있고 적절한 제약 조건을 더 쉽게 추가 할 수 있다는 것입니다.
Kenny Evitt 2016 년

2
어쩌면 나는 이전의 의견에서 명확하지 않았습니다. "ID가 0 또는 음수 값을 갖는 것을 금지하지 않습니다" 의 부작용 은 테이블이 2 개 이상의 행으로 끝날 수 있다는 것입니다. identity 속성은 고유 제한 조건을 의미하지 않습니다.
ypercubeᵀᴹ

3
@ ypercubeᵀᴹ이 말한 것을 설명하기 위해이 솔루션을 사용하면 예를 들어 INSERT INTO dbo.Config DEFAULT VALUES;한 번만 할 수 있지만 SET IDENTITY_INSERT dbo.Config ON; INSERT INTO dbo.Config (ID) VALUES (0); SET IDENTITY_INSERT dbo.Config OFF; 여러 번 수행 할 수 있으며 여러 행 테이블 이 생깁니다 .
Andriy M
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.