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