2016-05-12 20 views
3

我一直在玩Firebird 3中包含的新Firebird.pas接口。我嘗試使用自定義事務參數塊時遇到問題。我似乎總是得到錯誤「交易參數塊無效格式」,如果我添加任何標籤的塊。我見過的唯一例子是Firebird 3中包含的「Using_OO_API.html」文檔。下面是重現錯誤的代碼。任何建議感激!如何在Firebird 3中使用事務參數塊OO Api

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; 
+4

我建議你問的火鳥-devel郵件列表,如我懷疑的火鳥核心開發者之外,這個API所沒有的:這可以通過周圍創建用手緩衝如下面的代碼工作還有很多用處;我懷疑這個答案的機會不是很高。 –

+0

謝謝馬克。我也會給你一個機會。 – MarkF

回答

3

似乎存在與IXpbBuilder一個問題(或許特定於TPB或InsertTag),使得它創建了一個無效的事務參數緩衝器。

// var TransParamBuffer: TBytes 
SetLength(TransParamBuffer, 5); 
TransParamBuffer[0] := isc_tpb_version3; 
TransParamBuffer[1] := isc_tpb_write; 
TransParamBuffer[2] := isc_tpb_read_committed; 
TransParamBuffer[3] := isc_tpb_nowait; 
TransParamBuffer[4] := isc_tpb_rec_version; 
Transaction := attachment.startTransaction(status, Length(TransParamBuffer), @TransParamBuffer[0]); 
+4

發佈自己的解決方案做得很好,+1。我希望更多的人會這樣做,而不是放棄他們的q。 – MartynA

相關問題