AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials [Tutorial] Laden / Speichern von Objekten in einer normalisierten Datenbank

[Tutorial] Laden / Speichern von Objekten in einer normalisierten Datenbank

Ein Tutorial von haentschman · begonnen am 27. Jul 2017 · letzter Beitrag vom 24. Mai 2018
Antwort Antwort
Seite 3 von 4     123 4   
Benutzerbild von haentschman
haentschman
Registriert seit: 24. Okt 2006
Hallo...

Das ist mein erstes Tutorial. Bitte seid gnädig... Es soll als Anregung dienen wie man auch ohne datensensitive Controls auskommt.

Ich möchte Euch zeigen, wie man programmintern mit Objekten arbeitet und diese Objekte in einer normalisierten Datenbank speichert. Im Prinzip ist es
ein Mini-ORM ohne externes Framework. Der Kreativität sind keine Grenzen gesetzt.
Ich habe versucht das einfach zu halten. Mancher Code könnte mit unterschiedlichen Methoden realisiert werden. (JOIN statt separater procedure) Welche Variante
man nimmt, ist jedem selbst überlassen.

Hinweise:

* Weil die Units zu lang sind... siehe Projekt.
* Weil nicht alle das compilieren können ist die EXE zum Ausprobieren dabei... siehe Projekt
* Die Zwischenvariablen (wie var Customer: TCustomer; in Main) sind nicht immer notwendig aber es macht es für den Anfang imho übersichtlicher.

Anhänge:
* Projekt mit Datenbank ausführbar.
* kompletter Quelltext D10.1

Voraussetzungen:
Delphi XE und höher wegen Generics im Beispiel

Aufbau 3 Schicht Anwendung:
(Unit: FormMain) -> (Unit: Logic) -> (Unit: Database) -> (Database: z.B.Firebird)
<- (Event) <- (Event)

Database (beliebiebiges DBMS)
Code:
CREATE TABLE T_CUSTOMER (
    ID               INTEGER NOT NULL,
    F_NAME           VARCHAR(50),
    F_FIRST_NAME     VARCHAR(50),
    F_ADDRESS_ID     INTEGER
);


CREATE TABLE T_ADDRESS (
    ID                INTEGER NOT NULL,
    F_POSTCODE        VARCHAR(30),
    F_TOWN            VARCHAR(50),
    F_STREET          VARCHAR(50),
    F_HOUSE_NUMBER    VARCHAR(10)
);
Unit: Database
In dieser Unit ist die Schnittstelle zur Datenbank definiert. In diesem Falle als Interface. Die Logik kennt nur das Interface welches in der Logik instanziert wird. (siehe Unit: Logik)
Die Querys werden nicht mehr auf die Form "geklatscht" und dort die SQL eingetragen. Das Interface kennt alleinig die SQL Statements.
Das macht es einfacher mehrere Datenbanken anzubinden. Für jede Datenbank gibt es dann ein eigenes Interface wegen der Unterschiede der möglichen Datenbanken.
Als Datenbankkomponenten kommen hier die UniDAC mit der Schnittstelle zu Firebird zum Einsatz. Andere Komponenten sind natürlich auch möglich.
Diese eine Unit kennt allein die Datenbank. Die Kommunikation mit der Logik, welche die Unit nicht kennt, kann sowohl über Events oder als Rückgabe der Funktion
aus der Logik erfolgen.

Interface:
Delphi-Quellcode:
unit Database.Interfaces;

interface

uses
  Logic.DataClasses,
  Database.Events;

type
  IDatabaseCommon = interface(IInterface) // ggf. in seperate Unit bei mehreren DBMS
  ['{E41ADEE8-56F9-4223-8238-61B6C033DFF1}']
    function GetAfterConnect: TOnAfterConnectEvent;
    procedure SetAfterConnect(const Value: TOnAfterConnectEvent);
    function GetDatabaseError: TOnDatabaseErrorEvent;
    procedure SetDatabaseError(const Value: TOnDatabaseErrorEvent);
    function GetAfterDisconnect: TOnAfterDisconnectEvent;
    procedure SetAfterDisconnect(const Value: TOnAfterDisconnectEvent);

    property OnAfterConnect: TOnAfterConnectEvent read GetAfterConnect write SetAfterConnect;
    property OnAfterDisconnect: TOnAfterDisconnectEvent read GetAfterDisconnect write SetAfterDisconnect;
    property OnDatabaseError: TOnDatabaseErrorEvent read GetDatabaseError write SetDatabaseError;

    function Connect: Boolean;
    procedure Disconnect;
    procedure StartTransaction;
    procedure Commit;
    procedure Rollback;

    function GetSQLByName(SQLName: string): string; // ggf. bei Laden des SQL Statements aus Ressource
  end;

  IDatabase = interface(IDatabaseCommon)
    ['{C1BC6FE3-9586-4D92-8221-A3DD030E80B5}']
    // Entweder overload oder als einzelne Prozeduren, der Creativität sind keine Grenzen gesetzt.
    procedure FillList(List: TCustomerList); overload;

    function Save(Customer: TCustomer): Integer; overload;
    function Save(Address: TAddress): Integer; overload;

    procedure Get(Customer: TCustomer; ID: Integer); overload;
    procedure Get(Address: TAddress; ID: Integer); overload; // kann auch separat genutzt werden...oder auch nicht
  end;


implementation

end.
Database gekürzt:
Delphi-Quellcode:
unit Database.Firebird;

interface

uses
  System.Classes, System.SysUtils, System.Variants, System.Generics.Collections, System.Generics.Defaults, System.DateUtils,
  Uni, DBAccess, InterBaseUniProvider,
  Database.Interfaces, Database.Events,
  Logic.DataClasses;

type
  TDatabaseFirebird = class(TInterfacedObject, IDatabase)
  strict private
    // Properties Connection
    FConnection: TUniConnection;
    FOnAfterConnect: TOnAfterConnectEvent;
    FOnAfterDisconnect: TOnAfterDisconnectEvent;
    FOnDatabaseError: TOnDatabaseErrorEvent;
    // Getter / Setter
    function GetAfterConnect: TOnAfterConnectEvent;
    procedure SetAfterConnect(const Value: TOnAfterConnectEvent);
    function GetDatabaseError: TOnDatabaseErrorEvent;
    procedure SetDatabaseError(const Value: TOnDatabaseErrorEvent);
    function GetAfterDisconnect: TOnAfterDisconnectEvent;
    procedure SetAfterDisconnect(const Value: TOnAfterDisconnectEvent);
    // Eventhandler
    procedure DoAfterConnect(Sender: TObject);
    procedure DoAfterDisconnect(Sender: TObject);
    procedure DoError(Sender: TObject; E: EDAError; var Fail: Boolean);
    // Funktionen
    function CreateQuery: TUniQuery;
  public
    constructor Create;
    destructor Destroy; override;
    // Events
    property OnAfterConnect: TOnAfterConnectEvent read GetAfterConnect write SetAfterConnect;
    property OnAfterDisconnect: TOnAfterDisconnectEvent read GetAfterDisconnect write SetAfterDisconnect;
    property OnDatabaseError: TOnDatabaseErrorEvent read GetDatabaseError write SetDatabaseError;
    // Funktionen aus Interface
    function Connect: Boolean;
    procedure Disconnect;
    procedure StartTransaction;
    procedure Commit;
    procedure Rollback;

    function GetSQLByName(SQLName: string): string; // ggf. bei Laden des SQL Statements aus Ressource

    procedure FillList(List: TCustomerList); overload;

    function Save(Customer: TCustomer): Integer; overload;
    function Save(Address: TAddress): Integer; overload;

    procedure Get(Customer: TCustomer; ID: Integer); overload;
    procedure Get(Address: TAddress; ID: Integer); overload; // kann auch separat genutzt werden...oder auch nicht
  end;
  
...
Unit: Logic
In dieser Unit ist die Logik definiert. Die Logik nimmt die Befehle der Form entgegen und führt diese aus. Desweiteren hällt die Logik die Daten der Anwendung. In diesem
Falle die CustomerList. Die Kommunikation mit der Form, welche die Unit nicht kennt, kann sowohl über Events oder als Rückgabe der Function aus der Logik erfolgen.

Klassendefinition gekürzt:
Delphi-Quellcode:
unit Logic.DataClasses;

interface

uses
  System.Generics.Collections, System.Generics.Defaults;

type
  TDataState = (ddsNormal, ddsNew, ddsModified, ddsDeleted);

  TBaseClass = class
  strict protected
    FID: Integer;
    FState: TDataState; // jedes Objekt kennt seinen Status
  public
    property ID: Integer read FID write FID;
    property State: TDataState read FState write FState;
  end;

  TAddress = class(TBaseClass)
  strict private
    FTown: string;
    FStreet: string;
    FPostCode: string;
    FHouseNumber: string;
  public
    constructor Create;
    destructor Destroy; override;
    property PostCode: string read FPostCode write FPostCode;
    property Town: string read FTown write FTown;
    property Street: string read FStreet write FStreet;
    property HouseNumber: string read FHouseNumber write FHouseNumber;
  end;

  TCustomer = class(TBaseClass)
  strict private
    FName: string;
    FAddress: TAddress;
    FFirstName: string;
  public
    constructor Create;
    destructor Destroy; override;
    property Name: string read FName write FName;
    property FirstName: string read FFirstName write FFirstName;
    property Address: TAddress read FAddress write FAddress;
  end;

  TCustomerList = TObjectList<TCustomer>;
...
Logic gekürzt:
Delphi-Quellcode:
unit Logic.Base;

interface

uses
  Database.Interfaces, Database.Firebird, Database.Events,
  Logic.DataClasses;

type
  TOnFillCustomerListEvent = procedure(Sender: TObject; List: TCustomerList) of object;
  TOnGetCustomerEvent = procedure(Sender: TObject; Customer: TCustomer) of object;
  TOnDataChangedEvent = procedure(Sender: TObject; State: Boolean) of object;

  TLogic = class
  strict private
    FDatabase: IDatabase;
    FCustomerList: TCustomerList;

    FOnConnectDatabase: TOnAfterConnectEvent;
    FOnDisconnectDatabase: TOnAfterDisconnectEvent;
    FOnDatabaseError: TOnDatabaseErrorEvent;
    FOnFillCustomerList: TOnFillCustomerListEvent;
    FOnGetCustomer: TOnGetCustomerEvent;

    procedure DoOnDatabaseError(Sender: TObject; ErrorNumber: Integer; ErrorMessage: string);
    procedure DoOnAfterConnect(Sender: TObject);
    procedure DoOnAfterDisconnect(Sender: TObject);
  private
    FDataChanged: Boolean;
    FOnDataChanged: TOnDataChangedEvent;
    procedure SetDataChanged(const Value: Boolean);
  public
    constructor Create;
    destructor Destroy; override;

    property OnConnectDatabase: TOnAfterConnectEvent read FOnConnectDatabase write FOnConnectDatabase;
    property OnDisconnectDatabase: TOnAfterDisconnectEvent read FOnDisconnectDatabase write FOnDisconnectDatabase;
    property OnDatabaseError: TOnDatabaseErrorEvent read FOnDatabaseError write FOnDatabaseError;
    property OnFillCustomerList: TOnFillCustomerListEvent read FOnFillCustomerList write FOnFillCustomerList;
    property OnGetCustomer: TOnGetCustomerEvent read FOnGetCustomer write FOnGetCustomer;
    property OnDataChanged: TOnDataChangedEvent read FOnDataChanged write FOnDataChanged;

    property DataChanged: Boolean read FDataChanged write SetDataChanged;

    property CustomerList: TCustomerList read FCustomerList;

    procedure GetCustomerList;
    procedure GetCustomer(ID: Integer);
    procedure SaveCustomer(Customer: TCustomer);
    procedure RefreshCustomerList;
  end;
...
Unit: FormMain gekürzt
In dieser Unit ist die Form mit den Controls definiert. Die Form gibt der Logic Befehle was sie an Informationen haben möchte. Über Events werden die Information aus der Logik
zurückgeliefert und verarbeitet.
Delphi-Quellcode:
unit FormMain;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Actions, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.ActnList, Vcl.ComCtrls,
  ImageList.Small,
  Logic.Base, Logic.DataClasses;

const
  conTextGroupboxNormal = 'Details (Normal)';
  conTextGroupboxEdit = 'Details (Editmodus)';

type
  TfoMain = class(TForm)
    pnlTop: TPanel;
    pnlContent: TPanel;
    lvCustomers: TListView;
    btnNew: TButton;
    btnCopy: TButton;
    btnDelete: TButton;
    grpDetails: TGroupBox;
    btnSave: TButton;
    edtName: TEdit;
    lblName: TLabel;
    edtFirstName: TEdit;
    lblFirstName: TLabel;
    edtPostCode: TEdit;
    lblPostCode: TLabel;
    edtTown: TEdit;
    lblTown: TLabel;
    edtStreet: TEdit;
    lblStreet: TLabel;
    edtHouseNumber: TEdit;
    lblHouseNumber: TLabel;
    actlstMain: TActionList;
    actNew: TAction;
    btnInfo: TButton;
    actCopy: TAction;
    actDelete: TAction;
    actInfo: TAction;
    actSave: TAction;
    actCancel: TAction;
    btnCancel: TButton;
    btnMessage: TButton;
    actMessage: TAction;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure actNewExecute(Sender: TObject);
    procedure actCopyExecute(Sender: TObject);
    procedure actDeleteExecute(Sender: TObject);
    procedure actInfoExecute(Sender: TObject);
    procedure actSaveExecute(Sender: TObject);
    procedure actCancelExecute(Sender: TObject);
    procedure lvCustomersChange(Sender: TObject; Item: TListItem; Change: TItemChange);
    procedure actMessageExecute(Sender: TObject);
  private
    FLogic: TLogic;
    procedure DoFillCustomerList(Sender: TObject; List: TCustomerList);
    procedure DoGetCustomer(Sender: TObject; Customer: TCustomer);
    procedure DoDataChanged(Sender: TObject; State: Boolean);

    procedure ShowCustomerList(List: TCustomerList);
    procedure ShowCustomer(Customer: TCustomer);
    procedure SetCustomerToEdit(Active: Boolean);
    procedure SetButtons(Active: Boolean);
  public

  end;

var
  foMain: TfoMain;
...

Prinzip des Datenholens:

Delphi-Quellcode:
procedure TDatabaseFirebird.Get(Customer: TCustomer; ID: Integer); // nur einen Customer holen
var
  Qry: TUniQuery;
begin
  Qry := CreateQuery; // Query incl. der Connection erzeugen
  try
    // SQL wie gehabt
    Qry.SQL.Text := 'SELECT * FROM T_CUSTOMER WHERE ID = :ID';
// Alternativ über Ressource: Qry.SQL.Text := GetSQLByName('xxx'); // SQL Name ergänzen
    Qry.ParamByName('ID').AsInteger := ID;
    Qry.Open;
    
    // das Objekt füllen
    Customer.ID := Qry.FieldByName('ID').AsInteger;
    Customer.Name := Qry.FieldByName('F_NAME').AsString;
    Customer.FirstName := Qry.FieldByName('F_FIRST_NAME').AsString;
    // Alternative für GET wäre ein JOIN im Statement und die Adresse hier zusammenbauen.
    // Der Vorteil der Trennung: Man kann auch die Adresse seperat lesen. Wie man es braucht... :-)
    Get(Customer.Address, Qry.FieldByName('F_ADDRESS_ID').AsInteger);
    Customer.State := ddsNormal; // Wichtig: Status setzen
  finally
    Qry.Free;
  end;
end;

...

procedure TDatabaseFirebird.FillList(List: TCustomerList); // komplette Liste füllen
var
  Qry: TUniQuery;
  Customer: TCustomer;
begin
  List.Clear;
  Qry := CreateQuery; // Query incl. der Connection erzeugen
  try
    Qry.SQL.Text := 'SELECT * FROM T_CUSTOMER';
// Alternativ über Ressource: Qry.SQL.Text := GetSQLByName('xxx'); // SQL Name ergänzen
    Qry.Open;
    while not Qry.Eof do
    begin
      Customer := TCustomer.Create; // Objekt erzeuggen
      Get(Customer, Qry.FieldByName('ID').AsInteger); // Objekt füllen
      List.Add(Customer); // Objekt in Liste legen
      Qry.Next;
    end;
  finally
    Qry.Free;
  end;
end;
Prinzip der Speicherung
Delphi-Quellcode:
function TDatabaseFirebird.Save(Customer: TCustomer): Integer; // Speichern
var
  Qry: TUniQuery;
begin
  Result := -1;
  Qry := CreateQuery;
  try
    StartTransaction;
    try
      case Customer.State of // entsprechend dem Status des Objektes
        ddsNew: // insert
          begin
            Customer.Address.ID := Save(Customer.Address); // Rückgabe der ID als Erstes wegen ID
            Qry.SQL.Text := 'INSERT INTO T_CUSTOMER (F_NAME, F_FIRST_NAME, F_ADDRESS_ID) VALUES (:NAM, :FIN, :ADD) returning ID';
            // Alternativ über Ressource: Qry.SQL.Text := GetSQLByName('xxx'); // SQL Name ergänzen
            // das Objekt dem SQL übergeben
            Qry.ParamByName('NAM').AsString := Customer.Name;
            Qry.ParamByName('FIN').AsString := Customer.FirstName;
            Qry.ParamByName('ADD').AsInteger := Customer.Address.ID;
            Qry.ExecSQL;
            Customer.ID := Qry.ParamByName('RET_ID').AsInteger;

            Customer.State := ddsNormal;
            Result := Customer.ID;
          end;
        ddsModified: // update
          begin
            Qry.SQL.Text := 'UPDATE T_CUSTOMER SET F_NAME = :NAM, F_FIRST_NAME = :FIN, F_ADDRESS_ID = :ADD WHERE ID = :ID';
            // Alternativ über Ressource: Qry.SQL.Text := GetSQLByName('xxx'); // SQL Name ergänzen
            // das Objekt dem SQL übergeben
            Qry.ParamByName('ID').AsInteger := Customer.ID;
            Qry.ParamByName('NAM').AsString := Customer.Name;
            Qry.ParamByName('FIN').AsString := Customer.FirstName;
            Qry.ParamByName('ADD').AsInteger := Customer.Address.ID;
            Qry.ExecSQL;

            Save(Customer.Address);

            Customer.State := ddsNormal;
            Customer.Address.State := ddsNormal;
            Result := Customer.ID;
          end;
        ddsDeleted: // deleted
          begin
            Qry.SQL.Text := 'DELETE FROM T_CUSTOMER WHERE ID = :ID';
            // Alternativ über Ressource: Qry.SQL.Text := GetSQLByName('xxx'); // SQL Name ergänzen
            Qry.ParamByName('ID').AsInteger := Customer.ID;
            Qry.ExecSQL;

            Customer.Address.State := ddsDeleted;
            Save(Customer.Address);

            Result := Customer.ID;
          end;
      end;

      Commit;
    except
      Rollback;
    end;
  finally
    Qry.Free;
  end;
end;
Prinzip der Datenanzeige
Delphi-Quellcode:
procedure TfoMain.DoFillCustomerList(Sender: TObject; List: TCustomerList); // Event nach dem Datenholen
begin
  ShowCustomerList(List);
  SetCustomerToEdit(False);
end;

...

procedure TfoMain.ShowCustomerList(List: TCustomerList);
var
  Item: TListItem;
  Customer: TCustomer;
begin
  lvCustomers.Items.Clear;
  for Customer in List do
  begin
    Item:= lvCustomers.Items.Add;
    Item.Data:= Customer; // Das Objekt (Pointer) hängt an dem Eintrag
    Item.SubItems.Add(Customer.Name);
    Item.SubItems.Add(Customer.FirstName);
    Item.SubItems.Add(Customer.Address.Town);
    Item.ImageIndex:= dmSmall.GetIconIndexDataState(Customer.State);
  end;
  lvCustomers.Items.Item[0].Selected := True; // ersten Eintrag markieren...oder so
end;
Erweiterungen:
Nach Bedarf können u.a. Funktionen hinzugefügt oder mit einander kombiniert werden. (DRY)

Vorteile:
* Keine datensensitiven Controls. Das bedeutet Unabhängigkeit von der Optik der DB sensitiven Controls.
* Eine Property des Objektes kann z.B. in einem TEdit einem TMemo oder mit einem TRotMitGelbenPunktenControl dargestellt werden.
* Alle SQL Statements auf einem Fleck. Das erleichtert das Suchen nach einem Statement. Die SQL sind nicht mehr auf den gesamten QT verteilt.
* Die Umbauten bei Datenbankwechsel beziehen sich nur auf das Interface.
* Durch die Objekte kann man sich die Informationen beliebig zustammenstellen. Auch wenn sie auch verschieden Tabelle stammen.
* Speichern mit einem Einzeiler
Delphi-Quellcode:
FDatabase.Save(Customer);
...
* Objekte sind besser debugbar.
* Objekte können wiederum Listen mit Objekten enthalten.
* Objekte sind mit einem Rutsch, über das Database Interface, speicherbar.

Bei diesem Tutorial geht es ums Prinzip bei der Arbeit mit Objekten ohne die üblichen Verdächtigen der großen Frameworks für Datenbanken. Meistens lohnt der Aufwand nicht
ein großes Framework zu installieren. Auch der Einarbeitungsaufwand bei diesen ist nicht ohne... Manchmal ist weniger mehr.


Diskussion eröffnet.

PS: Alle Fehler sind urheberrechtlich geschützt weil Unikate.
Miniaturansicht angehängter Grafiken
tutorial.png  
Angehängte Dateien
Dateityp: zip Tutorial_Projekt.zip (4,82 MB, 88x aufgerufen)

Geändert von haentschman (27. Jul 2017 um 15:01 Uhr)
 
mkinzler

 
Delphi 11 Alexandria
 
#21
  Alt 24. Mai 2018, 09:24
Nein. in der express fehlt der Treiber für Interbase/FireBird.
Man könnte aber auf Zeos, UIB o.ä umstellen.
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

 
Delphi 12 Athens
 
#22
  Alt 24. Mai 2018, 09:28
Zitat:
Das MadExcept aus der .dpr habe ich auskommentiert, reicht das aus oder muss ich MadExcept dafür auch laden und installieren?
...schlecht. Aber auch ohne den MadExcept geht das.
Zitat:
Reicht da die Express oder muss ich die Pro Version nehmen
Ich habe das Beispiel mit UniDAC entwickelt...Aber es geht auch jede andere Datenbankkomponente! Für den Anfang reichten die ZEOS. Einfach die UniQuery gegen die ZeosQuery tauschen ... fertsch.

so ungefähr:
Delphi-Quellcode:
function TDatabaseFirebird.CreateQuery: TZQuery;
begin
  Result := TZQuery.Create(nil);
  Result.Connection := FConnection;
end;
...logischerweise auch die Parameter der Connection anpassen.

Geändert von haentschman (24. Mai 2018 um 09:35 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

 
Delphi 11 Alexandria
 
#23
  Alt 24. Mai 2018, 10:14
Ich glaube das übersteigt gerade meine Grenzen, wenn ich "Uni, DBAccess, InterBaseUniProvider" weglasse ploppen da an sehr vielen Stellen fehlende Bezeichner auf wo ich bei meinem momentanen Wissensstand nicht wüßte wie ichs machen müßte.
Das sind nur die fehlenden Unit-Namen in der Database.Firebird.pas Datei, wer weiß wo mir da noch so alles was fehlt.
Meine Tokyo Version besitzt noch keine Extras, nur so wie es als Professional erhältlich ist bis auf PngComponents und Daniels Startpage.
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

 
Delphi 12 Athens
 
#24
  Alt 24. Mai 2018, 11:45
Ok...
1. Installiere dir die ZEOS Datenbank Komponenten. https://sourceforge.net/projects/zeoslib/

...dann melde dich wieder.
  Mit Zitat antworten Zitat
mkinzler

 
Delphi 11 Alexandria
 
#25
  Alt 24. Mai 2018, 11:51
QuickAndDirty Umbau nach FireDAC
Angehängte Dateien
Dateityp: pas Database.Firebird.pas (12,5 KB, 12x aufgerufen)
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

 
Delphi 11 Alexandria
 
#26
  Alt 24. Mai 2018, 12:28
QuickAndDirty Umbau nach FireDAC
Vielen Dank, das isses! Die Qualität kann ich nicht beurteilen aber kompilieren und Zugriff auf Test DB klappt!!
Also mein Problem ist hiermit gelöst, Danke!!!
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

 
Delphi 12 Athens
 
#27
  Alt 24. Mai 2018, 12:38

Damit ist auch geklärt, daß man mit relativ wenigen Handgriffen eben mal den Datenbankzugriff tauscht.

@KodeZwerg
Zitat:
Also mein Problem ist hiermit gelöst, Danke!!!
...es wäre vieleicht besser gewesen, daß du dir die Zeos selbst installiert hast, um besser zu verstehen was alles zu einer Datenbank dazugehört.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

 
Delphi 11 Alexandria
 
#28
  Alt 24. Mai 2018, 13:06
@haentschman: Da fehlt ein Tutorial was mal beschreibt was was ist. Ich höre hier mal AnyDAC dann UniDAC dort, FireDAC hab ich mal bei Emba was drüber gelesen, Maria Mongo Firebird DB, (non-)Sql nun Zeos, ich blicke da null durch was was macht und wofür man es braucht weswegen ich Deinem Rat nachkomme und mich mit Zeos beschäftigen werde. Auch durch andere Tutorials in Richtung DB verliere ich schnell den Überblick weil da teilweise nurnoch fachchinesisch gesprochen wird ohne chinesisch vorher zu entziffern. Hier bei Dir mit Aussage welche Unit was für Aufgaben hat, wie im groben die geforderten Tasks durchzuführen sind plus die Alternative Kommentare im Source, das ist für mich Nachvollziehbarer als woanders.
  Mit Zitat antworten Zitat
mkinzler

 
Delphi 11 Alexandria
 
#29
  Alt 24. Mai 2018, 13:29
Es gibt verschiedene Zugriffsbibliotheken

MultiDB: UniDAC, FireDAC (ehemals AnyDAC), Zeos, ...
Datenbankspezifisch: IBDAC, UIB, ...

FireBird, Interbase, MySQL/MariaDB, Mongo, SQLite, MSSQL, Oracle, PosGres, ... sind verschiedene Datenbanksysteme

Auf die Datenbank-Tutorials des Delphi-Treffs wurdest Du ja schon mehrfach hingewiesen.

Vergelieche mal die Originalversion der Datei mit meinen Änderungen, dann sollte klar sein, was geändert wurde.
Markus Kinzler
  Mit Zitat antworten Zitat
mkinzler

 
Delphi 11 Alexandria
 
#30
  Alt 24. Mai 2018, 13:30
Zitat:
Damit ist auch geklärt, daß man mit relativ wenigen Handgriffen eben mal den Datenbankzugriff tauscht.
Wäre einfacher, wenn Klassen auf abreakterer Ebene Verwendung finden würden.
Markus Kinzler
  Mit Zitat antworten Zitat
Themen-Optionen Tutorial durchsuchen
Tutorial durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:55 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