Мне нужна помощь в разрешении этого сообщения об ошибке.
Я использую Code Typhon32 V4.9 в Windows 7 Pro.
У меня был проект, подключающийся к базе данных firebird, единая форма, которая отлично работает - никаких проблем.
Я добавил вторую форму, которая будет моей формой ввода данных, связанной с другой базой данных в Firebird - мне нужны обе базы данных в одном проекте.
После добавления второй формы я получаю следующую ошибку, когда закрываю тифон кода и когда закрываю форму Form1 при использовании отладчика: «SQLTransaction2: операция не может быть выполнена для активной транзакции»
Я пробовал множество решений, найденных в Интернете, но не могу их решить.
У меня есть кнопка, открывающая второй из следующих:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
frmContributions := TfrmContributions.Create(nil);
try
frmContributions.ShowModal;
finally
frmContributions.Free;
end;
end;
Вот мой код второй формы:
unit uFirebirdDemo1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, sqldb, IBConnection, pqconnection, db, FileUtil, Forms,
Controls, Graphics, Dialogs, StdCtrls, DBGrids, DbCtrls;
type
TfrmContributions = class(TForm)
btnUpdate: TButton;
btnDeleteProgrammer: TButton;
dsProgrammer: TDatasource;
dbgrdProgrammer: TDBGrid;
dbnavProgrammer: TDBNavigator;
IBConnection2: TIBConnection;
sqlqProgrammer: TSQLQuery;
SQLScript1: TSQLScript;
SQLTransaction2: TSQLTransaction;
procedure btnDeleteProgramClick(Sender: TObject);
procedure btnUpdateClick(Sender: TObject);
procedure btnUpdateProgramsClick(Sender: TObject);
procedure btnDeleteProgrammerClick(Sender: TObject);
procedure dbgrdCombinedTitleClick(Column: TColumn);
procedure dbgrdProgrammerTitleClick(Column: TColumn);
procedure dbgrdProgramsTitleClick(Column: TColumn);
procedure edtSearchChange(Sender: TObject);
procedure Savechanges;
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
end;
var
frmContributions: TfrmContributions;
implementation
{$R *.lfm}
procedure TfrmContributions.btnUpdateClick(Sender: TObject);
begin
sqlqProgrammer.Edit;
sqlqProgrammer.Post;
sqlqProgrammer.ApplyUpdates(1);
SQLTransaction2.CommitRetaining;
end;
procedure TfrmContributions.btnDeleteProgrammerClick(Sender: TObject);
begin
SQLScript1.Script.Text:= 'Delete from Programmer WHERE ID = ' + dbgrdProgrammer.Columns[0].Field.AsString + ';';
SQLScript1.Execute;
SQLTransaction2.CommitRetaining;
sqlqProgrammer.Refresh;
end;
procedure TfrmContributions.dbgrdProgrammerTitleClick(Column: TColumn);
begin
sqlqProgrammer.Close;
SQLTransaction2.Active := TRUE;
sqlqProgrammer.SQL.Text := 'Select * from Programmer ORDER BY ID DESC';
sqlqProgrammer.Open;
end;
procedure TfrmContributions.Savechanges;
// Saves edits done by user, if any.
begin
try
if SQLTransaction2.Active then
// Only if we are within a started transaction
// otherwise you get "Operation cannot be performed on an inactive dataset"
begin
sqlqProgrammer.ApplyUpdates; //Pass user-generated changes back to database...
SQLTransaction2.Commit; //... and commit them using the transaction.
//SQLTransaction2.Active now is false
end;
except
on E: EDatabaseError do
begin
MessageDlg('Error', 'A database error has occurred. Technical error message: ' +
E.Message, mtError, [mbOK], 0);
end;
end;
end;
procedure TfrmContributions.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
SaveChanges;
sqlqProgrammer.Close;
SQLTransaction2.Commit;
SQLTransaction2.RollBack;
SQLTransaction2.Active := False;
IBConnection2.Connected := False;
end;
end.
Я попытался добавить форму, близкую к моей первой форме, следующим образом, чтобы решить проблему, но, похоже, она ничего не делает:
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
frmContributions.SaveChanges;
frmContributions.SQLTransaction2.RollBack;
frmContributions.SQLTransaction2.Active := False;
frmContributions.IBConnection2.Connected := False;
end;
Я пробовал разные решения, найденные в Интернете, но все еще получаю:
«SQLTransaction2: операция не может быть выполнена для активной транзакции», когда я закрываю свой проект с помощью отладчика, а также получаю ту же ошибку при закрытии тифона кода.
Вот файл lfm:
object frmContributions: TfrmContributions
Left = 816
Height = 415
Top = 172
Width = 774
Caption = 'Data Entry for Promo'
ClientHeight = 415
ClientWidth = 774
Color = clHighlight
OnClose = FormClose
LCLVersion = '1.3'
object btnUpdate: TButton
Left = 536
Height = 25
Top = 376
Width = 168
Caption = 'Update programmers'
OnClick = btnUpdateClick
TabOrder = 0
end
object dbgrdProgrammer: TDBGrid
Left = 16
Height = 360
Top = 0
Width = 744
Color = clWindow
Columns = <
item
Title.Caption = 'ID'
Width = 60
FieldName = 'ID'
end
item
Title.Caption = 'DATESENT'
FieldName = 'DATESENT'
end
item
Title.Caption = 'COURSE'
Width = 140
FieldName = 'COURSE'
end
item
Title.Caption = 'PROMOTYPE'
Width = 140
FieldName = 'PROMOTYPE'
end
item
Title.Caption = 'LINK'
Width = 100
FieldName = 'LINK'
end
item
Title.Caption = 'VALUE'
Width = 50
FieldName = 'VALUECHART'
end
item
Title.Caption = 'TOTALSENT'
FieldName = 'TOTALSENT'
end
item
Title.Caption = 'NOTES'
FieldName = 'NOTES'
end>
DataSource = dsProgrammer
TabOrder = 1
OnTitleClick = dbgrdProgrammerTitleClick
end
object dbnavProgrammer: TDBNavigator
Left = 280
Height = 25
Top = 376
Width = 241
BevelOuter = bvNone
ChildSizing.EnlargeHorizontal = crsScaleChilds
ChildSizing.EnlargeVertical = crsScaleChilds
ChildSizing.ShrinkHorizontal = crsScaleChilds
ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 100
ClientHeight = 25
ClientWidth = 241
DataSource = dsProgrammer
Options = []
TabOrder = 2
VisibleButtons = [nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbRefresh]
end
object btnDeleteProgrammer: TButton
Left = 64
Height = 25
Top = 376
Width = 201
Caption = 'Delete Selected Programmer'
OnClick = btnDeleteProgrammerClick
TabOrder = 3
end
object dsProgrammer: TDataSource
DataSet = sqlqProgrammer
left = 696
top = 168
end
object IBConnection2: TIBConnection
Connected = True
LoginPrompt = False
DatabaseName = '.......CONTRIBUTIONS.FDB'
KeepConnection = False
Password = 'password'
Transaction = SQLTransaction2
UserName = 'username'
HostName = 'hostname'
left = 696
top = 8
end
object SQLTransaction2: TSQLTransaction
Active = True
Action = caCommitRetaining
Database = IBConnection2
left = 696
top = 56
end
object sqlqProgrammer: TSQLQuery
IndexName = 'DEFAULT_ORDER'
FieldDefs = <
item
Name = 'ID'
DataType = ftInteger
Precision = -1
Size = 0
end
item
Name = 'DATESENT'
DataType = ftDate
Precision = -1
Size = 0
end
item
Name = 'PROMOTYPE'
DataType = ftString
Precision = -1
Size = 25
end
item
Name = 'COURSE'
DataType = ftString
Precision = -1
Size = 25
end
item
Name = 'LINK'
DataType = ftString
Precision = -1
Size = 450
end
item
Name = 'VALUECHART'
DataType = ftInteger
Precision = -1
Size = 0
end>
Active = True
Database = IBConnection2
Transaction = SQLTransaction2
SQL.Strings = (
'select * from Programmer order by ID DESC'
)
UpdateSQL.Strings = (
''
)
InsertSQL.Strings = (
''
)
DeleteSQL.Strings = (
''
)
Params = <>
UpdateMode = upWhereChanged
UsePrimaryKeyAsKey = False
left = 696
top = 224
end
object SQLScript1: TSQLScript
DataBase = IBConnection2
Transaction = SQLTransaction2
Directives.Strings = (
'SET TERM'
'COMMIT'
'#IFDEF'
'#IFNDEF'
'#ELSE'
'#ENDIF'
'#DEFINE'
'#UNDEF'
'#UNDEFINE'
)
Script.Strings = (
''
)
Terminator = ';'
CommentsinSQL = True
UseSetTerm = True
UseCommit = True
UseDefines = True
left = 696
top = 112
end
end
Спасибо.
1 ответ
На самом деле я точно не знаю, что должно быть дальше, но
(0) Я бы переместил код базы данных в автономный TDataModule (вне кода пользовательского интерфейса), чтобы упростить чтение и обслуживание кода. Во время этого рефакторинга вы можете обнаружить скрытую проблему.
(1) этот http: //forum.lazarus. freepascal.org/index.php?topic=14301.0, похоже, решает аналогичную проблему
(2) книга Lazarus, полное руководство < / a> кажется, есть глава о TDataModule
(3) Мартин Фаулер написал книгу о рефакторинге и запустил сайт о том же по адресу http: // refactoring .com /
(4) некоторые компоненты работают некорректно, если они активны в режиме разработки. Поскольку на самом деле это другой и более сложный сценарий (много if
с csDesigning in ComponentState
, диаграмма последовательности событий другая, почти случайная, и все должно быть надежным и повторяющимся ..). Таким образом, безопасная сторона для производства - отключить активное состояние компонента в режиме разработки и активировать их в коде в четко определенном порядке, ожидаемом авторами компонента.
(5) Если ошибка возникает только в отладчике, и она не отображается в производственном коде, я думаю, что вы можете игнорировать проблему, поскольку среда отладки
Похожие вопросы
Новые вопросы
freepascal
Free Pascal - это мультидиалектный мультиплатформенный компилятор Object Pascal. Первоначально он начал заменять устаревший компилятор Turbo Pascal, теперь он пытается следовать диалекту Delphi, который все еще разрабатывается Embarcadero Technologies. Он имеет режимы компилятора для Delphi, Turbo Pascal и Mac Pascal. Он также имеет два режима для своего собственного диалекта надмножества: один режим с исключениями, классами и интерфейсами и режим без.