如何将外键链接到 Oracle 中的自动递增主键?

Posted

技术标签:

【中文标题】如何将外键链接到 Oracle 中的自动递增主键?【英文标题】:How to link foreign key to auto-incremented primary key in Oracle? 【发布时间】:2013-02-04 10:54:14 【问题描述】:

我有两个表,它们的公共字段是 Load_ID。第一个的PK和第二个的FK是一对多的关系。例如:

Table1:
1, someValue

Table2:
1, value1, ...  
1, value2, ... 
1, value3, ... 

我已经在一个 ASP.NET 类中嵌入了实际的插入语句,其中的值取自用户输入:

 "INSERT INTO Compare_Header_Table VALUES
(compare_sequence.nextval, //other values are inserted here)

我用来自动增加 P​​K 的序列是CREATE SEQUENCE compare_sequence; 即使没有创建触发器或指定任何参数,这似乎也可以工作,因为序列默认为增量 1 和初始值 1,这对我的目的来说很好。

我遇到问题的地方是尝试将 FK 从第二个表链接到第一个表的 PK。我不能简单地使用 compare_sequence.currval,因为我有一个单独的插入方法每个表,所以我每次都创建一个新连接。我不想将这些组合成一种方法,因为这将涉及更改我的 C# 类的逻辑结构,我宁愿保持原样。

对如何完成这项工作有任何建议吗?

【问题讨论】:

您不应该为应该在单个事务中的插入使用单独的连接。 @a_horse_with_no_name 很高兴知道以供将来参考。最初我只是将它插入一张桌子,但后来它被分成了两张。现在一次完成所有插入将涉及一些我宁愿避免的重大重组。 【参考方案1】:

您可以做的是使用 RETURNING 原因来获取分配的值:

 INSERT INTO Compare_Header_Table (ID) VALUES
        (compare_sequence.nextval)
 returning id into some_value;

这个some_value 是一个局部变量,你需要将它从你的第一堂课中传递出来并传递给第二堂课。您这样做的精确程度取决于您的架构。

顺便说一句,我确实希望当您说“我每次都在创建一个新连接”时,这是一些 C# 行话,而您并不是每次都真正创建一个新的数据库连接。因为那是一项相当昂贵的手术。

另一件事是,如果您在不同的会话中创建父记录和子记录,那么事务会发生什么?您必须提交每个插入(否则,当您尝试插入子项时,外键验证将看不到新的父记录)。

【讨论】:

hmmm 好吧,在这种情况下,我可能不得不考虑修改我的 C# 代码。【参考方案2】:

如果您希望在单独的会话中完成INSERT 操作,您需要从第一条语句中检索生成的密钥并将其传递给将数据插入table2 的方法。在不需要数据库往返的情况下检索生成的密钥的一种方法是执行类似

INSERT INTO compare_header_table
  VALUES( compare_sequence.nextval,
          ... )
 RETURNING name_of_primary_key_column
      INTO :bind_variable

【讨论】:

以上是关于如何将外键链接到 Oracle 中的自动递增主键?的主要内容,如果未能解决你的问题,请参考以下文章

Django模型基于外键自动递增主键

如何将自动递增的主键也用作外键?

Django如何将外键传递给ModelForm字段

sqlserver字段如何自动更新

将外键传递给 Rails 中的部分渲染

将主键更改为自动递增