Datenbankanwendung mit MySQL

 

Hier eine kleine DB -  Anwendung.

Ich arbeite mit MySql (http://www.mysql.de)  und den DB-Komponenten von ZEOS welche es unter http://www.zeoslib.net (benötigt werden Zeos Database Objects – Ich verwende die Vers. 6.5.0 Alpha) gibt. Das ganze gibts auch im Downloadbereich als Projekt zum Downloaden!

 

Nach der Installation der Komponenten und dem SQL-Server möchte ich nun ein Tool erstellen, indem man Nachrichten an bestimmte User im Netzwerk schicken kann auch wenn diese nicht online sind.

 

Das hab ich mir so überlegt, das div. Nachrichten an die DB geschickt wird und für die div. User gespeichert wird. Und diese dann beim Online gehen bzw. durch einen Timer abgerufen werden.

 

Vorerst mal die Oberfläche:

 

 

Verwendet wird ein DB-Grid eine Combobox (für die Usernamen an die eine Nachricht geschickt werden soll), 2x Textfeld (Edt_User und Edt_Passwort), 3x Button (Btn_Senden und Btn_Verbinden, Btn_Loeschen), 1xMemofeld, ZConnection (Zeos), ZQery (Zeos), Datasource und ein Timer.

 

So nun müssen wir eine Datenbank in MySql anlegen.

 

Dafür am besten folgendes Tool von MySql herunterladen:

MySQL-Control Center und MySql-Administrator .

 

 

Mit der rechten Maustaste auf Databases klicken und New Database. Ich benenne die DB: nachrichten.

 

Jetzt legen wir die Felder an in denen die Nachrichten gespeichert werden.

Dazu auf Nachrichten doppelt klicken.

Dann auf Tables mit der re. Maustaste und auf new Table.

Dann erscheint folgendes:

 

Dann in die Felder folgendes wie unten eingeben

 

Bei Length den benötigten Wert eingegeben.

Ich habe für jeden User einen eigenen Table angelegt (markusnachricht usw.).

 

Nun brauchen wir auch User:

Mit der rechten Maustaste auf User Administration klicken und auf new User:

 

All Privileges nicht vergessen!

 

So DB mäßig sind wir fertig nun wieder zu Delphi .

 

Zuerst müssen wir die DB Komponenten miteinander verbinden:

ZQuery1 in Connection ZConcection1 auswählen.

Bei DataSource1 = Dataset: ZQuery1

Bei DBGrid1 Datasource = DataSource1

 

                                                              So im FormCreate Ereignis noch schnell folgendes:

 

Procedure TForm1.FormCreate(Sender: TObject);

begin

try

   ComboBox1.Items.LoadFromFile('./Namen.dat');

except

   MessageDlg('Konnte Namen.dat nicht laden!',mtError,[mbOK],0);

   end;

 

   Btn_Senden.Enabled:=false;

   StatusBar1.Panels[1].Text:= DateToStr(now);

   Memo1.Text:='';

end;

 

 

 

Beschreibung Name.dat:

Name.dat ist eine gewöhnliche Textdatei in welcher die Usernamen gespeichert sind (jeder Name in einer neuen Zeile!!) und als .dat Datei gespeichert wurde.

 

 

 

                                                   Und weiter gehts im VerbindenClick Ereignis:

 

procedure TForm1.Btn_VerbindenClick(Sender: TObject);

begin

     TempUser:=Edt_User.text;

     if Edt_User.text <> '' then

     begin

        try

        with ZConnection1 do begin

          HostName:=’127.0.0.1’;

          User:=TempUser;       // TempUser ist globale Variable da noch benötigt.

          Protocol:='mysql-4.1';

          Port:=3306;

          Database:='nachrichten';

          Password:= edt_Passwort.text;

          Connected:=true;

          Btn_Senden.Enabled:=true;

 

          Form1.Caption:='Verbunden '+ TempUser;

          MEINSQL.Select_Abfrage(TempUser);  // MEINSQL ist eine von mir erstellte Klasse siehe unten.

          DBGrid1.Visible:=true;

          ZeilenDBGrid:= ZQuery1.RecordCount;  //Anzahl global Speichern für Taksbar (blinken) wenn

                // neuer Eintrag

          Btn_Verbinden.Enabled:= false;

        end;

        except

        on e : Exception do begin

        assert (false,e.message);

 

        MessageDlg('Kann keine Verbindung zu Server herstellen!',mtError,[mbOK],0);

      end;

      end;

    end;

end;       

 

 

 

So damit haben wir mal die Verbindung zur DB erschaffen.

 

Jetzt werden wir noch eine Testnachricht in der DB speichern!

Dafür gehen wir wieder in MySQL Controlcenter und Klicken links oben auf SQL dann sehen wird

folgendes:

 

 

Diesen Text eingeben und auf das rote Rufzeichen klicken!

Damit wird der SQL-Befehl ausgeführt – wenn alles geklappt hat

erscheint folgende Meldung etwas weiter unten:

Query OK, 1 row affected (0,01) sec

 

Zur Kontrolle geben wir in diesem Fenster noch folgendes ein:

SELECT MDatum, MText FROM `markusnachricht`

Dann sollten wir die gespeicherten Daten sehen.

 

Kurz mal den Insert Befehl beschrieben:

 

Insert into nachrichten.markusnachricht (MDatum,Von,MText) Values (now(),’UserX’,’Testn’)

Nachrichten = Datenbank

markusnachricht = Table

MDatum,Von,MText = sind die Felder in die Daten gespeichert werden sollen.

Die Werte in Klammer nach Values sind die Daten die in den Feldern gespeichert werden sollen.

Wobei now() eine Funktion in SQL ist welche das Datum + Zeit ausgibt.

 

So das ganze noch mal, aber diesmal aus unserem Programm:

 

Ich lege für alle SQL-Befehle ein eigenes Unit an welches ich SQL benenne:

In diesem lege ich mir Klassen an!

 

Das sieht dann so aus:

 

unit SQL;

 

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

     Dialogs, Menus, ComCtrls, StdCtrls, TeleNachrichten;  //TeleNachrichten ist mein HauptUnit!!!!

 

type SQL_BEFEHLE  = class(TObject)

public

    procedure INSERT_BEFEHL (DB_Table : String; DB_Field :String; DB_Daten : String);

    Procedure Select_Abfrage(TempUser:String);

    Procedure GEWAEHLTEN_EINTRAG_LOESCHEN (TempUser:String;WelcherEintrag:String);

end;

 

 

implementation

 

uses ZAbstractRODataset, ZDataset;

 

 

 

 

procedure SQL_BEFEHLE.INSERT_BEFEHL (DB_Table : String; DB_Field :String; DB_Daten : String);

var SQL_Text : String;

begin

    SQL_Text:= 'Insert into ' + DB_Table + ' (' + DB_Field + ') Values ('''+DB_Daten+''' ,now() )';   //now() ist

                                                                                                                                                       //SQL function

    with Form1.ZQuery1 do

        begin

          SQL.Clear;

          SQL.Add(SQL_Text);

          ExecSQL;

          active:=false;

        end;

end;

 

 

 

 

Procedure SQL_Befehle.Select_Abfrage(TempUser:String);

begin

      with Form1.ZQuery1 do

        begin

          SQL.Clear;

          SQL.Add('Select * from '+ TempUser +'nachricht');

          Open;

          Active:=true;

        end;

end;

 

 

 

 

Procedure SQL_BEFEHLE.GEWAEHLTEN_EINTRAG_Loeschen(TempUser:String;WelcherEintrag:String);

var temp:string;

begin

temp:=Delete TempUser where MText=''''WelcherEintrag + '''' ;      
with
Form1.ZQuery1 do

        begin

          SQL.Clear;

          SQL.Add(temp);

          ExecSQL;

        end;

        Select_Abfrage(Tempuser);

        form1.Memo1.Text:='';

end;

end;

 

 

Nun muß die Klasse im Haupt-Unit deklariert werden!

Nach implementation folgendes eingeben:

 

implementation

uses SQL;  //Name der zuerst erstellen Unit

var MEINSQL : SQL_BEFEHLE;  //Anlegen der Klasse

 

{$R *.dfm}

 

 

 

Somit ist unsere Klasse im HauptUnit bekannt.

 

    Nun ins Ereignis Btn_SendenClick;

 

procedure TForm1.Btn_SendenClick(Sender: TObject);

var temp:integer;

var StTemp:string;

begin

    temP:=ComboBox1.ItemIndex;

    case temp of

    -1:  begin

              beep;

              MessageDlg('User auswählen!',mtError,[mbOK],0);

              ComboBox1.SetFocus;

         end;

    0:   StTemp:= 'User1 //dies muß an eure Bedürfnisse angepasst werden, da

    1:   StTemp:= 'User2 //diese namen an die DB weitergegeben werden siehe

    2:   StTemp:= 'User3 // 3 Zeilen weiter unten (MEINSQL.INSERT_BEFEHL)!!!

    end;

    if temp<> -1 then begin

      MEINSQL.INSERT_BEFEHL(StTemp + 'nachricht','mtext,Von,mdatum' ,memo1.Text +

                                                      ''','''+TempUser);

      MEINSQL.Select_Abfrage('nachrichten.'+TempUser);  //DbGrid aktualisieren.

      StatusBar1.Panels[0].Text:='Nachricht wurde an '+ StTemp + ' am '+ DateTimeToStr(now) +

                                                    ' verschickt';

      Memo1.Text:='';

    end;

end;

 

 

Jetzt sollte das Speichern schon funken.

 

Nun soll der Text ja auch im Memo angezeigt werden wenn man im DBGrid draufklickt also:

procedure TForm1.DBGrid1CellClick(Column: TColumn);

begin

      Memo1.Text:=DbGrid1.DataSource.DataSet.FieldByName('MText').AsString;   //Text aus Grid holen

      Application.Title:='Max-Nachrichten';  // wieder Zurücksetzen da in OnTimer Ereignis geändert wird

end;

 

 

                                                       Nun noch der Timer:

 

procedure TForm1.Timer1Timer(Sender: TObject);

var temp : Integer;

begin

  if ZConnection1.Connected=true then begin

    ZQuery1.Refresh;  //nötig da sonst nie der User verständigt wird das neue Nachricht

    temp:= ZQuery1.RecordCount;      //aktuelle Anzahl

 

if temp > ZeilenDBGrid then    //in ZeilenDBgrid ist Anzahl von Start

    begin

      MEINSQL.Select_Abfrage(TempUser);     //Nach neuen einträgen suchen (aktualisieren)

      FlashWindow(Handle, True);          //Taskbar blinken lassen

      FlashWindow(Application.Handle, True);

      beep;

      Application.Title:='Neue Nachricht';  //In Statusbar erscheint der Text

      ZeilenDBGrid:= ZQuery1.RecordCount; // Anzahl aktualisieren da sonst if immer ausgeführt wird

    end;

  end;

end;

 

                                                        Jetzt noch das Löschen Button:

 

procedure TForm1.Btn_LoeschenClick(Sender: TObject);

var antwort : Integer;

begin

  antwort:= MessageDlg('Eintrag wirklich löschen?',mtConfirmation,[mbNo,mbYes],0);

      if antwort = 6 then begin

        MEINSQL.GEWAEHLTEN_EINTRAG_LOESCHEN(TempUser,Memo1.Text);    //Eintrag aus

                                                                                                                                        DB löschen

        ZeilenDBGrid:= ZQuery1.RecordCount; // Anzahl aktualisieren

      end;

end;

 

 

 

                                                            Und zum Schluß noch sämtlichen Speicher freigeben:

Procedure TForm1.FormDestroy(Sender: TObject);

begin

    MEINSQL.Free;       //Klasse freigeben

    ZConnection1.Disconnect;

    ZConnection1.Destroy;

end;