Programing

SQL Server : 단일 행을 포함하도록 테이블을 제한하는 방법은 무엇입니까?

lottogame 2020. 10. 29. 07:45
반응형

SQL Server : 단일 행을 포함하도록 테이블을 제한하는 방법은 무엇입니까?


내 애플리케이션의 구성 테이블에 단일 행을 저장하고 싶습니다. 이 테이블에 행을 하나만 포함 할 수 있도록 강제하고 싶습니다.

단일 행 제약 조건을 적용하는 가장 간단한 방법은 무엇입니까?


열 중 하나가 하나의 값만 포함 할 수 있는지 확인한 다음 기본 키로 만들거나 고유성 제약 조건을 적용합니다.

CREATE TABLE T1(
    Lock char(1) not null,
    /* Other columns */,
    constraint PK_T1 PRIMARY KEY (Lock),
    constraint CK_T1_Locked CHECK (Lock='X')
)

주로 구성을 저장하기 위해 다양한 데이터베이스에 이러한 테이블이 많이 있습니다. 구성 항목이 int 여야하는 경우 DB에서 int 만 읽을 수 있다는 사실을 아는 것이 훨씬 좋습니다.


나는 항상 나를 위해 잘 작동했던 Damien의 접근 방식을 사용하지만 한 가지 추가합니다.

CREATE TABLE T1(
    Lock char(1) not null DEFAULT 'X',
    /* Other columns */,
    constraint PK_T1 PRIMARY KEY (Lock),
    constraint CK_T1_Locked CHECK (Lock='X')
)

"DEFAULT 'X'"를 추가하면 잠금 열을 처리 할 필요가 없으며 테이블을 처음로드 할 때 잠금 값이 무엇인지 기억할 필요가 없습니다.


이 전략을 다시 생각할 수 있습니다. 비슷한 상황에서 필자는 과거 정보를 위해 이전 구성 행을 그대로 두는 것이 매우 중요하다는 사실을 종종 발견했습니다.

이를 위해 실제로 추가 열 creation_date_time(삽입 또는 업데이트 날짜 / 시간)과 현재 날짜 / 시간으로 올바르게 채워지는 삽입 또는 삽입 / 업데이트 트리거가 있습니다.

그런 다음 현재 구성을 가져 오려면 다음과 같이 사용합니다.

select * from config_table order by creation_date_time desc fetch first row only

(DBMS 맛에 따라 다름).

이렇게하면 복구 목적으로 기록을 유지하고 (테이블이 너무 커지지 만 가능성이 적을 경우 정리 절차를 시작할 수 있음) 최신 구성으로 계속 작업 할 수 있습니다.


INSTEAD OF 트리거구현 하여 데이터베이스 내에서 이러한 유형의 비즈니스 논리를 적용 할 수 있습니다 .

트리거는 테이블에 레코드가 이미 있는지 확인하는 논리를 포함 할 수 있으며있는 경우 삽입을 ROLLBACK합니다.

이제 더 큰 그림을보기 위해 뒤로 물러서서 아마도 구성 파일이나 환경 변수에이 정보를 저장할 수있는 대안이 있고 더 적합한 방법이 있는지 궁금합니다.


IsActive라는 이름의 기본 키에 비트 필드를 사용합니다. 따라서 최대 2 개의 행이있을 수 있으며 유효한 행을 가져 오는 SQL은 다음과 같습니다. select * from Settings where IsActive = 1 if the table is named Settings.


다음은 Y 또는 N (예 : 애플리케이션 잠금 상태)을 보유하는 하나의 행만 포함 할 수있는 잠금 유형 테이블에 대해 생각 해낸 솔루션입니다.

하나의 열이있는 테이블을 만듭니다. 한 열에 검사 제약을 두어 Y 또는 N 만 넣을 수 있습니다. (또는 1 또는 0 또는 무엇이든)

테이블에 "정상"상태로 한 행을 삽입합니다 (예 : N은 잠기지 않음을 의미 함).

그런 다음 SIGNAL (DB2) 또는 RAISERROR (SQL Server) 또는 RAISE_APPLICATION_ERROR (Oracle) 만있는 테이블에 INSERT 트리거를 만듭니다. 따라서 애플리케이션 코드가 테이블을 업데이트 할 수 있지만 INSERT는 실패합니다.

DB2 예 :

create table PRICE_LIST_LOCK
(
    LOCKED_YN       char(1)   not null  
        constraint PRICE_LIST_LOCK_YN_CK  check (LOCKED_YN in ('Y', 'N') )
);
--- do this insert when creating the table
insert into PRICE_LIST_LOCK
values ('N');

--- once there is one row in the table, create this trigger
CREATE TRIGGER ONLY_ONE_ROW_IN_PRICE_LIST_LOCK
   NO CASCADE 
   BEFORE INSERT ON PRICE_LIST_LOCK
   FOR EACH ROW
   SIGNAL SQLSTATE '81000'  -- arbitrary user-defined value
     SET MESSAGE_TEXT='Only one row is allowed in this table';

나를 위해 작동합니다.


You can write a trigger on the insert action on the table. Whenever someone tries to insert a new row in the table, fire away the logic of removing the latest row in the insert trigger code.


Old question but how about using IDENTITY(MAX,1) of a small column type?

CREATE TABLE [dbo].[Config](
[ID] [tinyint] IDENTITY(255,1) NOT NULL,
[Config1] [nvarchar](max) NOT NULL,
[Config2] [nvarchar](max) NOT NULL

IF NOT EXISTS ( select * from table )
BEGIN
    ///Your insert statement
END

Here we can also make an invisible value which will be the same after first entry in the database.Example: Student Table: Id:int firstname:char Here in the entry box,we have to specify the same value for id column which will restrict as after first entry other than writing lock bla bla due to primary key constraint thus having only one row forever. Hope this helps!

참고URL : https://stackoverflow.com/questions/3967372/sql-server-how-to-constrain-a-table-to-contain-a-single-row

반응형