Einzelnen Beitrag anzeigen

Ykcim

Registriert seit: 29. Dez 2006
Ort: NRW
824 Beiträge
 
Delphi 10.4 Sydney
 
#1

Exception mit DataSet ausschließlich im Release Build

  Alt 22. Jun 2021, 18:59
Datenbank: MySQL • Version: 8 • Zugriff über: FireDac
Hallo Zusammen,
ich habe ein seltsames Problem. Ich habe eine Client-Server Application, die im Debug-Build fehlerfrei läuft und im Release-Build mir den Fehler auswirft, "Operation bei geschlossener Datenmenge nicht möglich".

Mein Problem ist, dass ich es nicht debuggen kann, denn es tritt nur im Release-Build auf. Ich habe schon den Release-Ordner gelöscht und neu erstellen lassen und die zusätzlichen Dateien alle aus dem Debug-Ordner reinkopiert (Verbindungsdaten zum SQL-Server, Vorlagen etc.)

So sieht der Weg aus:

Bei Drücken des Buttons in der Client-App
Delphi-Quellcode:
procedure TFrm_BD_DHL.btn_PropertiesClick(Sender: TObject);
begin
   DB_Unit.Get_Propteries; //Es geht nur um diese Procedure
   PgCntrl_Frms.ActivePage := TbSht_Properties;
   Verlauf_Write;
end;
Delphi-Quellcode:
procedure TDB_Unit.Get_Propteries;
var LClient: TxDataClient;
      LService: IDBService;
      LStream: TMemoryStream;
begin
   LClient := TXDataClient.Create;
   LStream := TMemoryStream.Create;
   Try
      LClient.Uri:= xData_Connect.URL;
      LService:= LClient.Service<IDBService>;
      LStream:=LService.Properties_Select as TMemoryStream;
      LStream.Position:=0;
      MTable_Properties.LoadFromStream(LStream, sfJSON);
   Finally
      LClient.Free;
      LStream.Free;
   end;
end;
Auf dem Server werden folgende Proceduren ausgelöst:
In der Service-Unit:
Delphi-Quellcode:
function TDBService.Properties_Select: TStream;
var MxSQL: TDB_Modul;
      LStream: TMemoryStream;
begin
   LStream := TMemoryStream.Create;
   Try
      DB_Modul.Get_Properties(LStream); //Hier werden die Daten vom SQL-Server geholt
      Result:= LStream;
   Finally
      MxSQL.Free;
   End;
end;
Die Datenbank-Procedure
Delphi-Quellcode:
procedure TDB_Modul.Get_Properties (AStream: TStream);
begin
   Qry_Properties.SQL.Clear;
   Qry_Properties.SQL.Add('select * from hlp_properties');
   Qry_Properties.Open;
   if Assigned(AStream) then begin
      Qry_Properties.SaveToStream(AStream, sfJSON);
   end;
end;
Diese Procedure wird öfters ausgeführt und ich wollte, das diese Daten in der Query des Servers bleiben und ich immer darauf zugreifen kann. Wenn der Client Daten haben will, wird ein Object von TMxSQL erstellt, in dem die Datenbankabfragen stattfinden. Diese Object wird in der Unit TDB_Module definiert. Aber damit die Daten dieser Query immer zur Verfügung stehen, ist die Query ein Object von TDB_Module und hat auch dort seine Procedure:

Delphi-Quellcode:
unit TDatenbank;

interface

uses
  System.SysUtils, System.Classes, SQLServerUniProvider, UniProvider,
  MySQLUniProvider, Data.DB, DBAccess, Uni, vcl.Forms, vcl.Dialogs,
  FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
  FireDAC.Stan.Async, FireDAC.DApt, FireDAC.UI.Intf, FireDAC.Stan.Def,
  FireDAC.Stan.Pool, FireDAC.Phys, FireDAC.Phys.MySQL, FireDAC.Phys.MySQLDef,
  FireDAC.VCLUI.Wait, FireDAC.Comp.Client, FireDAC.Comp.DataSet, System.JSON,
  FireDAC.Comp.BatchMove, FireDAC.Comp.BatchMove.JSON, FireDAC.Stan.StorageJSON,
  FireDAC.Comp.BatchMove.DataSet, FireDAC.Phys.MSSQL, FireDAC.Phys.MSSQLDef,
  FireDAC.Phys.ODBCBase, TLogic_Unit, FireDAC.Stan.StorageXML,
  FireDAC.Stan.StorageBin, MemData;

type
  TDB_Modul = class(TDataModule)
      Qry_Properties: TFDQuery;//Das ist die angesprochene Query
      MyConnect: TFDConnection;
      MSConnect: TFDConnection;
      FDPhysMSSQLDriverLink1: TFDPhysMSSQLDriverLink;
      MySQLDriver: TFDPhysMySQLDriverLink;
      FDStanStorageXMLLink1: TFDStanStorageXMLLink;
      FDStanStorageBinLink1: TFDStanStorageBinLink;
      DS_Properties: TUniDataSource;
      procedure DataModuleCreate(Sender: TObject);
      procedure MyConnectLost(Sender: TObject);
      procedure MyConnectError(ASender, AInitiator: TObject;
         var AException: Exception);
      procedure MSConnectLost(Sender: TObject);
      procedure MSConnectError(ASender, AInitiator: TObject;
         var AException: Exception);
      procedure MyConnectAfterConnect(Sender: TObject);
  private
      FCountConnect: integer;
  public
      procedure Get_Properties( AStream: TStream);//Hier ist die Select-Anweisung
      procedure LostConnection(Sender: TObject; Component: TComponent; ConnLostCause: TConnLostCause; var RetryMode: TRetryMode);
      function Connect (Connection: TFDConnection; FileName: string): boolean;
      function DisConnect (Connection: TFDConnection): boolean;
      function Insert_Properties (Einstellung, Wert, Kommentar: string): integer;
      function Update_Properties (prop_id: integer; Einstellung, Wert, Kommentar: string): boolean;
      function Read_Einstellungswert(Einstellung: string): string;
end;

Type
   TMxSQL = class//Für alle anderen Abfragen des Clients wird jeweils ein Object von TMxSQL erzeugt
  private
    { Private-Deklarationen }
    function Get_BNumbers (BNumber, LNumber, TNumber, VDLeister, Kunde: string; VDate_von, VDate_bis: TDate): string;
  public
    { Public-Deklarationen }
    procedure ExecQuery (query: TFDQuery; var Cols: TCols; var Rows: TRows; AddRows: integer);
    procedure Get_Buyer(Lieferschein: string; AStream: TStream);
    procedure JSArray_TRows (JS_ArrayString: string; var Cols: TCols; var Rows: TRows);
    procedure Get_TNumber (var Cols: TCols; var Rows: TRows; BNumber: string);
    procedure Get_Order (var Cols: TCols; var Rows: TRows; BNumber: string);
    procedure Get_WeeklyStock (var AStream: TMemorySTream);
    procedure Get_SData(BNumber, TNumber, VDLeister, Kunde, BestellNr: string; VDate_von, VDate_bis: TDate; AStream: TStream);
    procedure Get_BData(BestellNr: string; LStream: TStream);
    procedure Get_VData(BNumber: string; LStream: TStream);
    function Write_TNum_MySQL (Cols: TCols; Rows: TRows): boolean;
    function Write_TNum_MsSQL (Cols: TCols; Rows: TRows): boolean;
    function Write_order (BestNr, LNumber, Empfaenger: string): boolean;
    function Exist_BNumber (BNumber: string): boolean;
    function QryToStream (Query: TFDQuery): TMemoryStream;
  end;

var
  DB_Modul: TDB_Modul;//Über dieses Object ist die Query immer zu erreichen

implementation
Wenn ich in der Server-App die Procedure aufrufe, dann bekomme ich auch die Daten, aber wenn ich das von der Client-App probiere, kommt der oben genannte Fehler.
Aber auch nur im Release-Build und nicht im Debug-Build.

Vielleicht hat das auch garnichts mit meinem Konstrukt zu tun, sondern ist ein ganz anderer Fehler. Ich habe nur versucht, Euch ein Gesamt-Bild zu vermitteln.

Kennt jemand das Problem, dass sich der Debug und Release unterschiedlich verhält?

Vielen Dank
Patrick
Patrick
  Mit Zitat antworten Zitat