Home » Tutorials » Datenbanken » MySQL direct

MySQL direct

Abfragen

Der interessantere Teil und der eigentliche Nutzen eines Datenbankzugriffs ist das Durchführen von SQL-Abfragen.

procedure TForm1.Button16Click(Sender: TObject);
var q: string;
    ex: boolean;
begin
  if assigned(FResult) then begin
    if FMysql.Status<>MYSQL_STATUS_READY then
      ShowMessage('Ein Ergebnis wurde unvollständig gelesen!');
      FreeAndNil(FResult);
  end;
  q := InputBox('Geben Sie eine Abfrage ein',
  'Welche Abfrage durchgeführt werden soll','');
  FResult := FMysql.query(q, true, ex);
  if assigned(FResult) then
    ShowMessage('Query: OK - Ergebnis gespeichert')
  else
    if ex then
      ShowMessage('Query: OK - ausgeführt')
    else
      ShowMessage('Query fehlgeschlagen: '+FMysql.LastError);
end;

In obigem Beispielcode wird die SQL-Abfrage über eine InputBox eingegeben und in der Variablen q gespeichert. Der eigentliche Kern ist der Aufruf der Methode Query. Nach der erfolgreichen Ausführung verweist FResult, das wir im private-Teil von TForm1 deklariert haben, auf die Ergebnismenge.
Im Folgenden sind zwei Beispiel-Methoden zu sehen. Die erste ist dafür zuständig, die Struktur der Ergebnismenge in einem StringGrid anzuzeigen. Wichtig ist hierbei der Typ TMysql_FieldDef.

procedure TForm1.TableStructure;
var i, j: integer;
    af: TMysql_FieldDef;
    cr: integer;
begin
  if assigned(FResult) then begin
    StringGrid1.RowCount := FResult.FieldsCount+1;
    for i:=0 to FResult.FieldsCount-1 do begin
      af:=FResult.FieldDef(i)^;
      StringGrid1.Cells[0,i+1]:=af.Name;
      StringGrid1.Cells[1,i+1]:=af.Table;
      StringGrid1.Cells[2,i+1]:=IntToStr(af.Field_Type);
      StringGrid1.Cells[3,i+1]:=IntToStr(af.Length);
      StringGrid1.Cells[4,i+1]:=IntToStr(af.Max_Length);
      StringGrid1.Cells[5,i+1]:=IntToStr(af.Flags);
      StringGrid1.Cells[6,i+1]:=IntToStr(af.Decimals);
    end;
  end;
end;

Die zweite Methode zeigt den eigentlichen Inhalt, also die Daten der Abfrage an. An diesem Beispiel ist zu erkennen, wie man also auf die Ergebnismenge einer SQL-Abfrage zugreifen kann. Dafür wird FieldValue von FResult verwendet. Die Navigation erfolgt wie in TTable mit First, Next, Prior und Last. Die Ausgabe im Beispiel erfolgt in StringGrid2.

procedure TableContent;
var i, j: integer;
    af: TMysql_FieldDef;
    cr: integer;
begin
  if assigned(FResult) then begin
    if FResult.ResultType=rtStored then begin
      cr := FResult.RecNo;
      StringGrid2.RowCount := FResult.RowsCount+1;
      StringGrid2.ColCount := FResult.FieldsCount+1;
      for i:=0 to FResult.FieldsCount-1 do begin
        af := FResult.FieldDef(i)^;
        StringGrid2.cells[i+1,0] := af.Name;
      end;
      FResult.First;
      for i:=0 to FResult.RowsCount-1 do begin
        if FResult.RecNo=cr then
          StringGrid2.Cells[0,i+1] := '*'
        else
          StringGrid2.Cells[0,i+1] := '';
        for j:=0 to FResult.FieldsCount-1 do
          StringGrid2.Cells[j+1,i+1] := FResult.FieldValue(j);
        FResult.Next;
      end;
      FResult.RecNo := cr;
    end
    else begin
      StringGrid2.RowCount := 2;
      StringGrid2.ColCount := FResult.FieldsCount+1;
      for i:=0 to FResult.FieldsCount-1 do begin
        af := FResult.FieldDef(i)^;
        StringGrid2.cells[i+1,0] := af.Name;
      end;
      for j:=0 to FResult.FieldsCount-1 do
        StringGrid2.Cells[j+1,1] := FResult.FieldValue(j);
    end;
  end;
end;

Wird die Ergebnismenge in FResult nicht mehr benötigt, muss diese freigegeben werden:

procedure TForm1.Button29Click(Sender: TObject);
begin
  FreeAndNil(FResult);
end;

Wie die Datenbankverbindung geschlossen wird, wurde bereits im Zusammenhang mit dem Verbindungsaufbau beschrieben.