我一直在使用 Firebird 3 中包含的新 Firebird.pas 界面。当我尝试使用自定义事务参数块时遇到问题。如果我向块中添加任何标签,我似乎总是收到错误“事务参数块的格式无效”。我见过的唯一一个关于如何做到这一点的例子是 Firebird 3 中包含的“Using_OO_API.html”文档。这里是重现错误的代码。任何建议表示赞赏!
procedure TForm1.Connect2ButtonClick(Sender: TObject);
var
Master: IMaster;
Status: IStatus;
Dispatcher: IProvider;
Util: IUtil;
dpb: IXpbBuilder;
tpb: IXpbBuilder;
Attachment: IAttachment;
Transaction: ITransaction;
Statement: IStatement;
ErrorString: AnsiString;
StatusVector: NativeIntPtr;
UseCustomTransaction: Boolean;
begin
// Connect to Firebird 3 and use a custom transaction object.
try
Master := fb_get_master_interface();
Status := Master.getStatus();
Dispatcher := master.getDispatcher();
Util := Master.getUtilInterface();
dpb := Util.getXpbBuilder(status, IXpbBuilder.DPB, nil, 0);
dpb.insertString(status, isc_dpb_user_name, 'SYSDBA');
dpb.insertString(status, isc_dpb_password, 'sillypw');
Attachment := Dispatcher.attachDatabase(status, PAnsiChar('myserver:testdb'), dpb.getBufferLength(status), dpb.getBuffer(status));
UseCustomTransaction := True;
if UseCustomTransaction then
begin
// Transaction := attachment.startTransaction(status, 0, nil);
tpb := Util.getXpbBuilder(status, IXpbBuilder.TPB, nil, 0);
tpb.insertTag(status, isc_tpb_version3);
tpb.insertTag(status, isc_tpb_write);
tpb.insertTag(status, isc_tpb_read_committed);
tpb.insertTag(status, isc_tpb_nowait);
tpb.insertTag(status, isc_tpb_rec_version);
// This always seems to error with "invalid format for transaction parameter block"
Transaction := attachment.startTransaction(status, tpb.getBufferLength(status), tpb.getBuffer(status));
end
else
begin
// Creating default transaction works fine. As an aside, what are the default transaction properties?
Transaction := attachment.startTransaction(status, 0, nil);
end;
Statement := attachment.prepare(status, transaction, 0,
'select rdb$relation_id relid, rdb$relation_name csname ' +
' from rdb$relations ' +
' where rdb$relation_id < ?',
3, 0);
Memo1.Lines.Add('Simple Plan: ' + Statement.getPlan(status, false));
Memo1.Lines.Add('Detailed Plan: ' + Statement.getPlan(status, true));
Memo1.Lines.Add('');
transaction.rollback(status);
Statement.free(status);
attachment.detach(status);
dpb.dispose;
if UseCustomTransaction then
tpb.dispose;
except
on E: FbException do
begin
SetLength(ErrorString, 2000);
StatusVector := E.getStatus().getErrors();
// Note that fb_interpret does not seem to appear in firebird.pas so we added it by hand.
// function fb_interpret(s: PAnsiChar; n: Cardinal; var statusVector: NativeIntPtr): Integer; cdecl; external 'fbclient';
SetLength(ErrorString, fb_interpret(PAnsiChar(ErrorString), 2000, StatusVector));
ShowMessage(String(ErrorString));
end
end;
end;