从插入的 DataSet 中获取主键以链接到其他插入

Posted

技术标签:

【中文标题】从插入的 DataSet 中获取主键以链接到其他插入【英文标题】:Obtaining the primary key from an inserted DataSet to chain into other insertions 【发布时间】:2019-02-07 12:25:00 【问题描述】:

假设我在 Oracle 数据库中有以下表

富:

+--------+---------+---------+
| id_foo | string1 | string2 |
+--------+---------+---------+
|      1 | foo     | bar     |
|      2 | baz     | bat     |
+--------+---------+---------+

酒吧:

+--------+-----------+--------+
| id_bar | id_foo_fk | string |
+--------+-----------+--------+
|      1 |         1 | boo    |
|      2 |         1 | bum    |
+--------+-----------+--------+

当我使用 Dataset 和 JDBC 插入 Foo 时,例如

Dataset<Row> fooDataset = //Dataset is initialized
fooDataset.write().mode(SaveMode.Append).jdbc(url, table, properties)

ID 由数据库自动生成。现在,当我需要保存Bar 时,使用相同的策略,我希望能够通过id_foo_fk 将其链接到Foo

我研究了一些可能性,例如按照this question 中的建议使用monotonically_increasing_id(),但这并不能解决问题,因为我需要数据库生成的ID。我尝试了this question 中的建议,但它导致了相同的问题,即唯一的非数据库 ID

也不可能再次从 JDBC 中选择,因为 string1string2 可能不是唯一的。也无法更改数据库。例如,我无法将其更改为 UUID,也无法为其添加触发器。这是一个我们只能使用的遗留数据库

我怎样才能做到这一点? Apache Spark 可以做到这一点吗?

【问题讨论】:

我是否正确理解FooBar 之间没有可以仅从数据中推断出的联系? 正确,除了外键没有其他链接 所以请原谅一个愚蠢的问题 - 但是你怎么知道记录在 Spark 中实际上是链接的?这意味着在某些时候 Foo 和 Bar 中的信息必须形成一行,对吧? 要创建Bar,我需要Foo,因为我需要Foo_ID。所以当我创建Bar 时,我在它之前创建了Foo 的一个实例,这个实例包含一个从数据库自动生成的ID。创建 Bar 需要此 ID。 嗯,我明白了这一点,但我觉得那里缺少一块拼图。假设我有一个元组(foo, bar)。我执行插入,然后取回 PK 1。然后我想插入Bar。我有id_foo_fkid_bar会由数据库生成,但是string(这里的“foo”)是从哪里来的呢? 【参考方案1】:

我不是 Java 专家,因此您必须研究数据库层以了解如何准确地进行操作,但您可以通过 3 种方法做到这一点:

如果您使用的数据库服务器能够(大多数情况下),您可以创建一个存储过程并从您的代码中调用它。 创建一个触发器,在第一次插入时返回 ID 号,并在下次插入数据库时​​使用它。 使用 UUID 并将其用作密钥,而不是数据库自动生成的密钥。

【讨论】:

不幸的是,无法更改数据库(我也将其添加到问题中) 很抱歉直到最后才读到,然后我看到的唯一选择是在将另一条记录插入另一个表之前查询该表。 oracle 有一个事务选项,可让您包装所有查询。使用 Max 运算符获取插入的最新 id。如果有任何问题,使用事务功能可以让您提交或回滚。 我不相信这会真正解决我的用例,但也许它可以为未来的用户解决。

以上是关于从插入的 DataSet 中获取主键以链接到其他插入的主要内容,如果未能解决你的问题,请参考以下文章

如何使主键以特定字母开头?

SQL怎么在有外键的主键表中插数据

如何从 aspx 中的 Gridview 行中检索主键以在 userControl.ascx 中使用?

设计 mySql 索引和主键以提高效率

从 Access 获取最后一个插入 ID

mysql 插入操作最多能插入多少条记录