但参照表和被参照表为同一个表时,该怎样插入数据

new妞宁 2010-04-29 12:00:04
例如下面我建的一个课程表Course,其中Cpno是外码,被参照表是Course本身,被参照列是Cno

create table Course
(Cno char(9) primary key,
Cname char(20),
Cpno char(4),
Ccredit smallint,
foreign key Cpno references Course(Cno)
);

当要插入数据时,Cpno必需参照Cno,所以好像存在一个问题,例如插入一个元组:

insert into Course
values('1','数据库','5','4');

因为第三个'5'必须参照主码Cno,要想插入主码为'5'的元组,则必须知道它的Cpno,如此下去,就是一直持续了,
后来想了一下下面的插入语句,将其得Cpno设置为空,但它参照的主码取值唯一且不空,所以还是错误的。请大家帮忙考虑一下,不胜感激……
...全文
759 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
new妞宁 2012-10-30
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 的回复:]

先把完整性约束去掉,创建表,再用ALTER加上约束条件
[/Quote]
数据是随时加入 更新的
menghuanguaishou 2012-08-16
  • 打赏
  • 举报
回复
先把完整性约束去掉,创建表,再用ALTER加上约束条件
dawugui 2010-04-29
  • 打赏
  • 举报
回复
既然这么麻烦,不如在程序中去判断.
htl258_Tony 2010-04-29
  • 打赏
  • 举报
回复
但效率比触发器更差
htl258_Tony 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 newningning 的回复:]
引用 14 楼 htl258 的回复:
引用 11 楼 newningning 的回复:
引用 9 楼 htl258 的回复:
引用 8 楼 newningning 的回复:
引用 7 楼 dawugui 的回复:
那就对所有课程加个序号就行了.

好像还是不行!

触发器可行

不用触发器咋办?
为什么不用

虽然触发器比约束更加灵活,可以实施比 foreign ke……
[/Quote]也可以写自定义函做,约束调用函数
new妞宁 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 htl258 的回复:]
引用 11 楼 newningning 的回复:
引用 9 楼 htl258 的回复:
引用 8 楼 newningning 的回复:
引用 7 楼 dawugui 的回复:
那就对所有课程加个序号就行了.

好像还是不行!

触发器可行

不用触发器咋办?
为什么不用
[/Quote]
虽然触发器比约束更加灵活,可以实施比 foreign key约束,check 约束更为复杂的检查和操作,但是这个问题应该是不用触发器也可以解决的!
htl258_Tony 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 newningning 的回复:]
引用 9 楼 htl258 的回复:
引用 8 楼 newningning 的回复:
引用 7 楼 dawugui 的回复:
那就对所有课程加个序号就行了.

好像还是不行!

触发器可行

不用触发器咋办?
[/Quote]为什么不用
new妞宁 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 mackzhaozhonggang 的回复:]
你插入的数据和表中的列是不是相对应的,insert into Course (列名)values('1','数据库','5','4');
[/Quote]
当然是!
htl258_Tony 2010-04-29
  • 打赏
  • 举报
回复
create table Course
(Cno char(9) primary key,
Cname char(20),
Cpno char(4),
Ccredit smallint--,
--foreign key Cpno references Course(Cno)
);
GO
create trigger my_tr on Course
for insert,update
as
if not exists(
select top 1 1 from inserted i
where exists(
select top 1 1 from Course
where Cpno=i.Cno
)
)
begin
raiserror('您插入的值不在Cno范围内,请重新输入!',16,1)
rollback
end
go
new妞宁 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 htl258 的回复:]
引用 8 楼 newningning 的回复:
引用 7 楼 dawugui 的回复:
那就对所有课程加个序号就行了.

好像还是不行!

触发器可行
[/Quote]
不用触发器咋办?
mackzhaozhonggang 2010-04-29
  • 打赏
  • 举报
回复
你插入的数据和表中的列是不是相对应的,insert into Course (列名)values('1','数据库','5','4');

htl258_Tony 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 newningning 的回复:]
引用 7 楼 dawugui 的回复:
那就对所有课程加个序号就行了.

好像还是不行!
[/Quote]
触发器可行
new妞宁 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 dawugui 的回复:]
那就对所有课程加个序号就行了.
[/Quote]
好像还是不行!
dawugui 2010-04-29
  • 打赏
  • 举报
回复
那就对所有课程加个序号就行了.
dawugui 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 newningning 的回复:]
就像学生的选课一样,修一门之前必须要修完另一门课,而且必须是学校开的课程,即在course中已存在的课程,所以Cpno是先修课,Cno是课程号。
[/Quote]
那就对所以课程加个序号就行了.
new妞宁 2010-04-29
  • 打赏
  • 举报
回复
就像学生的选课一样,修一门之前必须要修完另一门课,而且必须是学校开的课程,即在course中已存在的课程,所以Cpno是先修课,Cno是课程号。
dawugui 2010-04-29
  • 打赏
  • 举报
回复
同一个表这么做没有意义或者根本做不到.
htl258_Tony 2010-04-29
  • 打赏
  • 举报
回复
同表,
htl258_Tony 2010-04-29
  • 打赏
  • 举报
回复
但你在同步,做这样完全相同的一列,有意义吗
htl258_Tony 2010-04-29
  • 打赏
  • 举报
回复
同表应该用约束或触发器

34,575

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧