跟踪 SQL 中的新主键
Posted
技术标签:
【中文标题】跟踪 SQL 中的新主键【英文标题】:Keeping track of new primary keys in SQL 【发布时间】:2011-12-05 11:50:50 【问题描述】:抱歉,这是一个很长的问题,但它涉及数据库的一般问题:
我正在使用 sqlite/jdbc(在这种情况下),并且我正在尝试跟踪在向表中添加行时创建的自动 ID。该数据库有一个主表“Person”和称为“training”和“induction”的其他表。这个想法是人名和其他基本细节进入“人”表,一个人很多人有很多“培训”和“入职”。因此,我可以通过 SELECT * FROM INDUCTIONS WHERE PERSON_ID = 不管来查找给定人员的所有归纳。
问题在于创建数据库时,我必须添加一个人,然后跟踪他们获得的 AUTOINCREMENTing ID,然后在另一个表中使用该 ID 作为外键创建条目:
所以
int id = 0;
PreparedStatement prepPerson = conn.prepareStatement("insert into persons values (?, ?);");
prepPerson.setString(2, p.getName());
prepPerson.addBatch();
然后
PreparedStatement prepInductions = conn.prepareStatement("insert into inductions values (?, ?, ?, ?);");
Then loop over all the inductions
prepInductions.setInt(2, id);
prepInductions.setString(3, i.getSite());
prepInductions.setString(4, i.getExpiryDate());
prepInductions.addBatch();
我希望与数据库的交互是“原子的”,所以我想做
prepPerson.executeBatch();
prepInductions.executeBatch();
id++;
我意识到可以改为添加人员,执行 getGeneratedKeys(),然后使用新人员的正确 row_id 添加归纳,但我不希望在添加人员之后但在归纳之前发生异常。如果发生这种情况,那么我将不得不回滚时间并删除此人。
目前我知道我每次都从外部源重新创建数据库,我使用本地整数变量跟踪 row_id,我知道这很危险。
这种情况没有通用的解决方案吗?还是我非常担心与数据库的“原子”交互?
【问题讨论】:
请澄清一下为什么好的旧交易不适合您。 AFAIK sqlite 支持它们并且 setAutocommit(false) 将隐式启动一个新事务。 【参考方案1】:请使用getGeneratedKeys()
检索生成的 ID。
要保持数据完整性,请使用事务。通常,JDBC 使用“autoCommit”模式,但在这种情况下,您需要手动处理事务。
在您的连接上调用.setAutoCommit(false)
并使用.commit()
和.rollback()
提交或放弃更改。
(查看ConnectionJavadoc)。
【讨论】:
你的意思是rollback()
而不是abort()
(后者是为了强行关闭连接)?
感谢大家的快速回复。它现在点击自动提交的内容。根据示例,我在执行批次之前将其设置为 false 并在它们之后将其设置为 true ,但没有确切地意识到原因 - 我根本没有 .commit()
,但它仍然有效。所以你可以这么几个.executeBatch()
es,然后一个.commit()
,一旦你完成了?这正是我需要的。解决了。
@Mike 在处于活动事务中的连接上调用 autoCommit(true)
将调用 commit()
(如 javadoc 中所述)。
@马克。是的,这似乎工作得很好。 (另外,刚刚学会了关闭()结果集的缓慢方法。)再次感谢大家。【参考方案2】:
对于这样的场景,一般框架是......
Begin A Transaction
Create your primary entry
Collect the auto-generated key
Create your child entries
Commit The Transaction
然后,如果任何步骤失败,您可以Rollback the Transaction
。
在 SQLite 中,我相信 last_insert_rowid()
可用于在您第一次插入后获取自动生成的 id。
【讨论】:
【参考方案3】:您可以使用上面提供的代码,但请确保关闭自动提交。然后,一旦加载了该人的所有归纳,您就需要手动提交事务。或者遇到错误就回滚。
这是完全原子的。
【讨论】:
以上是关于跟踪 SQL 中的新主键的主要内容,如果未能解决你的问题,请参考以下文章