Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Exception mit DataSet ausschließlich im Release Build (https://www.delphipraxis.net/208187-exception-mit-dataset-ausschliesslich-im-release-build.html)

Ykcim 22. Jun 2021 18:59

Datenbank: MySQL • Version: 8 • Zugriff über: FireDac

Exception mit DataSet ausschließlich im Release Build
 
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

hoika 22. Jun 2021 22:32

AW: Exception mit DataSet ausschließlich im Release Build
 
Hallo,
Dann must du sich mit MessageBoxen durchhangeln.

Fang mal,bei den Verbindungsdaten an.

jaenicke 23. Jun 2021 06:56

AW: Exception mit DataSet ausschließlich im Release Build
 
Du könntest einfach mal versuchen die Debuginformationen in der Release-Konfiguration zu aktivieren um dort debuggen zu können. Vielleicht liegt das Problem ja eher an einer anderen Stelle der Buildkonfiguration, dann würde der Fehler ja weiter auftreten und debugbar sein.

Hast du einmal versucht die .dproj Datei umzubenennen und durch Öffnen der .dpr neu erzeugen zu lassen? Vielleicht klappt es dann ja in der Standardkonfiguration, dann könntest du die Einstellungen vergleichen um die Ursache zu finden.

Ykcim 23. Jun 2021 13:33

AW: Exception mit DataSet ausschließlich im Release Build
 
Hallo Zusammen,

ich habe ein paar ShowMessages eingebaut, mit dem Ergebnis, dass es dann ohne Fehler funktioniert...

Delphi-Quellcode:
function TDBService.Properties_Select: TStream;
var  MxSQL: TDB_Modul;
      LStream: TMemoryStream;
begin
   LStream := TMemoryStream.Create;
   Try
      DB_Modul.Get_Properties(LStream);
      ShowMessage('LStream.Size: '+IntToStr(LStream.Size));//Ich brauche diese Showmessage
      Result:= LStream;
      ShowMessage('Result.Size: '+IntToStr(Result.Size));//und dieses, sonst kommt der Fehler
   Finally
      MxSQL.Free;
   End;
end;
Wenn ich ein Sleep einbaue, kommt der Fehler trotzdem.
Mit diesen ShowMessages funktioniert es auch, wenn ich diese blitzschnell wieder schließe, aber ich habe es noch nicht geschafft, dass es ohne funktioniert.
Das ist natürlich keine Lösung. Hat jemand einen Tip, wie ich das sauber prüfen kann.
Die Stream-Größe wird immer mit ca. 9000 angegeben...

Vielen Dank
Patrick

hoika 23. Jun 2021 13:42

AW: Exception mit DataSet ausschließlich im Release Build
 
Hallo,
dein MxSQL.Free; muss weg. Du hast die Variable ja gar nicht initialisiert.

Ich denke, dass beim Debugmode das irgendwie nicht zum Absturz führt, beim Release (Optimierung) dann aber schon.


Da muss doch eine Compilerwarnung gekommen sein...

Ykcim 23. Jun 2021 14:42

AW: Exception mit DataSet ausschließlich im Release Build
 
Ich könnte mich ohrfeigen!!! :oops:
Das war der Fehler - habe ich voll übersehen!

Vielen Dank!

hoika 23. Jun 2021 18:43

AW: Exception mit DataSet ausschließlich im Release Build
 
Hallo,

ein weiser Mann sagte mal:
"Alle Compilerwarnungen du beheben musst."

Ykcim 24. Jun 2021 12:55

AW: Exception mit DataSet ausschließlich im Release Build
 
:-D :thumb:

Ich muss gestehen, die Warnungen beachte ich nicht besonders. Fehler zwingen mich zum Handeln. Aber ich werden zukünftig ein Auge drauf haben.
Vielen Dank!

haentschman 24. Jun 2021 13:00

AW: Exception mit DataSet ausschließlich im Release Build
 
Zitat:

Ich muss gestehen, die Warnungen beachte ich nicht besonders
...schlecht. :zwinker: Ich hatte mal ein Projekt in den Fingern mit über 600 Warnungen und Hinweisen. Da findet man die wichtigen Sachen nicht! :warn:

Uwe Raabe 24. Jun 2021 13:39

AW: Exception mit DataSet ausschließlich im Release Build
 
Zitat:

Zitat von Ykcim (Beitrag 1491468)
Warnungen beachte ich nicht besonders. Fehler zwingen mich zum Handeln.

In den Projektoptionen kann man für einzelne Warnungen auch einstellen, ob man die gar nicht, nur als Warnung oder lieber als Fehler gemeldet bekommen möchte.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz