programing

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

lastcode 2023. 6. 1. 22: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만 읽을 수 있다는 것을 아는 것이 훨씬 좋습니다.

저는 주로 데미안의 접근 방식을 사용합니다. 데미안의 접근 방식은 항상 저에게 효과가 있었습니다. 하지만 다음과 같은 한 가지 추가 사항도 있습니다.

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 맛에 따라 다름).

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

트리거 대신을 구현하여 데이터베이스 내에서 이러한 유형의 비즈니스 논리를 시행할 수 있습니다.

트리거에는 레코드가 테이블에 이미 있는지 확인하고 레코드가 있으면 삽입을 롤백하는 논리가 포함될 수 있습니다.

이제 한 걸음 뒤로 돌아가서 더 큰 그림을 살펴보겠습니다. 예를 들어 구성 파일이나 환경 변수에 이 정보를 저장할 수 있는 대안적이고 더 적합한 방법이 있는지 궁금합니다.

저는 이것이 매우 오래된 것이라는 것을 알지만, BIG를 생각하는 대신 때때로 작은 것이 다음과 같은 ID 정수를 사용하는 것이 더 낫다고 생각합니다.

Create Table TableWhatever
(
    keycol int primary key not null identity(1,1) 
         check(keycol =1),
    Col2 varchar(7)
)

이런 식으로 다른 행을 삽입하려고 할 때마다 ID P 키가 1을 제외한 모든 값을 허용하지 않으므로 확인 제약 조건에 따라 행을 삽입할 수 없습니다.

다음은 Y 또는 N(예: 응용 프로그램 잠금 상태)을 유지하는 하나의 행만 포함할 수 있는 잠금 유형 테이블에 대한 솔루션입니다.

열 하나로 테이블을 만듭니다.하나의 열에 Y 또는 N만 넣을 수 있도록 체크 제약 조건을 붙였습니다. (또는 1 또는 0 또는 무엇이든)

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

그런 다음 SIGNAL(DB2) 또는 RAISEROR(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';

나한테 효과가 있어요.

이름이 IsActive인 기본 키에 비트 필드를 사용합니다.따라서 최대 2개의 행이 있을 수 있으며 유효한 행을 얻으려면 Settings(설정)에서 *를 선택합니다. 테이블 이름이 Settings(설정)인 경우 IsActive(IsActive) = 1을 선택합니다.

가장 쉬운 방법은 ID 필드를 값 1(또는 임의의 숫자...)로 계산된 열로 정의한 다음 ID에 대한 고유 인덱스를 고려하는 것입니다.

CREATE TABLE [dbo].[SingleRowTable](
  [ID]  AS ((1)),
  [Title] [varchar](50) NOT NULL,
   CONSTRAINT [IX_SingleRowTable] UNIQUE NONCLUSTERED 
   (
      [ID] ASC
   )
) ON [PRIMARY]

테이블의 삽입 작업에 트리거를 쓸 수 있습니다.누군가가 테이블에 새 행을 삽입하려고 할 때마다 삽입 트리거 코드에서 최신 행을 제거하는 논리를 실행합니다.

오래된 질문이지만 작은 열 유형의 IDENTITY(MAX,1)를 사용하는 것은 어떻습니까?

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

여기서는 데이터베이스의 첫 번째 항목 이후에도 동일한 보이지 않는 값을 만들 수 있습니다.예: 학생 표:Id:int firstname:char 여기 입력란에서는 기본 키 제약으로 인해 잠금 bla를 쓰는 것 외에 첫 번째 항목 이후로 제한되는 동일한 값을 ID 열에 지정해야 하므로 영원히 하나의 행만 있습니다.이것이 도움이 되길 바랍니다!

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

반응형