SQL中一个联合主键(a,b)中的一个字段a可以作为外键吗?

时间:2021-12-22 13:42:30
rt。。。
SQL中一个联合主键(a,b)中的一个字段a可以作为外键吗?

15 个解决方案

#1


• 外键约束并不仅仅可以与另一表的主键约束相链接,它还可以定义为引用另一个表中 UNIQUE 约束的列。
• 如果在 FOREIGN KEY 约束的列中输入非 NULL 值,则此值必须在被引用列中存在;否则,将返回违反外键约束的错误信息。 若要确保验证了组合外键约束的所有值,请对所有参与列指定 NOT NULL。
• FOREIGN KEY 约束仅能引用位于同一服务器上的同一数据库中的表。 跨数据库的引用完整性必须通过触发器实现。 有关详细信息,请参阅 CREATE TRIGGER (Transact-SQL)。
• FOREIGN KEY 约束可引用同一表中的其他列。 此行为称为自引用。
• 在列级指定的 FOREIGN KEY 约束只能列出一个引用列。 此列的数据类型必须与定义约束的列的数据类型相同。
• 在表级指定的 FOREIGN KEY 约束所具有的引用列数目必须与约束列列表中的列数相同。 每个引用列的数据类型也必须与列表中相应列的数据类型相同。
• 对于表可包含的引用其他表的 FOREIGN KEY 约束的数目或其他表所拥有的引用特定表的 FOREIGN KEY 约束的数目,数据库引擎都没有预定义的限制。 尽管如此,可使用的 FOREIGN KEY 约束的实际数目还是受硬件配置以及数据库和应用程序设计的限制。 建议表中包含的 FOREIGN KEY 约束不要超过 253 个,并且引用该表的 FOREIGN KEY 约束也不要超过 253 个。
• 对于临时表不强制 FOREIGN KEY 约束。
• 如果在 CLR 用户定义类型的列上定义外键,则该类型的实现必须支持二进制排序。 有关详细信息,请参阅 CLR 用户定义类型。
• 仅当 FOREIGN KEY 约束引用的主键也定义为类型 varchar(max) 时,才能在此约束中使用类型为 varchar(max) 的列。

来自 < http://msdn.microsoft.com/zh-cn/library/ms189049.aspx

#2



--行不行试试不就知道了?



drop table t_1

create table t_1
(
col1 varchar(10) not null,
col2 varchar(10)not null
)
drop table t_2

create table t_2
(
col1 varchar(10),
col2 varchar(10)
)

alter table t_1
add constraint pk_id primary key(col1,col2)  
命令已成功完成。

alter table t_2
add constraint fk_col1 foreign key(col1) references t_1(col1)

消息 1776,级别 16,状态 0,第 1 行
在被引用表 't_1' 中没有与外键 'fk_col1' 中的引用列列表匹配的主键或候选键。
消息 1750,级别 16,状态 0,第 1 行
无法创建约束。请参阅前面的错误消息。


alter table t_1
add constraint UQ_COL1
unique(col1)
命令已成功完成。

alter table t_2
add constraint fk_col1 foreign key(col1) references t_1(col1)
命令已成功完成。



#3


不可以,建立外键的一条规则:  外键列引用的 必须是 唯一的,举2个例子:
例子1:
A(a)  如果 a字段是A表主键 ----〉表明a在A表中 是唯一的------〉可以被引用
B  (b)      此时b字段基于A表的a字段建立外键是 合法的

列子2:
A(a1,a2)  如果 a1和a2两个字段是A表主键 ----〉a1或者a2字段在A表中 不是唯一的-----〉不可以被单独引用 (如果要引用,必须是a1和a2两个列同时被引用)
B  (b)      此时b字段基于A表的a1字段建立外键是 非法的

#4


哦!首先感谢各位及时的答复,可能是我没有表述清楚,应该是:
建表t1(a,b,c...)   其中(a,b)是联合主键,建表t2(a,b,c...)其中a是主键,现在要设置t1.a为参考t2.a的外键,
即:ALTER TABLE [dbo].[t1]  ADD  CONSTRAINT [FK_12] FOREIGN KEY([a])
REFERENCES [dbo].[t2] ([a]);这个为啥不行?

#5


外键引用要求被引用的表上有主键,其实是为了唯一性,而组合主键的话,单纯一个列无法保证唯一(最起码sqlserver认为)

#6


SQL中一个联合主键(a,b)中的一个字段a可以作为外键吗?,我这表述能力太差了  或者我始终把概念混淆了,现在是被引用的那个字段已经是它的那个表的主键了,引用的这个是一个表中联合主键的一个字段 ,但是会报错   不知道为什么?

#7


引用 4 楼 u012412518 的回复:
哦!首先感谢各位及时的答复,可能是我没有表述清楚,应该是:
建表t1(a,b,c...)   其中(a,b)是联合主键,建表t2(a,b,c...)其中a是主键,现在要设置t1.a为参考t2.a的外键,
即:ALTER TABLE [dbo].[t1]  ADD  CONSTRAINT [FK_12] FOREIGN KEY([a])
REFERENCES [dbo].[t2] ([a]);这个为啥不行?
这个可以,t2.a已经是主键了,保证其唯一性,没有违反创建外键的规则。你测试的情况如果有错,请贴出所有代码

#8


是不是这个意思:
表t1,有一个字段a,是主鍵。
表t2,有两个字段a、b,是联合主键。
现在是想要表t2的字段a设定成表t1字段a的外键。

我试过了,可以这样操作啊。

#9


IF OBJECT_ID('ta') IS NOT NULL
DROP TABLE dbo.ta
GO

CREATE TABLE Ta
(
ID INT NOT NULL,
Val VARCHAR(32)
)

ALTER TABLE ta ADD PRIMARY KEY(ID)
GO


IF OBJECT_ID('tb') IS NOT NULL
DROP TABLE dbo.TB
GO

CREATE TABLE Tb
(
ID1 INT NOT NULL,
ID2 INT NOT NULL,
Val VARCHAR(32)
)
GO

ALTER TABLE TB ADD PRIMARY KEY(ID1,ID2)
ALTER TABLE TB ADD CONSTRAINT pk_id FOREIGN KEY (ID1) REFERENCES ta(ID) 
GO
SQL中一个联合主键(a,b)中的一个字段a可以作为外键吗?

#10


问题已经解决,我把表给删了,重新建立一遍,建表的时候指定外键,就可以了,在最开始建完之后修改的时候会报错,以为是权限不够,就换了owner用户来试,可以了但是刷新表的键不会出现建的外键,抽风了,果断表删了重建,OK了!

#11


有可能是表中数据不对,导致不能建外键。

#12


虽然没有完美了解,但也算解决了,结贴喽。。。

#13


楼主,想问一下,你的使用的配置文件还是注解,能不能私聊下,我的测试通过了,但是数据库中添加不上数据

#14


我也遇到这个问题啊  真是日了狗了 


Create table Zj_Class
(
 Gx_No char(6) ,
 Xq_No char (2) ,
 Xy_No char(2),
 Class_No char(10) unique ,
 Class_Age int, 
 Class_Major char(20),
 Class_Header char(20),
 primary key(Gx_no,Xq_no,Xy_no,Class_NO),
 Constraint Class_Xy foreign key(Gx_no,Xq_no,Xy_no) references Zj_XueYuan
 )
  
--班级(学校编号,校区编号,学院编号,班级编号,年级,专业,班长)

Create table Zj_Stu
(
 Class_No char(10)  ,
 Stu_No char(12)  ,
 Stu_Name char(20),
 Stu_Sex char(4),
 Stu_Age int,
 Stu_Address char(20),
 Stu_Tel char(12)
 primary key(Class_no,Stu_no),
 Constraint Stu_Class foreign key(Class_NO) references Zj_Class
 )
--学生(班级编号,学号,姓名,性别,年龄,籍贯,电话) 

#15


引用 5 楼 DBA_Huangzj 的回复:
外键引用要求被引用的表上有主键,其实是为了唯一性,而组合主键的话,单纯一个列无法保证唯一(最起码sqlserver认为)
 



所以要怎么做才可以啊

#1


• 外键约束并不仅仅可以与另一表的主键约束相链接,它还可以定义为引用另一个表中 UNIQUE 约束的列。
• 如果在 FOREIGN KEY 约束的列中输入非 NULL 值,则此值必须在被引用列中存在;否则,将返回违反外键约束的错误信息。 若要确保验证了组合外键约束的所有值,请对所有参与列指定 NOT NULL。
• FOREIGN KEY 约束仅能引用位于同一服务器上的同一数据库中的表。 跨数据库的引用完整性必须通过触发器实现。 有关详细信息,请参阅 CREATE TRIGGER (Transact-SQL)。
• FOREIGN KEY 约束可引用同一表中的其他列。 此行为称为自引用。
• 在列级指定的 FOREIGN KEY 约束只能列出一个引用列。 此列的数据类型必须与定义约束的列的数据类型相同。
• 在表级指定的 FOREIGN KEY 约束所具有的引用列数目必须与约束列列表中的列数相同。 每个引用列的数据类型也必须与列表中相应列的数据类型相同。
• 对于表可包含的引用其他表的 FOREIGN KEY 约束的数目或其他表所拥有的引用特定表的 FOREIGN KEY 约束的数目,数据库引擎都没有预定义的限制。 尽管如此,可使用的 FOREIGN KEY 约束的实际数目还是受硬件配置以及数据库和应用程序设计的限制。 建议表中包含的 FOREIGN KEY 约束不要超过 253 个,并且引用该表的 FOREIGN KEY 约束也不要超过 253 个。
• 对于临时表不强制 FOREIGN KEY 约束。
• 如果在 CLR 用户定义类型的列上定义外键,则该类型的实现必须支持二进制排序。 有关详细信息,请参阅 CLR 用户定义类型。
• 仅当 FOREIGN KEY 约束引用的主键也定义为类型 varchar(max) 时,才能在此约束中使用类型为 varchar(max) 的列。

来自 < http://msdn.microsoft.com/zh-cn/library/ms189049.aspx

#2



--行不行试试不就知道了?



drop table t_1

create table t_1
(
col1 varchar(10) not null,
col2 varchar(10)not null
)
drop table t_2

create table t_2
(
col1 varchar(10),
col2 varchar(10)
)

alter table t_1
add constraint pk_id primary key(col1,col2)  
命令已成功完成。

alter table t_2
add constraint fk_col1 foreign key(col1) references t_1(col1)

消息 1776,级别 16,状态 0,第 1 行
在被引用表 't_1' 中没有与外键 'fk_col1' 中的引用列列表匹配的主键或候选键。
消息 1750,级别 16,状态 0,第 1 行
无法创建约束。请参阅前面的错误消息。


alter table t_1
add constraint UQ_COL1
unique(col1)
命令已成功完成。

alter table t_2
add constraint fk_col1 foreign key(col1) references t_1(col1)
命令已成功完成。



#3


不可以,建立外键的一条规则:  外键列引用的 必须是 唯一的,举2个例子:
例子1:
A(a)  如果 a字段是A表主键 ----〉表明a在A表中 是唯一的------〉可以被引用
B  (b)      此时b字段基于A表的a字段建立外键是 合法的

列子2:
A(a1,a2)  如果 a1和a2两个字段是A表主键 ----〉a1或者a2字段在A表中 不是唯一的-----〉不可以被单独引用 (如果要引用,必须是a1和a2两个列同时被引用)
B  (b)      此时b字段基于A表的a1字段建立外键是 非法的

#4


哦!首先感谢各位及时的答复,可能是我没有表述清楚,应该是:
建表t1(a,b,c...)   其中(a,b)是联合主键,建表t2(a,b,c...)其中a是主键,现在要设置t1.a为参考t2.a的外键,
即:ALTER TABLE [dbo].[t1]  ADD  CONSTRAINT [FK_12] FOREIGN KEY([a])
REFERENCES [dbo].[t2] ([a]);这个为啥不行?

#5


外键引用要求被引用的表上有主键,其实是为了唯一性,而组合主键的话,单纯一个列无法保证唯一(最起码sqlserver认为)

#6


SQL中一个联合主键(a,b)中的一个字段a可以作为外键吗?,我这表述能力太差了  或者我始终把概念混淆了,现在是被引用的那个字段已经是它的那个表的主键了,引用的这个是一个表中联合主键的一个字段 ,但是会报错   不知道为什么?

#7


引用 4 楼 u012412518 的回复:
哦!首先感谢各位及时的答复,可能是我没有表述清楚,应该是:
建表t1(a,b,c...)   其中(a,b)是联合主键,建表t2(a,b,c...)其中a是主键,现在要设置t1.a为参考t2.a的外键,
即:ALTER TABLE [dbo].[t1]  ADD  CONSTRAINT [FK_12] FOREIGN KEY([a])
REFERENCES [dbo].[t2] ([a]);这个为啥不行?
这个可以,t2.a已经是主键了,保证其唯一性,没有违反创建外键的规则。你测试的情况如果有错,请贴出所有代码

#8


是不是这个意思:
表t1,有一个字段a,是主鍵。
表t2,有两个字段a、b,是联合主键。
现在是想要表t2的字段a设定成表t1字段a的外键。

我试过了,可以这样操作啊。

#9


IF OBJECT_ID('ta') IS NOT NULL
DROP TABLE dbo.ta
GO

CREATE TABLE Ta
(
ID INT NOT NULL,
Val VARCHAR(32)
)

ALTER TABLE ta ADD PRIMARY KEY(ID)
GO


IF OBJECT_ID('tb') IS NOT NULL
DROP TABLE dbo.TB
GO

CREATE TABLE Tb
(
ID1 INT NOT NULL,
ID2 INT NOT NULL,
Val VARCHAR(32)
)
GO

ALTER TABLE TB ADD PRIMARY KEY(ID1,ID2)
ALTER TABLE TB ADD CONSTRAINT pk_id FOREIGN KEY (ID1) REFERENCES ta(ID) 
GO
SQL中一个联合主键(a,b)中的一个字段a可以作为外键吗?

#10


问题已经解决,我把表给删了,重新建立一遍,建表的时候指定外键,就可以了,在最开始建完之后修改的时候会报错,以为是权限不够,就换了owner用户来试,可以了但是刷新表的键不会出现建的外键,抽风了,果断表删了重建,OK了!

#11


有可能是表中数据不对,导致不能建外键。

#12


虽然没有完美了解,但也算解决了,结贴喽。。。

#13


楼主,想问一下,你的使用的配置文件还是注解,能不能私聊下,我的测试通过了,但是数据库中添加不上数据

#14


我也遇到这个问题啊  真是日了狗了 


Create table Zj_Class
(
 Gx_No char(6) ,
 Xq_No char (2) ,
 Xy_No char(2),
 Class_No char(10) unique ,
 Class_Age int, 
 Class_Major char(20),
 Class_Header char(20),
 primary key(Gx_no,Xq_no,Xy_no,Class_NO),
 Constraint Class_Xy foreign key(Gx_no,Xq_no,Xy_no) references Zj_XueYuan
 )
  
--班级(学校编号,校区编号,学院编号,班级编号,年级,专业,班长)

Create table Zj_Stu
(
 Class_No char(10)  ,
 Stu_No char(12)  ,
 Stu_Name char(20),
 Stu_Sex char(4),
 Stu_Age int,
 Stu_Address char(20),
 Stu_Tel char(12)
 primary key(Class_no,Stu_no),
 Constraint Stu_Class foreign key(Class_NO) references Zj_Class
 )
--学生(班级编号,学号,姓名,性别,年龄,籍贯,电话) 

#15


引用 5 楼 DBA_Huangzj 的回复:
外键引用要求被引用的表上有主键,其实是为了唯一性,而组合主键的话,单纯一个列无法保证唯一(最起码sqlserver认为)
 



所以要怎么做才可以啊