![]() |
Delphi-Version: 5
Zugriff auf MYSQL per DBExpress
Hallo Zusammen,
Zugriff auf die MYSQL per DBExpress Delphi XE5 libmysql.dll liegt im exe Ordner Ich habe das Programm 2 mal Implementiert. Einmal als VCL-Formularanwendung und einmal als Konsolenprogramm. Die Programme an sich sind identisch (bis auf die Formularanwendung spezifischen Sachen). In der Formularanwendung habe ich die Komponenten TSQLConnection, TSQLQuery auf dem Formular. In der Konsolenanwendung erzeuge ich diese. Hier der Sourcecode der Formularanwendung
Delphi-Quellcode:
hier der der Konsolenanwendung
unit Unit2;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Vcl.StdCtrls, Vcl.Buttons, Data.DBXMySQL, Data.SqlExpr, Data.FMTBcd, Vcl.Grids, Vcl.DBGrids; type TForm2 = class(TForm) BitBtn1: TBitBtn; DataSource1: TDataSource; Memo1: TMemo; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; CB_imc: TCheckBox; CB_sjs: TCheckBox; Label5: TLabel; Edit4: TEdit; SQLConnection1: TSQLConnection; SQLQuery1: TSQLQuery; procedure BitBtn1Click(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} procedure TForm2.BitBtn1Click(Sender: TObject); var imc : string; begin Memo1.Lines.Clear; SQLQuery1.Active := False; SQLQuery1.sql.Clear; if CB_imc.Checked then imc := 'inner join nagios.nagios_servicestatus ss on ss.service_object_id = s.service_object_id and ss.current_state=2 ' else imc := ''; if CB_sjs.Checked then begin // summe critical wahlweise über imc nur die die auch im moment critical sind SQLQuery1.SQL.Add('SELECT ' + 's.display_name, ' + 'sum(TIME_TO_SEC(TIMEDIFF(sc.end_time, sc.start_time))) as ausfallzeit ' + 'FROM nagios.nagios_hosts h ' + 'inner join nagios.nagios_services s on s.host_object_id = h.host_object_id ' + 'inner join nagios.nagios_servicechecks sc on sc.service_object_id = s.service_object_id ' + imc + 'where ' + 's.display_name like ' + quotedstr(edit1.text) + ' and ' + 'sc.state = 2 and ' + 'TIME_TO_SEC(TIMEDIFF(now(), sc.start_time)) < ' + edit3.text + ' ' + 'group by s.display_name ' + 'having sum(TIME_TO_SEC(TIMEDIFF(sc.end_time, sc.start_time))) > ' + edit2.text ); end else begin // einzeln critical wahlweise über imc nur die die auch im moment critical sind SQLQuery1.SQL.Add('SELECT ' + 's.display_name, ' + 'TIME_TO_SEC(TIMEDIFF(sc.end_time, sc.start_time)) ' + 'FROM nagios.nagios_hosts h ' + 'inner join nagios.nagios_services s on s.host_object_id = h.host_object_id ' + 'inner join nagios.nagios_servicechecks sc on sc.service_object_id = s.service_object_id ' + imc + 'where ' + 's.display_name like ' + quotedstr(edit1.text) + ' and ' + 'sc.state = 2 and ' + 'TIME_TO_SEC(TIMEDIFF(now(), sc.start_time)) < ' + edit3.text + ' and ' + 'TIME_TO_SEC(TIMEDIFF(sc.end_time, sc.start_time)) > ' + edit2.text ); end; SQLQuery1.Active := true; repeat Memo1.Lines.Add(SQLQuery1.FieldByName('display_name').AsString ); //+ ' Ausfallzeit: ' + floattostr(strtoint(SQLQuery1.FieldByName('ausfallzeit').AsString) / 60) + ' Minuten'); SQLQuery1.Next; until SQLQuery1.Eof; end; procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin SQLQuery1.Active := false; SQLConnection1.Connected := false; end; end.
Delphi-Quellcode:
Das Formularprogramm läuft einwandfrei.
program check_multi_af;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Data.DBXMySQL, Data.SqlExpr, Data.FMTBcd; var SQLConnection1: TSQLConnection; SQLQuery1: TSQLQuery; returncode : integer; returntext, like_service, sum_o_einzeln, imc, sum_dif_s_e, start_crit, jetzt_critical : string; begin returncode := 3; returntext := 'UNKNOWN - unbekannter Fehler !'; if ParamCount = 5 then begin sum_dif_s_e := ParamStr(1); start_crit := ParamStr(2); like_service := ParamStr(3); jetzt_critical := ParamStr(4); sum_o_einzeln := ParamStr(5); //CoInitialize(nil); SQLConnection1 := TSQLConnection.Create(nil); SQLQuery1 := TSQLQuery.Create(nil); try SQLConnection1.LoginPrompt := False; SQLConnection1.DriverName := 'MySQL'; SQLConnection1.GetDriverFunc := 'getSQLDriverMYSQL50'; SQLConnection1.LibraryName := 'dbxopenmysql50.dll'; SQLConnection1.VendorLib := 'libmysql.dll'; SQLConnection1.Params.Values['HostName'] := 'xxx'; SQLConnection1.Params.Values['Database'] := 'xxx'; SQLConnection1.Params.Values['User_Name'] := 'xxx'; SQLConnection1.Params.Values['Password'] := 'xxx'; SQLConnection1.Open; SQLConnection1.Connected := true; SQLQuery1.SQLConnection := SQLConnection1; if jetzt_critical = '1' then imc := 'inner join nagios.nagios_servicestatus ss on ss.service_object_id = s.service_object_id and ss.current_state=2 ' else imc := ''; if uppercase(sum_o_einzeln) = 'S' then begin // summe critical wahlweise über imc nur die die auch im moment critical sind SQLQuery1.SQL.Add('SELECT ' + 's.display_name, ' + 'sum(TIME_TO_SEC(TIMEDIFF(sc.end_time, sc.start_time))) as ausfallzeit ' + 'FROM nagios_hosts h ' + 'inner join nagios_services s on s.host_object_id = h.host_object_id ' + 'inner join nagios_servicechecks sc on sc.service_object_id = s.service_object_id ' + imc + 'where ' + 's.display_name like ' + quotedstr(like_service) + ' and ' + 'sc.state = 2 and ' + 'TIME_TO_SEC(TIMEDIFF(now(), sc.start_time)) < ' + start_crit + ' ' + 'group by s.display_name ' + 'having sum(TIME_TO_SEC(TIMEDIFF(sc.end_time, sc.start_time))) > ' + sum_dif_s_e ); end else begin // einzeln critical wahlweise über imc nur die die auch im moment critical sind SQLQuery1.SQL.Add('SELECT ' + 's.display_name, ' + 'TIME_TO_SEC(TIMEDIFF(sc.end_time, sc.start_time)) ' + 'FROM nagios_hosts h ' + 'inner join nagios_services s on s.host_object_id = h.host_object_id ' + 'inner join nagios_servicechecks sc on sc.service_object_id = s.service_object_id ' + imc + 'where ' + 's.display_name like ' + quotedstr(like_service) + ' and ' + 'sc.state = 2 and ' + 'TIME_TO_SEC(TIMEDIFF(now(), sc.start_time)) < ' + start_crit + ' and ' + 'TIME_TO_SEC(TIMEDIFF(sc.end_time, sc.start_time)) > ' + sum_dif_s_e ); end; SQLQuery1.Active := true; if SQLQuery1.RecordCount > 0 then begin repeat returntext := returntext + SQLQuery1.FieldByName('display_name').AsString + ', '; SQLQuery1.Next; until SQLQuery1.Eof; if copy(returntext, length(returntext) - 2, 1) = ',' then returntext := copy(returntext, 1, length(returntext) - 1); returncode := 2; returntext := 'CRITICAL - Services laufen nicht in den angegebenen Zeitraeumen ' + returntext; end else begin returncode := 0; returntext := 'OK - alle Services laufen in den angegebenen Zeitraeumen'; end; finally //CoUninitialize; writeln(returntext); SQLQuery1.Active := false; SQLConnection1.Close; end; end else begin writeln('Benutzung: check_multi_af like_service start_crit sum_dif_s_e jetzt_crit sum_o_einz' + CHR(10) + CHR(13) + 'like_service: ist die Einschraenkung nach dem like des displaynamens. s.display_name like "like_service"' + CHR(10) + CHR(13) + 'start_crit: Ist die Zeit in Sekunden die das start_time kleiner sein muss damit der Service in das Ergebnis kommt. TIME_TO_SEC(TIMEDIFF(now(), sc.start_time)) < "start_crit"' + CHR(10) + CHR(13) + 'sum_dif_s_e: Ist die Zeit in Sekunden die entweder der einzelne Service oder die Summe des Services critisch sein muss damit der Service in das Ergebnis kommt(mit oder ohne sum). sum(TIME_TO_SEC(TIMEDIFF(sc.end_time, sc.start_time))) > "sum_dif_s_e"' + CHR(10) + CHR(13) + 'jetzt_crit: Bestimmt ob der Service jetzt auch critisch sein muss damit er in das Ergebnis kommt. 1=ja, 0=nein' + CHR(10) + CHR(13) + 'sum_o_einz: Bestimmt ob jede einzelne Zeit des Auftretens des crtitschen Service betrachtet wird oder die Summe der crtitschen Zeiten eines Services. s=summe, e=einzeln' ); returncode := 3; returntext := 'UNKNOWN - Nicht genuegend Parameter !'; end; end. Bei dem Konsolenprogramm erhalte ich folgende Fehlermeldung "Der dbExpress-Treiber unterstützt der Datentyp TDBXTypes.UNKNOWN nicht. Fehlermeldung des Herstellers: . aufgetreten" der Fehler tritt an dieser Stelle auf "SQLQuery1.Active := true;" Verstehe ich nicht ist doch beides identisch. Weis einer von Euch Rat? Gruss Andreas |
AW: Zugriff auf MYSQL per DBExpress
Sowas ist doch viel zu anstrengend. Du hast unterschiedliche Eingangskriterien in den beiden Anwendungen und vielleicht irgendwo einen blöden Copy/Pastefehler drin. Eine Vergleichbarkeit ist erstmal nicht gegeben, dazu kommen noch Effekte durch eine mglw. variiernde Datensortierung.
Tu Dir doch selbst einen Gefallen und schreibe das Statement vor Active:= True ins Memo oder auf die Console und lass das Statement gegen den Server laufen. Kostet 20 Sekunden Arbeit. Entweder es knallt gleich wieder und Du erkennst den Fehler oder es läuft durch und dann wird es spannend. |
AW: Zugriff auf MYSQL per DBExpress
ich hab den Fehler gefunden. die Parameter waren an der falschen Stelle. Dann habe ich das Statement noch so umbauen müssen
Delphi-Quellcode:
mit einem Add klappte es nicht.
SQLQuery1.SQL.Add('SELECT nagios_services.display_name, sum(TIME_TO_SEC(TIMEDIFF(nagios_servicechecks.end_time, nagios_servicechecks.start_time))) as ausfallzeit ');
SQLQuery1.SQL.Add('FROM nagios_hosts '); SQLQuery1.SQL.Add('inner join nagios_services on nagios_services.host_object_id = nagios_hosts.host_object_id '); SQLQuery1.SQL.Add('inner join nagios_servicechecks on nagios_servicechecks.service_object_id = nagios_services.service_object_id '); SQLQuery1.SQL.Add(imc); SQLQuery1.SQL.Add('where nagios_services.display_name like ' + quotedstr(like_service)); SQLQuery1.SQL.Add(' and nagios_servicechecks.state = 2 and '); SQLQuery1.SQL.Add('TIME_TO_SEC(TIMEDIFF(now(), nagios_servicechecks.start_time)) < ' + start_crit + ' '); SQLQuery1.SQL.Add('group by nagios_services.display_name '); SQLQuery1.SQL.Add('having sum(TIME_TO_SEC(TIMEDIFF(nagios_servicechecks.end_time, nagios_servicechecks.start_time))) > ' + sum_dif_s_e); Nun habe ich aber das Problem das das "SQLQuery1.RecordCount" mir die falsche Anzahl an Datensätzen zurück gibt. Ich bin Deinem Rat gefolgt und gebe mit das Statement an der Konsole aus. mit diesem erhalte ich im MYSQL Query Browser z.B.: 0 Datensätze. in meinen Delphi Programm mit dem gleichen Statement sagt mein Record Count aber 40! Wie kann das den sein? |
AW: Zugriff auf MYSQL per DBExpress
Wieso hast Du nicht das geloggte Statement hier gepostet? Keine Ahnung, was nun in Deinen Variablen steht.
Und unabhängig von dem Count Attribut, wieviel Records werden denn angezeigt? Verwendest Du die gleiche Datenbank in beiden Fällen? (am besten auch hier notfalls bei CSI Thematik: 2. Query mit User, Datenbankname ausführen, mitloggen. Das Browsertool kenne ich nicht, zählt es sonst richtig? |
AW: Zugriff auf MYSQL per DBExpress
A propos Parameter, warum verwendest Du keine?
|
AW: Zugriff auf MYSQL per DBExpress
ich verstehe beide Antworten nicht.
1. ich verwende Parameter. Siehe 1. Post 2. gegoogeltes Statement? ich habe beide selber geschrieben. Was in den Variablen steht spielt doch keine Rolle. beim Recordcount gebe ich doch keine Datenbank an! Wenn ich beide Statements laufen lasse und im Memo mir die Ergebnisse ausgeben lasse bekomme ich z.B.: 10 Datensätze zurück. Wenn ich dann ein Query1.recordcount mache gibt es mir aber 40 zurück. |
AW: Zugriff auf MYSQL per DBExpress
Sieht aber überhaupt nicht nach Paramtern aus
Delphi-Quellcode:
SQLQuery1.SQL.Add('where nagios_services.display_name like ' + quotedstr(like_service));
|
AW: Zugriff auf MYSQL per DBExpress
vielleicht meinst du was anderes wie ich.
Delphi-Quellcode:
sind doch Parameter der Konsolenanwendung
if ParamCount = 5 then
begin sum_dif_s_e := ParamStr(1); start_crit := ParamStr(2); like_service := ParamStr(3); jetzt_critical := ParamStr(4); sum_o_einzeln := ParamStr(5); |
AW: Zugriff auf MYSQL per DBExpress
Ja ich meine Parameter bei der Abfrage:
Delphi-Quellcode:
Und Parameter belegen:
SQLQuery1.SQL.Add('where nagios_services.display_name like :like_service );
Delphi-Quellcode:
SQLQuery1.ParamByName('like_service').Value := like_service;
|
AW: Zugriff auf MYSQL per DBExpress
ah verstanden.
Ist das von Vorteil einen Parameter zu nehmen anstatt es so zu machen wie ich? Bevor ich es jetzt umschreibe. Weist Du ob dann das RecordCount funktioniert? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz