Como faço para criar uma chave estrangeira no SQL Server?

Eu nunca usei código de criação de object “codificado manualmente” para SQL Server e a decadência de chave estrangeira é aparentemente diferente entre o SQL Server e o Postgres. Aqui está o meu sql até agora:

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 ); 

Quando executo a consulta, recebo este erro:

Msg 8139, nível 16, estado 0, linha 9 Número de colunas de referência na chave externa difere do número de colunas referenciadas, tabela ‘question_bank’.

Você consegue identificar o erro?

 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) ); 

E se você quiser apenas criar a restrição por conta própria, você pode usar ALTER TABLE

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

Eu não recomendaria a syntax mencionada por Sara Chipps para criação em linha, apenas porque prefiro nomear minhas próprias restrições.

Você também pode nomear sua restrição de chave estrangeira usando:

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

Eu gosto da resposta do AlexCuse, mas algo que você deve prestar atenção sempre que você adicionar uma restrição de chave estrangeira é como você deseja atualizações na coluna referenciada em uma linha da tabela referenciada a ser tratada, e especialmente como você deseja excluir linhas no referenciado tabela a ser tratada.

Se uma restrição é criada assim:

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

.. então atualizações ou exclusões na tabela referenciada irão explodir com um erro se houver uma linha correspondente na tabela de referência.

Esse pode ser o comportamento que você quer, mas na minha experiência, muito mais comumente não é.

Se você, em vez disso, criar assim:

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

..as atualizações e exclusões na tabela pai resultarão em atualizações e exclusões das linhas correspondentes na tabela de referência.

(Não estou sugerindo que o padrão deva ser alterado, o padrão erra no lado da caucanvas, o que é bom. Só estou dizendo que é algo que uma pessoa que está criando restrições deve sempre prestar atenção .)

Isto pode ser feito, a propósito, ao criar uma tabela, como esta:

 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 ); 

– Isso vai funcionar também. Talvez uma construção um pouco mais intuitiva?

Para criar uma chave estrangeira em qualquer tabela

 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) 

Como você, eu não costumo criar foreign keys à mão, mas se por algum motivo eu precisar do script para fazê-lo, normalmente eu o crio usando o ms sql server management studio e antes de salvar as alterações, eu seleciono Table Designer | Gerar script de mudança

Se você quiser criar duas colunas de tabela em um relacionamento usando uma consulta, tente o seguinte:

 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) 

Necromancing.
Na verdade, fazer isso corretamente é um pouco mais complicado.

Primeiro você precisa verificar se a chave primária existe para a coluna para a qual deseja definir sua chave estrangeira.

Neste exemplo, uma chave estrangeira na tabela T_ZO_SYS_Language_Forms é criada, fazendo referência a 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 

Este script é sobre a criação de tabelas com chave estrangeira e eu adicionei a restrição de integridade referencial 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 );