简体   繁体   English

在一个查询中插入3个级别

[英]Insert 3 levels in one query

I have an Oracle data structure like this: 我有一个像这样的Oracle数据结构:

Clubs 俱乐部

Id
Name

A club can have many teams: 俱乐部可以有很多球队:

Teams 小组

Id
Name
ClubId

A team can have many players: 一个团队可以有很多球员:

Players 玩家

Id
Name
TeamId

How do I make an insert with a club with teams with players? 如何在俱乐部和球员组成的俱乐部中插入内容? If it is just a club with teams I can do: 如果这只是一个有团队合作的俱乐部,我可以做:

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

But how do I insert Players as well? 但是,如何插入播放器呢?

This doesn't work: 不起作用

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

Because 因为

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

This is a single statement needing the ClubIdSequence.nextval and TeamIdSequence.nextval. 这是一条需要ClubIdSequence.nextval和TeamIdSequence.nextval的语句。 These values are being retrieved and then the statement gets executed. 检索这些值,然后执行该语句。 Thus you get two teams with the same id. 因此,您将获得两个具有相同ID的团队。

With your first statement you could even swap currval and nextval: 使用第一个语句,您甚至可以交换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

It still does the same: excecute nextval, and then do the inserts with currval. 它仍然执行相同操作:执行nextval,然后使用currval进行插入。

When working with ids got from sequences, I highly recommend writing before-insert triggers reading the nextval of the appropriate sequence and fill the id. 当使用从序列中获得的ID时,我强烈建议编写插入前触发器,以读取适当序列的nextval并填充ID。 Thus the writer of an insert statement doesn't have to find the according sequence and can hence not be mistaken in choosing one. 因此,insert语句的编写者不必查找相应的序列,因此在选择一个序列时不会出错。 Also someone might be tempted to write an insert statement with id = max(id) + 1 oblivious to the fact that there even is a sequence to be used. 另外,可能有人会想编写一个id = max(id)+ 1的插入语句,而忽略了甚至还有一个要使用的序列的事实。

Once you are using triggers, you would simply omit the id in your insert statements. 使用触发器后,只需在插入语句中省略ID。

Still that doesn't solve your problem, because you would have to use currval, which gives the same value even when used more than once in one statement. 但这仍然不能解决您的问题,因为您将不得不使用currval,即使在一个语句中使用了多次以上,它也会提供相同的值。 (Strange enough it even gives you the current value after the first insert statement, ie neither the one before the two inserts nor the one after the two, as one would expect.) (足够奇怪的是,它甚至可以在第一个插入语句之后为您提供当前值,即不会像预期的那样在两个插入之前的一个或在两个插入之后的一个。)

So you end up with two scenarios: Either use sequences and not use insert all or use insert all and not use sequences. 因此,您最终遇到两种情况:要么使用序列而不使用全部插入,要么使用全部插入而不使用序列。 They just don't get along well. 他们只是相处不好。

Here is a solution without the use of sequences: 这是不使用序列的解决方案:

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

Insert all into Clubs (Name) Values ('Manchester United') into Teams (Name, ClubId) Values ('A-Team',max_id+1) into Clubs (Name) Values ('Manchester Apart') into Teams (Name, ClubId) Values ('B-Team',max_id+2) Select max(id) max_id from clubs 将全部插入俱乐部(名称)值(“曼彻斯特联队”)插入球队(名称,ClubId)值(“ A队”,max_id + 1)插入俱乐部(名称)值(“曼彻斯特公寓队”)插入球队(名称, ClubId)值('B-Team',max_id + 2)从俱乐部中选择max(id)max_id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM