TUIBStatementAdapter.Execute
If the Firebird database is complete empty then there is a problem with TDatabaseManager.BuildDatabase. In this method there are 3 calls to update the database: BuildTables(fEntities); BuildForeignKeys(fEntities); BuildSequences(fEntities);
The second call to BuildForeignKeys fails because the table created in BuildTables is not commited.
I changed TUIBStatementAdapter.Execute like this and it worked.
function TUIBStatementAdapter.Execute: NativeUInt;
begin
inherited;
try
Statement.Prepare;
Statement.ExecSQL;
Result := Statement.RowsAffected;
{
if Statement.Transaction = Statement.DataBase.Transactions[0] then
Statement.Close(etmCommit)
else
Statement.Close(etmStayIn);
}
Statement.Close(etmCommit); // always commit the statement!
except
raise HandleException;
end;
end;
Comments (5)
-
repo owner -
repo owner Please attach a complete sample project that reproduces the issue
-
reporter Hi Stefan,
I've set up a GitHub repo. The first Button opens the database which calls TDatabaseManager.BuildDatabase (in unit Hub.Database).
I don't think either that the changes I've suggested might work properly. It's just to illustrate the issue.
-
repo owner Not quite related to the reported issue but your code in THubDatabase.Load is not quite correct as it calls BuildDatabase in all cases even if the file existed. This will cause a complete recreation and due to lacking support for create table as select in firebird it does not preserve any data.
Also the code will not work properly when calling this method more than once (Close is missing FConnection := nil right between the other two statements).
-
repo owner - changed status to resolved
fixed issue
#280→ <<cset ed4626840627>>
- Log in to comment
I don't know how exactly the UIB components internally work but I suspect this change might not work properly (I even doubt the original code was correct though) when using the statement in other contexts. When Explicitly opening a transaction and then doing a statement this will always commit.