source

SQL Server에서 외부 키를 작성하려면 어떻게 해야 합니까?

ittop 2023. 4. 7. 21:54
반응형

SQL Server에서 외부 키를 작성하려면 어떻게 해야 합니까?

SQL Server 오브젝트 작성 코드를 "수작업으로 코딩"한 적이 없습니다.또한 SQL Server와 Postgres 간에 외부 키의 열화가 다른 것 같습니다.지금까지의 SQL은 다음과 같습니다.

drop table exams;
drop table question_bank;
drop table anwser_bank;

create table exams
(
    exam_id uniqueidentifier primary key,
    exam_name varchar(50),
);
create table question_bank
(
    question_id uniqueidentifier primary key,
    question_exam_id uniqueidentifier not null,
    question_text varchar(1024) not null,
    question_point_value decimal,
    constraint question_exam_id foreign key references exams(exam_id)
);
create table anwser_bank
(
    anwser_id           uniqueidentifier primary key,
    anwser_question_id  uniqueidentifier,
    anwser_text         varchar(1024),
    anwser_is_correct   bit
);

쿼리를 실행하면 다음 오류가 나타납니다.

Msg 8139, 레벨 16, 상태 0, 9행 외부 키의 참조 열 수가 참조 열 수(표 'question_bank')와 다릅니다.

오류를 발견할 수 있습니까?

제약조건을 스스로 작성하려면 ALTER 탭을 사용할 수 있습니다.LE

alter table MyTable
add constraint MyTable_MyColumn_FK FOREIGN KEY ( MyColumn ) references MyOtherTable(PKColumn)

인라인 작성에는 Sara Chipps가 언급한 구문은 권장하지 않습니다.단, 제 자신의 제약조건에 이름을 붙이고 싶기 때문입니다.

create table question_bank
(
    question_id uniqueidentifier primary key,
    question_exam_id uniqueidentifier not null,
    question_text varchar(1024) not null,
    question_point_value decimal,
    constraint fk_questionbank_exams foreign key (question_exam_id) references exams (exam_id)
);

다음 명령을 사용하여 외부 키 제약 조건을 지정할 수도 있습니다.

CONSTRAINT your_name_here FOREIGN KEY (question_exam_id) REFERENCES EXAMS (exam_id)

AlexCuse의 답변은 마음에 듭니다만, 외부 키 제약 조건을 추가할 때마다 주의해야 할 것은 참조 테이블의 행에 있는 참조 컬럼에 대한 업데이트 처리 방법, 특히 참조 테이블의 행 삭제를 처리하는 방법입니다.

다음과 같이 구속조건을 작성할 경우:

alter table MyTable
add constraint MyTable_MyColumn_FK FOREIGN KEY ( MyColumn ) 
references MyOtherTable(PKColumn)

참조 테이블에 대응하는 행이 있는 경우 참조 테이블 내의 갱신 또는 삭제가 에러와 함께 표시됩니다.

그게 네가 원하는 행동일 수도 있지만 내 경험상 그렇지 않은 경우가 훨씬 더 많아.

대신 다음과 같이 작성할 경우:

alter table MyTable
add constraint MyTable_MyColumn_FK FOREIGN KEY ( MyColumn ) 
references MyOtherTable(PKColumn)
on update cascade 
on delete cascade

상위 테이블에서 업데이트 및 삭제하면 참조 테이블에서 대응하는 행이 업데이트 및 삭제됩니다.

(디폴트를 변경할 것을 제안하는 것은 아닙니다.디폴트는 주의할 필요가 있습니다.이것은 좋은 것입니다.단지, 이것은, 콘센트를 만드는 사람이 항상 신경써야 할 사항이라고 하는 것입니다.)

이것은 테이블을 작성할 때 다음과 같이 할 수 있습니다.

create table ProductCategories (
  Id           int identity primary key,
  ProductId    int references Products(Id)
               on update cascade on delete cascade
  CategoryId   int references Categories(Id) 
               on update cascade on delete cascade
)
create table question_bank
(
    question_id uniqueidentifier primary key,
    question_exam_id uniqueidentifier not null constraint fk_exam_id foreign key references exams(exam_id),
    question_text varchar(1024) not null,
    question_point_value decimal
);

그것도 좋다.좀 더 직관적인 구조일까요?

임의의 테이블에 외부 키를 작성하려면

ALTER TABLE [SCHEMA].[TABLENAME] ADD FOREIGN KEY (COLUMNNAME) REFERENCES [TABLENAME](COLUMNNAME)
EXAMPLE
ALTER TABLE [dbo].[UserMaster] ADD FOREIGN KEY (City_Id) REFERENCES [dbo].[CityMaster](City_Id)

쿼리를 사용하여 두 테이블의 열을 관계로 만들려면 다음을 수행하십시오.

Alter table Foreign_Key_Table_name add constraint 
Foreign_Key_Table_name_Columnname_FK
Foreign Key (Column_name) references 
Another_Table_name(Another_Table_Column_name)

사용자처럼 외부 키를 직접 작성하지는 않지만 어떤 이유로 스크립트가 필요한 경우 보통 ms sql server 관리 스튜디오를 사용하여 작성하고 변경을 저장하기 전에 [Table Designer]| [Generate Change Script]를 선택합니다.

이 스크립트는 외부 키를 사용하여 테이블을 만드는 것으로, 참조 무결성 제약 조건 sql-server를 추가했습니다.

create table exams
(  
    exam_id int primary key,
    exam_name varchar(50),
);

create table question_bank 
(
    question_id int primary key,
    question_exam_id int not null,
    question_text varchar(1024) not null,
    question_point_value decimal,
    constraint question_exam_id_fk
       foreign key references exams(exam_id)
               ON DELETE CASCADE
);

네크로맨싱.
사실 이걸 제대로 하는 게 좀 더 까다로워.

먼저 참조할 외부 키를 설정하는 컬럼의 프라이머리 키가 존재하는지 확인해야 합니다.

이 예에서는 테이블 T_ZO_SYS_Language_에 있는 외부 키입니다.dbo를 참조하는 양식이 생성됩니다.T_SYS_Language_Forms.LANG_UID

-- First, chech if the table exists...
IF 0 < (
    SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_TYPE = 'BASE TABLE'
    AND TABLE_SCHEMA = 'dbo'
    AND TABLE_NAME = 'T_SYS_Language_Forms'
)
BEGIN
    -- Check for NULL values in the primary-key column
    IF 0 = (SELECT COUNT(*) FROM T_SYS_Language_Forms WHERE LANG_UID IS NULL)
    BEGIN
        ALTER TABLE T_SYS_Language_Forms ALTER COLUMN LANG_UID uniqueidentifier NOT NULL 

        -- No, don't drop, FK references might already exist...
        -- Drop PK if exists 
        -- ALTER TABLE T_SYS_Language_Forms DROP CONSTRAINT pk_constraint_name 
        --DECLARE @pkDropCommand nvarchar(1000) 
        --SET @pkDropCommand = N'ALTER TABLE T_SYS_Language_Forms DROP CONSTRAINT ' + QUOTENAME((SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
        --WHERE CONSTRAINT_TYPE = 'PRIMARY KEY' 
        --AND TABLE_SCHEMA = 'dbo' 
        --AND TABLE_NAME = 'T_SYS_Language_Forms' 
        ----AND CONSTRAINT_NAME = 'PK_T_SYS_Language_Forms' 
        --))
        ---- PRINT @pkDropCommand 
        --EXECUTE(@pkDropCommand) 

        -- Instead do
        -- EXEC sp_rename 'dbo.T_SYS_Language_Forms.PK_T_SYS_Language_Forms1234565', 'PK_T_SYS_Language_Forms';


        -- Check if they keys are unique (it is very possible they might not be) 
        IF 1 >= (SELECT TOP 1 COUNT(*) AS cnt FROM T_SYS_Language_Forms GROUP BY LANG_UID ORDER BY cnt DESC)
        BEGIN

            -- If no Primary key for this table
            IF 0 =  
            (
                SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
                WHERE CONSTRAINT_TYPE = 'PRIMARY KEY' 
                AND TABLE_SCHEMA = 'dbo' 
                AND TABLE_NAME = 'T_SYS_Language_Forms' 
                -- AND CONSTRAINT_NAME = 'PK_T_SYS_Language_Forms' 
            )
                ALTER TABLE T_SYS_Language_Forms ADD CONSTRAINT PK_T_SYS_Language_Forms PRIMARY KEY CLUSTERED (LANG_UID ASC)
            ;

            -- Adding foreign key
            IF 0 = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_NAME = 'FK_T_ZO_SYS_Language_Forms_T_SYS_Language_Forms') 
                ALTER TABLE T_ZO_SYS_Language_Forms WITH NOCHECK ADD CONSTRAINT FK_T_ZO_SYS_Language_Forms_T_SYS_Language_Forms FOREIGN KEY(ZOLANG_LANG_UID) REFERENCES T_SYS_Language_Forms(LANG_UID); 
        END -- End uniqueness check
        ELSE
            PRINT 'FSCK, this column has duplicate keys, and can thus not be changed to primary key...' 
    END -- End NULL check
    ELSE
        PRINT 'FSCK, need to figure out how to update NULL value(s)...' 
END 

항상 이 구문을 사용하여 두 테이블 사이에 외부 키 제약 조건을 만듭니다.

Alter Table ForeignKeyTable
Add constraint `ForeignKeyTable_ForeignKeyColumn_FK`
`Foreign key (ForeignKeyColumn)` references `PrimaryKeyTable (PrimaryKeyColumn)`

예.

Alter Table tblEmployee
Add constraint tblEmployee_DepartmentID_FK
foreign key (DepartmentID) references tblDepartment (ID)

언급URL : https://stackoverflow.com/questions/48772/how-do-i-create-a-foreign-key-in-sql-server

반응형