2

我有一个这样的 Oracle 数据结构:

俱乐部

Id
Name

一个俱乐部可以拥有多支球队:

团队

Id
Name
ClubId

一个团队可以有很多玩家:

球员

Id
Name
TeamId

我如何插入包含有球员的球队的俱乐部?如果它只是一个有球队的俱乐部,我可以这样做:

Insert all 
into Clubs (Id, Name) Values (ClubIdSequence.nextval,'Manchester United')
into Teams (Name, ClubId) Values ('A-Team',ClubIdSequence.currval)
into Teams (Name, ClubId) Values ('B-Team',ClubIdSequence.currval)
Select * from dual

但是我如何插入播放器呢?

不起作用

Insert all 
into Clubs (Id, Name) Values (ClubIdSequence.nextval,'Manchester United')
into Teams (Id,Name, ClubId) Values (TeamIdSequence.nextval,'A-Team',ClubIdSequence.currval)
into Players (Name,Teamid) Values ('Michael Laudrup',TeamIdSequence.currval
into Teams (Id,Name, ClubId) Values (TeamIdSequence.nextval,'B-Team',ClubIdSequence.currval)
into Players (Name,Teamid) Values ('Brian Laudrup',TeamIdSequence.currval)
Select * from dual

因为

An UPDATE or INSERT statement attempted to insert a duplicate key.
        For Trusted Oracle configured in DBMS MAC mode, you may see
        this message if a duplicate entry exists at a different level
4

1 回答 1

1

这是需要 ClubIdSequence.nextval 和 TeamIdSequence.nextval 的单个语句。正在检索这些值,然后执行该语句。因此,您会得到两个具有相同 ID 的团队。

使用您的第一个语句,您甚至可以交换 currval 和 nextval:

Insert all 
into Clubs (Id, Name) Values (ClubIdSequence.currval,'Manchester United')
into Teams (Name, ClubId) Values ('A-Team',ClubIdSequence.nextval)
into Teams (Name, ClubId) Values ('B-Team',ClubIdSequence.currval)
Select * from dual

它仍然执行相同的操作:执行 nextval,然后使用 currval 进行插入。

在使用从序列中获取的 id 时,我强烈建议编写插入前触发器,以读取适当序列的 nextval 并填充 id。因此,插入语句的编写者不必找到相应的序列,因此在选择一个时不会出错。也有人可能会想用 id = max(id) + 1 编写插入语句,而忽略了甚至要使用序列的事实。

使用触发器后,您只需在插入语句中省略 id 即可。

但这仍然不能解决您的问题,因为您必须使用 currval,即使在一个语句中多次使用它也会给出相同的值。(奇怪的是,它甚至在第一个插入语句之后为您提供了当前值,即既不是两次插入之前的值,也不是两次插入之后的值,正如人们所期望的那样。)

所以你最终会遇到两种情况:要么使用序列而不使用全部插入,要么使用全部插入而不使用序列。他们只是相处得不好。

这是一个不使用序列的解决方案:

Insert all 
  into Clubs (id, Name) Values (max_id + 1, 'Manchester United')
  into Teams (Name, ClubId) Values ('A-Team',max_id + 1)
  into Clubs (id, Name) Values (max_id + 2, 'Manchester Apart')
  into Teams (Name, ClubId) Values ('B-Team',max_id + 2)
Select nvl(max(id),0) max_id from clubs

将所有值('Manchester United')插入到球队(名字,ClubId)值('A-Team',max_id+1)到俱乐部(名字)值('Manchester Apart')到球队(名字, ClubId) Values ('B-Team',max_id+2) 从俱乐部中选择 max(id) max_id

于 2013-09-27T08:45:51.460 回答