Thema: Delphi MySQL ohne Komponenten

Einzelnen Beitrag anzeigen

Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: MySQL ohne Komponenten

  Alt 4. Aug 2003, 12:13
So, nachdem wir jetzt wissen, wie wir eine Verbindung herstellen (und auch wieder trennen) können, werden wir jetzt einige einfache Transaktionen durchführen.

Wir werden zunächst eine neue Datenbank erstellen und ihr gleich einige Tabellen hinzufügen. In diese Tabellen fügen wir einige Datensätze ein und löschen und modifizieren einige. Außerdem werden wir uns natürlich auch Datensätze zurückgegeben lassen.


1. Das Erstellen der Datenbank

Wir wollen eine Datenbank mit dem Namen APITest erstellen. Dazu benutzen wir folgendes SQL-Statement:
CREATE DATABASE APITest Dieses verwenden wir folgendermaßen:
Delphi-Quellcode:
var
  query: PChar;
  _myCon: PMySQL;
begin
  {...}
  {Verbindung herstellen, wie in Kapitel1 beschrieben}
  {...}
  
  query := 'CREATE DATABASE APITest';
  mysql_real_query(_myCon, query, Length(query));
end;
Transaktionen werden also mit [/b]mysql_real_query()[/b] durchgeführt. Der dritte Parameter, der die Anzahl Zeichen des SQL-Statements angibt, wird benötigt, da auch binäre Daten, die Nullen enthalten, in SQL-Statement enthalten sein können. Mit Length(query) übergeben wir immer genau die richtige Anzahl Zeichen.


2. Das Erzeugen der Tabellen

Nun, da die Datenbank erzeugt ist, benötigen wir noch Tabellen, um damit arbeiten zu können. Also erzeugen wir ein paar.

Als Beispiel nehmen wir einmal ein einfaches Forum mit einer Tabelle, in der die Einträge gespeichert werden und einer, in der die Daten der Benutzer gespeichert sind. Der Einfachheit halber muss jeder Forumseintrag von einem registrierten Benutzer verfasst sein.

Die Tabelle mit den Forumsbeiträgen benötigt 4 Felder: die ID des Eintrags, die ID des Verfassers, das Eintragedatum und den eingetragenen Text.
Als SQL-Statement bedeutet das:
SQL-Code:
CREATE TABLE posts (
  id int,
  author int,
  date datetime,
  entry text
)
Außerdem benötigen wir noch eine kleine Benutzerverwaltung. Diese kommt in eine eigene Tabelle mit Feldern für die ID des Benutzers, dem Namen und das Passwort.
Die Tabelle wird mit folgendem SQL-Statement erstellt:
SQL-Code:
CREATE TABLE users (
  id int,
  name varchar(50),
  pass varchar(50),
)
So, nachdem der theoretische Teil vorbei ist, machen wir uns an die Arbeit.
Die Tabellen werden in einer eigenen Prozedur erstellt. Die Prozedur benötigt als Parameter einen Verbindungsdeskriptor (vom Typ PMySQL), der eine bereits aktive Verbindung beschreibt.

Delphi-Quellcode:
procedure MakeTables(_myCon: PMySQL);
var
  query: PChar;
begin
  mysql_select_db(_myCon, 'APITest'); //zu Datenbank "APITest" wechseln
  mysql_real_query(_myCon, 'CREATE TABLE posts(id int, author int, date datetime, entry text)', Length(query);
  mysql_real_query(_myCon, 'CREATE TABLE users(id int, name varchar(50), pass varchar(50))', Length(query));
end;
Nach Aufruf dieser Prozedur sollten die Tabellen erstellt sein. Falls sie bereits erstellt sein sollten, wird die Transaktion vom Server als ungültig angesehen und nicht ausgeführt. Eine Abfrage, ob die Tabelle bereits existiert, ist also nicht zwingend notwendig.


3. Das Ermitteln der bisherigen Einträge

Um uns alle Einträge des Gästebuchs anzeigen zu lassen, brauchen wir eine SELECT-Abfrage. Wir erstellen uns ein Record, das alle Daten eines Gästebucheintrags enthält, dieses Record speichern wir in einem Array. Anstelle der ID des Verfassers wird der Namen gespeichert.

Unsere Abfrage der Einträge sieht so aus:
SELECT * FROM posts ORDER BY id Und so wird der Namen ermittelt
SELECT name FROM users WHERE id=IDdesUsers Folgendermaßen sieht unser Record aus:
Delphi-Quellcode:
type
  TPostEntry = record
    id: Integer;
    author: String[50];
    time: String[255];
    text: String;
  end;
  TPostEntries = Array of TPostEntry;
Und nun erfolgt das Einlesen:
Delphi-Quellcode:
var
  Posts: TPostEntries;
  idAuthor: String; //zum Zwischenspeichern der Verfasser-ID
  query: PChar;
  _myCon: PMySQL;
  _myRes: PMySQL_Res; //hier wird der gesamte Ergebnissatz gespeichert
  _mySubRes: PMySQL_Res; //benötigt, um Autor zu ermmitteln
  _myRow: PMySQL_Row; //enthält den aktuellen Datensatz
  _mySubRow: PMySQL_Row; //benötigt, um Autor zu ermmitteln
  i: Integer;
begin
  
  {...}
  {Verbindung herstellen wie in Kap. 1 beschrieben}
  
  query := 'SELECT * FROM posts ORDER BY id';
  mysql_real_query(_myCon, query, Length(query));
  
  _myRes := mysql_store_result(_myCon); //alle Datensätze vom Server anfordern
  if _myRes = nil then
  begin
    ShowMessage('Es konnten keine Datensätze zurückgebenen werden. Ursache: ' + mysql_error(_myCon));
    Exit;
  end;
  
  SetLength(Posts, mysql_num_rows(_myRes);); //Posts-Array-Größe auf Anzahl der Datensätze setzen
  
  for i := 0 to High(Posts) do
  begin
    _myRow := mysql_fetch_row(_myRes); //Datensatz abholen
    Posts[i].id := InttoStr(_myRow[0]); //ID des Posts ist erstes Feld im Datensatz
    Posts[i].time := _myRow[2]; //Zeitpunkt ist drittes Feld
    Posts[i].text := _myRow[3]; //Text ist viertes Feld
    
    idAuthor := _myRow[1];
    query := PChar('SELECT name FROM users WHERE id=' + idAuthor);
    _mySubRes := mysql_store_result(_myCon);
    _mySubRow := mysql_fetch_row(_mySubRes);
    Posts[i].author := _mySubRow[0];
    
    mysql_free_result(_mySubRes); //Ergebnissatz löschen
  end;
  
  mysql_free_result(_myRes); //Ergebnissätze löschen
  
  {...}
  {Verbindung schließen oder etwas anderes machen}
end;
Einige Anmmerkungen: Die zurückgebenen Daten sind alle Strings (oder besser gesagt PChars). Um sie in Zalen umzuwandeln, muss InttoStr() genutzt werden.
Jedes Ergebnis (also jede Variable vom Typ PMySQL_Res) muss mit mysql_free_result freigegeben werden, natürlich erst, wenn sie nicht mehr benötigt wird.


4. Das Ändern vorhandener Datensätze, das Hinzufügen von neuen und das Löschen von vorhanden

Um DELETE, INSERT und UPDATE-Statements durchzuführen, wird, man glaubt es kaum, wiederum die Funktion mysql_real_query benutzt. Da dies bekannt ist, gehe ich nicht per Code näher darauf ein.
Interessant ist hier lediglich noch mysql_affected_rows: Sie gibt die Anzahl der betroffenen Zeilen eines Statements an. Genaueres ist nachzulesen unter http://www.mysql.com/documentation/m..._affected_rows.


So, das war unser kleines Tutorial. Wenn ihr noch Fragen habt, dann sagt Bescheid.
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat