dbを論理的に一貫性のない状態のままにしたくないため、トランザクションスコープ内に挿入された行の主キーを取得しようとしています。
私の問題は、以前に実行されたクエリのID値を取得する方法が見つからないことです。これは、次の挿入クエリに使用します。トランザクションが有効なときにPostgreSQLデータベースをクエリすると、非外部キーテーブルに結果が表示されません(行はまだコミットされていませんか?)。これは、トランザクションの分離レベルによるものだと思います。
以下は、わかりやすくするために少し編集して1つの関数に絞り込んだものですが、本番コードで実行しようとしていることです。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();
}