qt - 如何使用 QSqlQuery 获取事务中先前插入的行的 ID

标签 qt transactions qtsql

我试图在事务范围内获取插入行的主键,因为我不想让数据库处于逻辑上不一致的状态。

我的问题是我找不到一种方法来检索以前执行的查询的 ID 值,我想将其用于下一个插入查询。在事务生效时查询 PostgreSQL 数据库显示非外键表中没有结果(该行尚未提交?)。我相信这是由于事务的隔离级别。

下面是我试图用生产代码做的事情,尽管为了清晰起见,我做了一些轻微的编辑并缩小到一个功能。 const int lastInsertId始终为 0,在这种情况下,这意味着未找到任何值(从技术上讲,toInt() 函数失败)。我尝试手动插入一个有效的非外键行,然后调用 LASTVAL()这产生了预期的结果 - 插入行的 ID。

那么,我做错了什么?我在这里遗漏或误解了什么?

void createEntityWithoutForiegnKeyConstraint(const QString &nameOfEntity)
{
  db_.transaction();

  QSqlQuery insertQuery(db_);
  insertQuery.prepare("INSERT INTO \"EntityWithoutForeignKey\" (\"name\") VALUES (:name);");

  insertQuery.bindValue(":name", nameOfEntity);
  execQuery(__LINE__, insertQuery);
  QSqlQuery lastIdQuery("SELECT LASTVAL();", db_); // auto executes
  const int lastInsertId = lastIdQuery.value(0).toInt();

  if (lastInsertId <= 0) // 0 is not a valid ID
    throw exception("Oh noes.");

  createEntityWithForeignKeyConstraint(lastInsertId, someData);

  if (!db_.commit())
    db_.rollback();
}

最佳答案

我意识到这是一个老问题,但在 Qt 5.10(可能更早)中有一个函数 QSqlQuery::lastInsertId()可以在 QSqlQuery::exec() 之后调用.

如果您使用的数据库如 SQLite 不支持 RETURNING,这将非常有用。条款 INSERT陈述。

QSqlQuery::lastInsertId() documentation.

用法类似于以下内容:

QSqlQuery q;
q.prepare("INSERT INTO table_name VALUES(:some_column_name)");
q.bindValue(":some_column_name", "FooBar");
q.exec();

qDebug() << "Last ID was:" << q.lastInsertId();

关于qt - 如何使用 QSqlQuery 获取事务中先前插入的行的 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13802614/

相关文章:

database - 这个的可序列化图是什么?

c# - RepeatableRead 似乎没有锁定读取

transactions - 如何处理跨有界上下文的长时间运行的流程/传奇用例

android - 内部错误 : Could not find . pro 文件

c++ - QT4.8.5在QTextEdit上显示光标

qt - 如何翻译默认 qsTr 字段 - 例如MessageDialog 是/否按钮

c++ - 无法从QTreeView连接信号/插槽

c++ - Qt SQL 准备失败

linux - QIBASE 的问题(firebird + Ubuntu)

mysql - QMSQL : Cannot mix incompatible Qt library (version 0x50b03) with this library (version 0x50c05)