![]() |
Quellcode mal bitte angucken
Liste der Anhänge anzeigen (Anzahl: 1)
So, ich habe mir innerhalb eines knapp zweitägigen Crashkurses mehr oder weniger die Grundlagen von (my)SQL angeeignet. Das heißt, ich kann eine Datenbank erstellen, eine einfache Tabelle anlegen und mit dieser Tabelle die gängigen Datenbankoperationen ausführen: Einfügen, ändern, löschen, sortieren.
Das habe ich an Hand von ![]() ![]() Ich würde, die jenigen von euch, die sich etwas mit SQL und speziell mySQL auskennen, jetzt mal bitten über den Code drüber zugucken, ob das so in Ordnung ist, also das Datenbank technische. Die Datenbank benötigt den mySQL-Server. Bevor ihr Daten eingeben könnt, müsst ihr eine Datenbank erstellen und dann die Tabelle. Die Schaltfläche "Import" läd eine csv Datei mit dem Namen "Adressen.csv" und dem Aufbau: "Namne, Vorname, Strasse, PLZ, Ort, Telefon, Handy, EMail". Das war nur für mich, um aus meiner Adressedatenbank da ein paar Datensätze reinzubekommen. Sortieren kann man die Datenbank, in dem man in das Texteingabefeld die zu sortierenden Spalten mit einem Komma getrennt eingibt und dann auf "Sortieren" klick. (Wäre bestimmt auch per Klick auf einen Spaltenkopf gegangen, aber darauf kam es mir nicht an.) Also mich interessiert, was ihr von dem Code haltet, das Design, die Funktionalität und die Bedienbarkeit der GUI spielen keine Rolle. Könnte man somit, nach diesem Projekt, sagen, dass ich die nötigsten Grundlagen beherrsche? |
Re: Quellcode mal bitte angucken
Ich würds mir ja gerne ankucken, hab aber leider keinen funktionierenden Rechner zu Hause. Vielleicht aber am Wochenende...
Wenns klappt, schau ich mal durch. |
Re: Quellcode mal bitte angucken
Den Code kannst du doch auch im Notepad öffnen. Und mit irgendwas Rechner ähnlichen musst du ja dieses Posting erstellt haben ;)
|
Re: Quellcode mal bitte angucken
Hallo Luckie,
ich kann leider keine Datenbank anlegen, obwohl ich die Konstanten (Host etc) richtig gesetzt hab. Vielleicht hast du/ich ein Verständnisproblem, was der Unterschied zwischen Datenbank und Tabelle ist... du hast ein konstante _DB: Die interpretier ich als Name der Datenbank und eine Konstante DBNAME: Das interpretier ich als der Name der Tabelle. Das kann dann aber nicht so ganz sein, da du z.B. in der Insert-Methode in die Tabelle Kontakte schreibst... Auf deutsch: ich versteh den Unterschied von _DB und DBNAME nicht? |
Re: Quellcode mal bitte angucken
Ja, das sind noch Überbleipsel aus dem gewachsenen Code. Ich hatte anfangs erstmal nur Versucht eine Verbindung zum DB-Server zu bekommen, dort habe ich _DB benutzt:
Delphi-Quellcode:
Aufruf:
procedure Connect(var ConDes: PMYSQL; const Host, User, PW, DB: string; Port:
Integer); begin if Assigned(ConDes) then begin log('Verbindungsdeskriptor initialisiert'); if Assigned(mysql_real_connect(ConDes, PChar(Host), PChar(User), PChar(PW), PChar(DB), PORT, nil, 0)) then begin log('Verbindung zum Datenbankserver hergestellt'); end else log(mysql_error(ConDes)); end else log('Initialisierung fehlgeschlagen'); end;
Delphi-Quellcode:
Beim Anlegen der Datenbank habe ich dann DBNAME genommen:
Connect(Descriptor, _HOST, _USER, _PW, _DB, _PORT);
Delphi-Quellcode:
Und selbige Konstante dann weiter benutzt. Ist etwas blöd, stimmt.
procedure TForm1.btnCreateBDClick(Sender: TObject);
var query : PChar; ErrorCode : Integer; begin query := 'CREATE DATABASE' + ' ' + DBNAME; try ErrorCode := mysql_real_query(ConDes, query, length(query)); if ErrorCode = 0 then log('Datenbank angelegt') else log(mysql_error(Descriptor)); except log('EXCEPTION Datenbank konnte nicht angelegt werden'); end; end; |
Re: Quellcode mal bitte angucken
Habs jetzt ne Datenbank erstellt gekriegt, der Unterschied zwischdn _DB und DBNAME weiss ich aber immer noch nicht..
Zu deiner Datenbank selbst: du nutzt überall den Feldtyp Text. Das macht die Datenbank nicht gerade effizient, auch wenns bei paar Adressen egal ist. Text ist ein sogenanntes Blob-Feld, und vergleichbar mit einem Memo. Da kannst du beliebig viel reinschreiben, hat aber auch gravierende Nachteile: 1) in den meisten Datenbanksystemen ist über Blob-Felder kein Suchen möglich, auch wenn bei MySQL funzt 2) du kannst über Blob-Felder keine Indizes rsp Schlüssel legen. Dadurch wird das Sortieren und deine Joins zwischen Tabellen sehr langsam, da alles sequentiell durchgescannt werden muss. Nimm also, bei Felder wie name, vorname lieber den Typ varchar, und leg dort eine maximale Länge fest. Den Typ Text kannst du z.B. verwenden, wenn du noch einen Kommentar zu einer Adresse aufnehmen willst. |
Re: Quellcode mal bitte angucken
Es gibt keinen. Lösch die Konstante _DB aus dem Quellcode und gib dort, wo sie verlangt wird, einen Leerstring an.
Danke für den Tipp. |
Re: Quellcode mal bitte angucken
Ich bekomme eine AV (im Modul libmysql.dll) beim Drücken von "DB Anlegen".
Habe die DB dann von Hand angelegt, dann ging alles. Sieht ganz gut aus. Evt. als Vorschlag für dich, zu dem Projekt passt ganz gut der embedded MySQL-Server. |
Re: Quellcode mal bitte angucken
So, ich sitz jetzt endlich wieder an meinem Rechner :)
Dein Code ist soweit OK, außer dass du für die Fehlerabfragen, wie ich schon in irgendeinem Thread erwähnt habe, mysql_error benutzen kannst. Bei Schreibe-Queryes ist vielleicht noch mysql_affected_rows ganz interessant. |
Re: Quellcode mal bitte angucken
Zitat:
|
Re: Quellcode mal bitte angucken
Zitat:
[Edit]Uff... bei mir passier ja das selbe. Muss ich mir mal ansehen |
Re: Quellcode mal bitte angucken
Zitat:
Die PLZ als Integer zu speichern ist zwar effektiv. Aber (es gibt ja immer ein aber). Wenn ich eine Postleitzahl eingebe die mir 0 beginnt stimmt natürlich die Anzeige nicht mehr und auch das Suchen würde nicht sauber funktionieren. Darum würde ich da lieber ein VarChar(5) verwenden. |
Re: Quellcode mal bitte angucken
Hallo sharky,
erklär mal bitte für alle Ahnungslosen was ein varchar(5) ist. Rainer |
Re: Quellcode mal bitte angucken
Zitat:
das ist ein Datenbankfeld das bis zu 5 Zeichen Text auf nehmen kann. |
Re: Quellcode mal bitte angucken
Danke,
hab ich nicht gewusst. Rainer |
Re: Quellcode mal bitte angucken
Zitat:
noch zwei Anmerkungen :stupid: a) Warum stellst Du die Verbindung zu mySQL-Server im OnPaint deiner Form her? Wäre es nicht besser das einmalig im OnCreate zu machen. b) Du verwendest eine Spalte deiner StringGrid zum "speichern" der ID jeder Adresse. Ich habe mir angewöhnt dafür die Eigenschaft Obejects zu missbrauchen. Diese hast Du dann nämlich auch bei TListBoxen TListViews und allem was ein TStrings Property hat. Im OnSelectCell deines StringGrids müsstest Du das so änder:
Delphi-Quellcode:
und in deinem FillStringGrid noch das:
ID := Integer(StringGrid1.Objects[0,ARow]);
// ID := StrToIntDef(StringGrid1.Cells[0, ARow], 0);
Delphi-Quellcode:
StringGrid1.Objects[0,i+1] := TObject (Kontakte[i].ID);
// StringGrid1.Cells[0, i + 1] := IntToStr(Kontakte[i].ID); |
Re: Quellcode mal bitte angucken
Zitat:
Zitat:
Delphi-Quellcode:
Dann kann man das für jede beliebige Datenbank einsetzten.
type
TKonatkte = array of String; TCols = array of String; GetKontakte(var Kontakte: TKonatkte; var Cols: TCols); FillStringGrid(SG: TStringGrid, Kontakte: TKontakte, Cols: TCols); begin SG.Cols := length(Ciols); for i := 0 to length(Cols) - 1 do begin SG.Cells[0, i] := Cols[i]; end; SG.Rows := length(Kontakte); for i := 0 to length(Kontakte) - 1 do begin ....; ....; end; end; Denn wenn ich jetzt so was mache:
SQL-Code:
dann stürzt mit alles ab. Da muss ich noch eine universelle Lösung finden
SELECT name, vorname FROM kontakte
|
Re: Quellcode mal bitte angucken
So, hier du Umsetzung:
Delphi-Quellcode:
Und ein Aufruf könnte so aussehen:
type
TRows = array of array of string; // [Cols, Rows] TCols = array of string; function ExecQuery(const query: string; var Cols: TCols; var Rows: TRows): Boolean; var MySQLRes : PMYSQL_RES; MySQLRow : PMYSQL_ROW; AffectedRows : Int64; ColCount : Cardinal; Field : PMYSQL_FIELD; i : Integer; j : Integer; ErrorCode : Integer; begin ErrorCode := mysql_select_db(Descriptor, DBNAME); if ErrorCode = 0 then begin ErrorCode := mysql_real_query(Descriptor, PChar(query), length(query)); if ErrorCode = 0 then begin MySQLRes := mysql_store_result(Descriptor); if Assigned(MySQLRes) then begin ColCount := mysql_num_fields(MySQLRes); SetLength(Cols, ColCount); for i := 0 to ColCount - 1 do begin Field := mysql_fetch_field_direct(MySQLRes, i); Cols[i] := Field.Name; end; AffectedRows := mysql_affected_rows(Descriptor); SetLength(Rows, ColCount, AffectedRows); for i := 0 to ColCount - 1 do begin for j := 0 to AffectedRows - 1 do begin MySQLRow := mysql_fetch_row(MySQLRes); Rows[i, j] := MySQLRow[i]; end; mysql_real_query(Descriptor, PChar(query), length(query)); MySQLRes := mysql_store_result(Descriptor); end; log(Format('Betroffene Zeile: %d', [mysql_affected_rows(Descriptor)])); mysql_free_result(MySQLRes); end end end; result := ErrorCode = 0; end; procedure FillGrid(SG: TStringGrid; Cols: TCols; Rows: TRows); var i, j : Integer; begin SG.ColCount := 0; SG.RowCount := 0; if Assigned(Rows) then begin SG.RowCount := length(Rows[0]); SG.ColCount := length(Cols); SG.FixedRows := 1; for i := 0 to length(Cols) - 1 do begin SG.Cols[i].Add(Cols[i]); SG.Cells[i, 0] := Cols[i]; end; for i := 0 to length(Cols) - 1 do begin for j := 0 to length(Rows[0]) - 1 do begin SG.Cells[i, j + 1] := Rows[i, j]; end; end; end; end;
Delphi-Quellcode:
if ExecQuery(query, Cols, Rows) then
FillGrid(StringGrid1, Cols, Rows) |
Re: Quellcode mal bitte angucken
375 Aufrufe! :shock: Liegt das jetzt an mir oder an dem Thema? :gruebel:
|
Re: Quellcode mal bitte angucken
Zitat:
|
Re: Quellcode mal bitte angucken
Wenn ich ehrlich sein darf: Mir gefällt der Code Style gar nicht. :duck:
Klassenlose Funktionen, globale Variablen, Records, Arrays,... alles Dinge die ich persönlich eher als Quick&Dirty bezeichnen würde. :angle2: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:53 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 by Thomas Breitkreuz