Kapitel 24. APIs und Bibliotheken
Zurück |  | Weiter

## Kapitel 24. APIs und Bibliotheken

In diesem Kapitel erfahren Sie, welche APIs für MySQL zur Verfügung stehen, wo Sie sie bekommen und wie Sie sie benutzen. Die C-API wird am gründlichsten behandelt, da sie von dem MySQL-Team entwickelt wurde und die Grundlage der meisten anderen APIs bildet. Außerdem behandelt das vorliegende Kapitel die `libmysqld`-Bibliothek (den Embedded Server) sowie einige Programme, die für Anwendungsentwickler nützlich sind.

## 24.1. libmysqld, die eingebettete MySQL Server-Bibliothek

### 24.1.1. Überblick über die eingebettete MySQL Server-Bibliothek

Die MySQL Embedded Server-Bibliothek ermöglicht es, einen kompletten MySQL Server innerhalb einer Clientanwendung auszuführen. Die Hauptvorteile davon sind erhöhte Geschwindigkeit und eine einfachere Verwaltung eingebetteter Anwendungen.

Die Embedded Server-Bibliothek basiert auf der Client/Server-Version von MySQL, die in C/C++ geschrieben ist. Folglich ist auch der Embedded Server in C/C++ verfasst. In anderen Sprachen steht kein Embedded Server zur Verfügung.

Die API für die Embedded-MySQL-Version und die Client/Server-Version von MySQL sind identisch. Um eine alte Threaded-Anwendung auf die Embedded-Bibliothek umzustellen, müssen Sie normalerweise nur Aufrufe an folgende Funktionen hinzufügen:

Funktion | Wann aufrufen
`mysql_server_init()` | Sollte vor jeder anderen MySQL-Funktion aufgerufen werden, am besten am Anfang der `main()`-Funktion.
`mysql_server_end()` | Sollte vor dem Beenden des Programms aufgerufen werden.
`mysql_thread_init()` | Sollte in jedem Thread aufgerufen werden, mit dem Sie auf MySQL zugreifen.
`mysql_thread_end()` | Sollte vor `pthread_exit()` aufgerufen werden.

Dann müssen Sie Ihren Code mit `libmysqld.a` statt mit `libmysqlclient.a` verlinken.

Die `mysql_server_`xxx`()`-Funktionen sind auch in `libmysqlclient.a` enthalten, damit Sie zwischen der Embedded und der Client/Server-Version umstellen können, indem Sie Ihre Anwendung einfach mit der richtigen Bibliothek verknüpfen. Siehe Abschnitt 24.2.12.1, „`mysql_server_init()`“.

Ein Unterschied zwischen dem Embedded und dem Standalone-Server besteht darin, dass die Authentifizierung für Verbindungen im Embedded Server standardmäßig deaktiviert ist. Um sie auch für den Embedded Server zu benutzen, geben Sie die Option `--with-embedded-privilege-control` an, wenn Sie configure aufrufen, um Ihre MySQL-Distribution zu konfigurieren.

### 24.1.2. Programme mit `libmysqld` kompilieren

Um eine `libmysqld`-Bibliothek zu erhalten, sollten Sie MySQL mit der Option `--with-embedded-server` konfigurieren. Siehe Abschnitt 2.8.2, „Typische configure-Optionen“.

Wenn Sie Ihr Programm mit `libmysqld` verknüpfen, müssen Sie auch die systemspezifischen `pthread`-Bibliotheken und einige andere vom MySQL Server verwendeten Bibliotheken einbinden. Die vollständige Liste der Bibliotheken können Sie mit dem Befehl mysql_config --libmysqld-libs abrufen.

Sie müssen die richtigen Flags zum Kompilieren und Verlinken eines Threaded-Programms benutzen, auch wenn Sie in Ihrem Code nicht direkt irgendwelche Thread-Funktionen aufrufen.

Um ein C-Programm so zu kompilieren, dass es alle notwendigen Dateien enthält, um die MySQL Server-Bibliothek in eine kompilierte Version eines Programms einzubinden, verwenden Sie den C-Compiler von GNU (`gcc`). Dem Compiler müssen Sie die Speicherorte diverser Dateien mitteilen und Anweisungen geben, wie er das Programm kompilieren soll. Das folgende Beispiel zeigt, wie ein Programm auf der Kommandozeile kompiliert werden könnte:

    gcc mysql_test.c -o mysql_test -lz \
    `/usr/local/mysql/bin/mysql_config --include --libmysqld-libs`

Unmittelbar hinter dem Befehl `gcc` steht der Name der unkompilierten Datei des C-Programms. Darauf folgt die Option `-o`, die anzeigt, dass der nachfolgende Dateiname der Name ist, den der Compiler der Ausgabedatei, also dem kompilierten Programm, geben soll. Die nächste Codezeile teilt dem Compiler die Speicherorte der Include-Dateien und Bibliotheken sowie andere Einstellungen für das System mit, auf dem das Programm kompiliert wird. Wegen eines Problems mit mysql_config wird hier die Option `-lz` (für die Komprimierung) hinzugefügt. Der mysql_config-Teil ist in Backticks statt in einfache Anführungszeichen eingefasst.

### 24.1.3. Einschränkungen bei der Benutzung des eingebetteten MySQL Servers

Für den Embedded Server gelten folgende Beschränkungen:

- Keine Unterstützung für `ISAM`-Tabellen (hauptsächlich, um die Bibliothek kleiner zu halten).

- Keine benutzerdefinierten Funktionen (UDFs).

- Kein Stack Trace bei einem Core Dump.

- Kein interner RAID-Support. (Dieser ist normalerweise überflüssig, da die meisten modernen Betriebssysteme große Dateien unterstützen.)

- Sie können ihn nicht als Master oder Slave einrichten (keine Replikation).

- Auf Systemen mit wenig Arbeitsspeicher sind sehr große Ergebnismengen unter Umständen unbenutzbar.

- Von außen über Sockets oder TCP/IP kann sich kein Prozess mit dem Embedded Server verbinden. Allerdings kann er sich mit einer zwischengeschalteten Anwendung verbinden, die ihrerseits für diesen Remote Client oder externen Prozess Verbindung mit dem Embedded Server aufnimmt.

Manche dieser Beschränkungen können Sie ändern, indem Sie die Include-Datei `mysql_embed.h` bearbeiten und MySQL neu kompilieren.

### 24.1.4. Optionen des eingebetteten Servers

Alle Optionen für den mysqld-Server-Daemon können auch für eine Embedded Server-Bibliothek benutzt werden. Serveroptionen können in einem Array als Argument an die Funktion `mysql_server_init()` übergeben werden, die den Server initialisiert. Oder sie werden in einer Optionsdatei wie `my.cnf` übergeben. Um eine Optionsdatei für ein C-Programm anzugeben, verwenden Sie die Option `--defaults-file` als eines der Elemente des zweiten Arguments der `mysql_server_init()`-Funktion. Weitere Informationen über die `mysql_server_init()`-Funktion finden Sie in Abschnitt 24.2.12.1, „`mysql_server_init()`“.

Optionsdateien erleichtern das Umschalten zwischen einer Client/Server-Anwendung und einer mit Embedded MySQL. Die gemeinsamen Optionen fassen Sie in der `[server]`-Gruppe zusammen. Diese werden dann von beiden MySQL-Versionen gelesen. Client/Server-spezifische Optionen gehören in den `[mysqld]`-Abschnitt. Optionen für die MySQL Embedded Server-Bibliothek speichern Sie im Abschnitt `[embedded]` und anwendungsspezifische Optionen in einem Abschnitt namens `[ApplicationName_SERVER]`. Siehe Abschnitt 4.3.2, „my.cnf-Optionsdateien“.

### 24.1.5. Ein einfaches Embedded Server-Beispiel

Die folgenden beiden Beispielprogramme müssten unverändert auf Linux oder FreeBSD laufen. Für andere Betriebssysteme sind kleinere Anpassungen erforderlich, hauptsächlich für die Dateipfade. Die Beispiele sollen genügend Einzelheiten vermitteln, um das Problem zu verdeutlichen, aber ohne den ganzen Ballast, der für eine echte Anwendung notwendig wäre. Das erste Beispiel ist ganz einfach, das zweite ein wenig fortgeschrittener, da es eine Fehlerprüfung enthält. Das erste wird gefolgt von einem Kommandozeileneintrag, mit dem man es kompilieren kann. Unter dem zweiten wird stattdessen eine GNU-Makefile für die Kompilierung angegeben.

Beispiel 1

`test1_libmysqld.c`

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include "mysql.h"

    MYSQL *mysql;
    MYSQL_RES *results;
    MYSQL_ROW record;

    static char *server_options[] = { "mysql_test", "--defaults-file=my.cnf" };
    int num_elements = sizeof(server_options)/ sizeof(char *);

    static char *server_groups[] = { "libmysqld_server", "libmysqld_client" };

    int main(void)
    {
       mysql_server_init(num_elements, server_options, server_groups);
       mysql = mysql_init(NULL);
       mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "libmysqld_client");
       mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);

       mysql_real_connect(mysql, NULL,NULL,NULL, "database1", 0,NULL,0);

       mysql_query(mysql, "SELECT column1, column2 FROM table1");

       results = mysql_store_result(mysql);

       while((record = mysql_fetch_row(results))) {
          printf("%s - %s \n", record[0], record[1]);
       }

       mysql_free_result(results);
       mysql_close(mysql);
       mysql_server_end();

       return 0;
    }

Das Programm wird mit folgender Kommandozeile kompiliert:

    gcc test1_libmysqld.c -o test1_libmysqld -lz \
     `/usr/local/mysql/bin/mysql_config --include --libmysqld-libs`

Beispiel 2

Um das Beispiel auszuprobieren, legen Sie ein Verzeichnis namens `test2_libmysqld` auf derselben Ebene wie das MySQL-Quellverzeichnis an. Speichern Sie die Quelldatei `test2_libmysqld.c` und die `GNUmakefile` in dieses Verzeichnis und führen Sie GNU `make` innerhalb des `test2_libmysqld`-Verzeichnisses aus.

`test2_libmysqld.c`

    /*
     * Ein einfacher Beispielclient, der die MySQL Embedded Server-Bibliothek benutzt
    */

    #include <mysql.h>
    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>

    MYSQL *db_connect(const char *dbname);
    void db_disconnect(MYSQL *db);
    void db_do_query(MYSQL *db, const char *query);

    const char *server_groups[] = {
      "test2_libmysqld_SERVER", "embedded", "server", NULL
    };

    int
    main(int argc, char **argv)
    {
      MYSQL *one, *two;

      /* mysql_server_init() muss vor allen anderen mysql-* Funktionen aufgerufen werden.
       *
       * Sie können die Funktion mysql_server_init(0, NULL, NULL) benutzen; sie initialisiert
       * den Server mit groups = {
       *   "server", "embedded", NULL
       *  }.
       *
       * Eventuell setzen Sie Folgendes in Ihre $HOME/.my.cnf-Datei:

    [test2_libmysqld_SERVER]
    language = /path/to/source/of/mysql/sql/share/english

       * Natürlich können Sie argc und argv auch ändern, ehe Sie sie an
       * diese Funktion übergeben. Oder Sie erstellen neue, ganz nach Bedarf.
       * Doch alle Argumente in argv (außer dem Programmnamen
       * argv[0]) sollten gültige Optionen
       * für den MySQL Server sein.
       *
       * Wenn Sie diesen Client mit der normalen mysqlclient-Bibliothek verlinken,
       * ist diese Funktion lediglich ein Funktionsrumpf, der nichts weiter tut.
       */
      mysql_server_init(argc, argv, (char **)server_groups);

      one = db_connect("test");
      two = db_connect(NULL);

      db_do_query(one, "SHOW TABLE STATUS");
      db_do_query(two, "SHOW DATABASES");

      mysql_close(two);
      mysql_close(one);

      /* Dies muss nach allen anderen mysql-Funktionen aufgerufen werden. */
      mysql_server_end();

      exit(EXIT_SUCCESS);
    }

    static void
    die(MYSQL *db, char *fmt, ...)
    {
      va_list ap;
      va_start(ap, fmt);
      vfprintf(stderr, fmt, ap);
      va_end(ap);
      (void)putc('\n', stderr);
      if (db)
        db_disconnect(db);
      exit(EXIT_FAILURE);
    }

    MYSQL *
    db_connect(const char *dbname)
    {
      MYSQL *db = mysql_init(NULL);
      if (!db)
        die(db, "mysql_init failed: no memory");
      /*
       * Beachten Sie, dass Client und Server verschiedene Gruppennamen verwenden.
       * Das ist wichtig, da der Server nicht die Optionen des Clients und dieser nicht die Optionen
       * des Servers akzeptiert.
       */
      mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "test2_libmysqld_CLIENT");
      if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0))
        die(db, "mysql_real_connect failed: %s", mysql_error(db));

      return db;
    }

    void
    db_disconnect(MYSQL *db)
    {
      mysql_close(db);
    }

    void
    db_do_query(MYSQL *db, const char *query)
    {
      if (mysql_query(db, query) != 0)
        goto err;

      if (mysql_field_count(db) > 0)
      {
        MYSQL_RES   *res;
        MYSQL_ROW    row, end_row;
        int num_fields;

        if (!(res = mysql_store_result(db)))
          goto err;
        num_fields = mysql_num_fields(res);
        while ((row = mysql_fetch_row(res)))
        {
          (void)fputs(">> ", stdout);
          for (end_row = row + num_fields; row < end_row; ++row)
            (void)printf("%s\t", row ? (char*)*row : "NULL");
          (void)fputc('\n', stdout);
        }
        (void)fputc('\n', stdout);
        mysql_free_result(res);
      }
      else
        (void)printf("Affected rows: %lld\n", mysql_affected_rows(db));

      return;

    err:
      die(db, "db_do_query failed: %s [%s]", mysql_error(db), query);
    }

`GNUmakefile`

    # Dies setzt voraus, dass die MySQL-Software in /usr/local/mysql installiert ist
    inc      := /usr/local/mysql/include/mysql
    lib      := /usr/local/mysql/lib

    # Wenn Sie die MySQL-Software noch nicht installiert haben, versuchen Sie dies:
    #inc      := $(HOME)/mysql-5.1/include
    #lib      := $(HOME)/mysql-5.1/libmysqld

    CC       := gcc
    CPPFLAGS := -I$(inc) -D_THREAD_SAFE -D_REENTRANT
    CFLAGS   := -g -W -Wall
    LDFLAGS  := -static
    # Sie können -lmysqld in -lmysqlclient ändern, um die
    # Client/Server-Bibliothek zu benutzen
    LDLIBS    = -L$(lib) -lmysqld -lz -lm -lcrypt

    ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))
    # FreeBSD
    LDFLAGS += -pthread
    else
    # Linux vorausgesetzt
    LDLIBS += -lpthread
    endif

    # Dies funktioniert für einfache Testprogramme mit nur einer einzigen Datei
    sources := $(wildcard *.c)
    objects := $(patsubst %c,%o,$(sources))
    targets := $(basename $(sources))

    all: $(targets)

    clean:
            rm -f $(targets) $(objects) *.core

### 24.1.6. Lizenzierung des eingebetteten Servers

Wir ermutigen jeden Entwickler, freie Software zu fördern, indem er seinen Code unter der GPL oder einer ähnlichen Lizenz herausgibt. Wer dazu nicht in der Lage ist, kann eine kommerzielle Lizenz für den MySQL-Code von MySQL AB kaufen. Einzelheiten finden Sie unter http://www.mysql.com/company/legal/licensing/.

## 24.2. MySQL-C-API

Der C-API-Code wird mit MySQL zusammen ausgeliefert. Er ist in der `mysqlclient`-Bibliothek inbegriffen und ermöglicht C-Programmen den Zugriff auf die Datenbank.

Viele Clients der MySQL-Quelldistribution sind in C geschrieben. Wenn Sie Beispiele für die Nutzung der C-API suchen, schauen Sie sich diese Clients an. Zu finden sind sie im Verzeichnis `clients` der MySQL-Quelldistribution.

Die meisten anderen Client-APIs (alle außer Connector/J und Connector/NET) nutzen die `mysqlclient`-Bibliothek zur Kommunikation mit dem MySQL Server. Das bedeutet, dass Sie beispielsweise viele derselben Umgebungsvariablen einsetzen können, die auch andere Clientprogramme verwenden, da sie in der Bibliothek referenziert werden. Eine Liste dieser Variablen finden Sie unter Kapitel 8, Client- und Hilfsprogramme.

Der Client hat eine Größenbeschränkung für den Kommunikationspuffer. Für den Puffer werden anfangs 16 Kbyte reserviert, die jedoch automatisch bis hin zur Maximalgröße (16 Mbyte) ausgeweitet werden. Da Puffergrößen nur aufgrund der Nachfrage erhöht werden, werden allein dadurch, dass Sie die voreingestellte Maximalgröße erhöhen, keine größeren Ressourcen belegt. Die Überprüfung dieser Größe ist im Grunde nur eine Prüfung auf fehlerhafte Anweisungen und Kommunikationspakete.

Der Kommunikationspuffer muss groß genug sein, um eine einzelne SQL-Anweisung (für die Übertragung von Client zu Server) und eine Zeile der Rückgabedaten (für die Übertragung von Server zu Client) zu speichern. Der Kommunikationspuffer jedes Threads wird bis zum Größenlimit dynamisch vergrößert, um jede Anfrage oder Zeile handhaben zu können. Wenn Sie beispielsweise `BLOB`-Werte mit bis zu 16 Mbyte Daten haben, benötigen Sie für den Kommunikationspuffer ein Limit von mindestens 16 Mbyte (sowohl im Server als auch im Client). Das voreingestellte Limit im Client beträgt 16 Mbyte, aber im Server nur 1 Mbyte. Sie können es erhöhen, indem Sie den Wert des Parameters `max_allowed_packet` beim Serverstart heraufsetzen. Siehe Abschnitt 7.5.2, „Serverparameter feineinstellen“.

Der MySQL Server lässt jeden Kommunikationspuffer nach jeder Anfrage auf `net_buffer_length` zusammenschrumpfen. Bei Clients wird ein mit einer Verbindung zusammenhängender Puffer erst beim Schließen der Verbindung verkleinert, wenn der Arbeitsspeicher des Clients zurückgeholt wird.

Zur Programmierung mit Threads siehe Abschnitt 24.2.15, „Wie man einen Thread-Client herstellt“. Zur Erstellung einer Standalone-Anwendung, die "Server" und "Client" in demselben Programm enthält (und nicht mit einem externen MySQL Server kommuniziert), siehe Abschnitt 24.1, „libmysqld, die eingebettete MySQL Server-Bibliothek“.

### 24.2.1. C-API: Datentypen

- `MYSQL`

  Diese Struktur ist ein Handle für eine einzelne Datenbankverbindung. Sie wird für fast alle MySQL-Funktionen benutzt. Bitte versuchen Sie nicht, eine Kopie einer `MYSQL`-Struktur anzulegen. Es ist nicht garantiert, dass eine solche Kopie benutzbar ist.

- `MYSQL_RES`

  Diese Struktur stellt das Ergebnis einer Anfrage dar, die Zeilen liefert (`SELECT`, `SHOW`, `DESCRIBE`, `EXPLAIN`). Die Rückgabedaten aus der Anfrage wird im weiteren Verlauf dieses Abschnitts als Ergebnismenge bezeichnet.

- `MYSQL_ROW`

  Eine typsichere Darstellung einer Datenzeile. Sie ist zurzeit als Array gezählter Byte-Strings implementiert. (Diese dürfen nicht als auf null endende Strings behandelt werden, wenn die Feldwerte Binärdaten enthalten könnten, da solche Werte intern Nullbytes enthalten können.) Die Zeilen werden mit `mysql_fetch_row()` abgerufen.

- `MYSQL_FIELD`

  Diese Struktur enthält Informationen über ein Feld, wie beispielsweise seinen Namen, seinen Typ und seine Größe. Ihre Bestandteile werden hier genauer erklärt. Die `MYSQL_FIELD`-Strukturen von Feldern erhalten Sie, indem Sie wiederholt `mysql_fetch_field()` aufrufen. Die Werte der Felder sind nicht Teil dieser Struktur, sondern in einer `MYSQL_ROW`-Struktur enthalten.

- `MYSQL_FIELD_OFFSET`

  Dies ist eine typsichere Darstellung eines Offsets in einer MySQL-Feldliste. (Wird von `mysql_field_seek()` benutzt.) Offsets sind Feldnummern innerhalb einer Zeile. Sie werden beginnend mit null gezählt.

- `my_ulonglong`

  Dieser Typ wird für die Anzahl der Zeilen und für `mysql_affected_rows()`, `mysql_num_rows()` und `mysql_insert_id()` genutzt. Er hat einen Wertebereich von `0` bis `1.84e19`.

  Auf manchen Systemen können Werte vom Typ `my_ulonglong` nicht ausgegeben werden. In einem solchen Fall konvertieren Sie diesen in einen `unsigned long` und verwenden das Ausgabeformat `%lu`. Beispiel:

      printf ("Number of rows: %lu\n", (unsigned long) mysql_num_rows(result));

Die `MYSQL_FIELD`-Struktur hat folgende Bestandteile:

- `char * name`

  Der Name des Felds als auf null endender String. Wenn dem Feld mit einer `AS`-Klausel ein Aliasname gegeben wurde, ist der Wert von `name` der Alias.

- `char * org_name`

  Der Name des Felds als auf null endender String. Aliasnamen werden ignoriert.

- `char * table`

  Der Name der Tabelle, die dieses Feld enthält, wenn es nicht ein berechnetes Feld ist. Für berechnete Felder ist der `table`-Wert ein leerer String. Wenn der Tabelle mit einer `AS`-Klausel ein Aliasname gegeben wurde, ist der Wert von `name` der Alias.

- `char * org_table`

  Der Name der Tabelle als auf null endender String. Aliasnamen werden ignoriert.

- `char * db`

  Der Name der Datenbank, aus der das Feld stammt, als auf null endender String. Ist das Feld ein berechnetes Feld, ist `db` ein leerer String.

- `char * catalog`

  Der Katalogname. Dieser Wert ist immer `"def"`.

- `char * def`

  Der Standardwert dieses Felds als auf null endender String. Wird nur gesetzt, wenn Sie `mysql_list_fields()` verwenden.

- `unsigned long length`

  Die Feldbreite gemäß Tabellendefinition.

- `unsigned long max_length`

  Die maximale Breite des Felds für die Ergebnismenge (die Länge des längsten Feldwerts der Zeilen, die sich tatsächlich gerade in der Ergebnismenge befinden). Wenn Sie `mysql_store_result()` oder `mysql_list_fields()` benutzen, enthält dieser Wert die Höchstlänge für das Feld. Wenn Sie `mysql_use_result()` aufrufen, ist der Wert dieser Variablen null.

- `unsigned int name_length`

  Die Länge von `name`.

- `unsigned int org_name_length`

  Die Länge von `org_name`.

- `unsigned int table_length`

  Die Länge von `table`.

- `unsigned int org_table_length`

  Die Länge von `org_table`.

- `unsigned int db_length`

  Die Länge von `db`.

- `unsigned int catalog_length`

  Die Länge von `catalog`.

- `unsigned int def_length`

  Die Länge von `def`.

- `unsigned int flags`

  Verschiedene Bit-Flags für das Feld. Im Wert von `flags` können null oder mehr der folgenden Bits gesetzt sein:

  Flag-Wert | Flag-Beschreibung
  `NOT_NULL_FLAG` | Feld kann nicht `NULL` sein
  `PRI_KEY_FLAG` | Feld ist Teil eines Primärschlüssels
  `UNIQUE_KEY_FLAG` | Feld ist Teil eines eindeutigen Schlüssels
  `MULTIPLE_KEY_FLAG` | Feld ist Teil eines nichteindeutigen Schlüssels
  `UNSIGNED_FLAG` | Feld hat das Attribut `UNSIGNED`
  `ZEROFILL_FLAG` | Feld hat das Attribut `ZEROFILL`
  `BINARY_FLAG` | Feld hat das Attribut `BINARY`
  `AUTO_INCREMENT_FLAG` | Feld hat das Attribut `AUTO_INCREMENT`
  `ENUM_FLAG` | Feld ist eine `ENUM` (veraltet)
  `SET_FLAG` | Feld ist ein `SET` (veraltet)
  `BLOB_FLAG` | Feld ist ein `BLOB` oder `TEXT` (veraltet)
  `TIMESTAMP_FLAG` | Feld ist ein `TIMESTAMP` (veraltet)

  Die Flags `BLOB_FLAG`, `ENUM_FLAG`, `SET_FLAG`, und `TIMESTAMP_FLAG` sind veraltet, da sie keinen Attribut-, sondern einen Feldtyp angeben. Es ist besser, den `field->type` mit `MYSQL_TYPE_BLOB`, `MYSQL_TYPE_ENUM`, `MYSQL_TYPE_SET` oder `MYSQL_TYPE_TIMESTAMP` zu vergleichen.

  Das folgende Beispiel zeigt eine typische Verwendung des `flags`-Werts:

      if (field->flags & NOT_NULL_FLAG)
          printf("Field can't be null\n");

  Mit den folgenden Makros können Sie den booleschen Status des `flags`-Werts nachschauen:

  Flag-Status | Beschreibung
  `IS_NOT_NULL(flags)` | Ist wahr, wenn dieses Feld als `NOT NULL` definiert ist
  `IS_PRI_KEY(flags)` | Ist wahr, wenn dieses Feld ein Primärschlüssel ist
  `IS_BLOB(flags)` | Ist wahr, wenn dieses Feld ein `BLOB` oder `TEXT` ist (veraltet; bitte testen Sie stattdessen `field->type`)

- `unsigned int decimals`

  Die Anzahl der Dezimalstellen für numerische Felder.

- `unsigned int charset_nr`

  Die Nummer des Zeichensatzes für das Feld.

- `enum enum_field_types type`

  Der Typ des Felds. Der `type`-Wert kann eines der `MYSQL_TYPE_`-Symbole aus der folgenden Tabelle sein.

  Typwert | Typbeschreibung
  `MYSQL_TYPE_TINY` | `TINYINT`-Feld
  `MYSQL_TYPE_SHORT` | `SMALLINT`-Feld
  `MYSQL_TYPE_LONG` | `INTEGER`-Feld
  `MYSQL_TYPE_INT24` | `MEDIUMINT`-Feld
  `MYSQL_TYPE_LONGLONG` | `BIGINT`-Feld
  `MYSQL_TYPE_DECIMAL` | `DECIMAL`- oder `NUMERIC`-Feld
  `MYSQL_TYPE_NEWDECIMAL` | `DECIMAL`- oder `NUMERIC`-Typ für Präzisionsberechnungen
  `MYSQL_TYPE_FLOAT` | `FLOAT`-Feld
  `MYSQL_TYPE_DOUBLE` | `DOUBLE`- oder `REAL`-Feld
  `MYSQL_TYPE_BIT` | `BIT`-Feld
  `MYSQL_TYPE_TIMESTAMP` | `TIMESTAMP`-Feld
  `MYSQL_TYPE_DATE` | `DATE`-Feld
  `MYSQL_TYPE_TIME` | `TIME`-Feld
  `MYSQL_TYPE_DATETIME` | `DATETIME`-Feld
  `MYSQL_TYPE_YEAR` | `YEAR`-Feld
  `MYSQL_TYPE_STRING` | `CHAR`- oder `BINARY`-Feld
  `MYSQL_TYPE_VAR_STRING` | `VARCHAR`- oder `VARBINARY`-Feld
  `MYSQL_TYPE_BLOB` | `BLOB`- oder `TEXT`-Feld (die Maximallänge wird mit `max_length` ermittelt)
  `MYSQL_TYPE_SET` | `SET`-Feld
  `MYSQL_TYPE_ENUM` | `ENUM`-Feld
  `MYSQL_TYPE_GEOMETRY` | Feld eines raumbezogenen Typs
  `MYSQL_TYPE_NULL` | Feld mit `NULL`-Typ
  `MYSQL_TYPE_CHAR` | Veraltet; verwenden Sie stattdessen `MYSQL_TYPE_TINY`

  Mit dem Makro `IS_NUM()` können Sie testen, ob ein Feld einen numerischen Typ hat. Wenn Sie den `type`-Wert an `IS_NUM()` übergeben und TRUE zurückgeliefert wird, ist das Feld numerisch:

      if (IS_NUM(field->type))
          printf("Field is numeric\n");

### 24.2.2. C-API: Funktionsüberblick

Die Funktionen der C-API werden im Folgenden zusammengefasst und in einem späteren Abschnitt genauer beschrieben. Siehe hierzu Abschnitt 24.2.3, „C-API: Funktionsbeschreibungen“.

Funktion | Beschreibung
mysql_affected_rows() | Liefert die Anzahl der mit dem letzten `UPDATE`, `DELETE` oder `INSERT` geänderten/gelöschten/eingefügten Zeilen
mysql_autocommit() | Schaltet Autocommit ein oder aus
mysql_change_user() | Ändert den Benutzer und die Datenbank für eine offene Verbindung
mysql_charset_name() | Liefert den Namen des Standardzeichensatzes für die Verbindung
mysql_close() | Schließt eine Serververbindung
mysql_commit() | Committet die Transaktion.
mysql_connect() | Verbindet sich mit einem MySQL Server. Diese Funktion ist veraltet; verwenden Sie stattdessen `mysql_real_connect()`.
mysql_create_db() | Legt eine Datenbank an. Diese Funktion ist veraltet; verwenden Sie stattdessen die SQL-Anweisung `CREATE DATABASE`.
mysql_data_seek() | Sucht in der Ergebnismenge einer Anfrage eine beliebige Datenzeile
mysql_debug() | Führt ein `DBUG_PUSH` mit dem angegebenen String durch
mysql_drop_db() | Löscht eine Datenbank. Diese Funktion ist veraltet; verwenden Sie stattdessen die SQL-Anweisung `DROP DATABASE`.
mysql_dump_debug_info() | Lässt den Server Debugginginformationen in das Log schreiben
mysql_eof() | Stellt fest, ob die letzte Zeile einer Ergebnismenge gelesen wurde. Diese Funktion ist veraltet; verwenden Sie stattdessen `mysql_errno()` oder `mysql_error()`.
mysql_errno() | Liefert die Fehlernummer für die zuletzt aufgerufene MySQL-Funktion
mysql_error() | Liefert die Fehlermeldung für die zuletzt aufgerufene MySQL-Funktion
mysql_escape_string() | Versieht Sonderzeichen in einem String, der in einer SQL-Anweisung benutzt werden soll, mit Escape-Symbolen
mysql_fetch_field() | Liefert den Typ des nächsten Tabellenfelds.
mysql_fetch_field_direct() | Liefert den Typ des Tabellenfelds mit der gegebenen Feldnummer
mysql_fetch_fields() | Liefert ein Array aller Feldstrukturen
mysql_fetch_lengths() | Liefert die Längen aller Spalten der aktuellen Zeile
mysql_fetch_row() | Holt die nächste Zeile der Ergebnismenge ab
mysql_field_seek() | Setzt den Spalten-Cursor auf eine gegebene Spalte
mysql_field_count() | Liefert die Anzahl der Ergebnisspalten der letzten Anweisung
mysql_field_tell() | Liefert die Position des Feld-Cursors, der für das letzte `mysql_fetch_field()` verwendet wurde
mysql_free_result() | Gibt den von einer Ergebnismenge belegten Speicher frei
mysql_get_client_info() | Liefert Versionsinformationen für den Client als String
mysql_get_client_version() | Liefert Versionsinformationen für den Client als Integer
mysql_get_host_info() | Liefert einen String, der die Verbindung beschreibt
mysql_get_server_version() | Liefert die Versionsnummer des Servers als Integer.
mysql_get_proto_info() | Liefert die Protokollversion der Verbindung
mysql_get_server_info() | Liefert die Versionsnummer des Servers
mysql_info() | Liefert Informationen über die zuletzt ausgeführte Anfrage
mysql_init() | Holt oder initialisiert eine `MYSQL`-Struktur
mysql_insert_id() | Liefert die für eine `AUTO_INCREMENT`-Spalte von der vorhergehenden Anfrage generierte ID
mysql_kill() | Hält einen gegebenen Thread an
mysql_library_end() | Finalisiert die MySQL-C-API-Bibliothek
mysql_library_init() | Initialisiert die MySQL-C-API-Bibliothek
mysql_list_dbs() | Liefert Datenbanknamen, die mit einem einfachen regulären Ausdruck übereinstimmen
mysql_list_fields() | Liefert Feldnamen, die mit einem einfachen regulären Ausdruck übereinstimmen
mysql_list_processes() | Liefert eine Liste der aktuellen Server-Threads
mysql_list_tables() | Liefert Tabellennamen, die mit einem einfachen regulären Ausdruck übereinstimmen
mysql_more_results() | Prüft, ob noch weitere Ergebnisse vorhanden sind
mysql_next_result() | Liefert/initiiert das nächste Ergebnis für Mehrfachanweisungen
mysql_num_fields() | Liefert die Anzahl der Spalten einer Ergebnismenge
mysql_num_rows() | Liefert die Anzahl der Zeilen einer Ergebnismenge
mysql_options() | Stellt Verbindungsoptionen für `mysql_connect()` ein
mysql_ping() | Prüft, ob die Serververbindung funktioniert, und baut bei Bedarf eine neue Verbindung auf
mysql_query() | Führt eine SQL-Anfrage aus, die als auf null endender String angegeben ist.
mysql_real_connect() | Verbindet sich mit einem MySQL Server
mysql_real_escape_string() | Versieht Sonderzeichen in einem String, der in einer SQL-Anweisung benutzt werden soll, mit Escape-Symbolen, wobei der aktuelle Zeichensatz der Verbindung berücksichtigt wird
mysql_real_query() | Führt eine als abgezählter String angegebene SQL-Anfrage aus
mysql_refresh() | Schreibt Tabellen und Caches auf die Platte zurück oder setzt sie zurück
mysql_reload() | Lässt den Server die Berechtigungstabellen neu laden
mysql_rollback() | Rollt die Transaktion zurück
mysql_row_seek() | Findet einen Zeilen-Offset in einer Ergebnismenge anhand des Rückgabewerts von `mysql_row_tell()`
mysql_row_tell() | Liefert die Position des Zeilen-Cursors
mysql_select_db() | Wählt eine Datenbank aus
mysql_server_end() | Finalisiert die Embedded Server-Bibliothek
mysql_server_init() | Initialisiert die Embedded Server-Bibliothek
mysql_set_server_option() | Setzt eine Option für die Verbindung (wie `multi-statements`)
mysql_sqlstate() | Liefert den SQLSTATE-Fehlercode für den letzten Fehler
mysql_shutdown() | Fährt den Datenbankserver herunter
mysql_stat() | Liefert den Serverstatus als String
mysql_store_result() | Holt eine vollständige Ergebnismenge auf den Client
mysql_thread_id() | Liefert die aktuelle Thread-ID
mysql_thread_safe() | Liefert 1, wenn die Clients als Thread-sicher kompiliert wurden
mysql_use_result() | Initiiert einen zeilenweisen Abruf der Ergebnismenge
mysql_warning_count() | Liefert die Anzahl der Warnungen für die vorangehende SQL-Anweisung

Anwendungsprogramme sollten sich an folgende Vorgehensweise halten, wenn sie mit MySQL zusammenarbeiten wollen:

1. Sie initialisieren die MySQL-Bibliothek durch Aufruf von `mysql_library_init()`. Die Bibliothek kann entweder die `mysqlclient`-C-Clientbibliothek oder die `mysqld`-Embedded Server-Bibliothek sein, je nachdem, ob die Anwendung mit dem Flag `-libmysqlclient` oder `-libmysqld` verlinkt worden ist.

2. Sie initialisieren einen Verbindungs-Handler durch Aufruf von `mysql_init()` und verbinden sich durch `mysql_real_connect()` mit dem Server.

3. Sie geben ihre SQL-Anweisungen und verarbeiten die Ergebnisse. (Im Folgenden wird genauer beschrieben, wie dies getan wird.)

4. Sie schließen die Verbindung zum MySQL Server durch Aufruf von `mysql_close()`.

5. Sie beenden die Nutzung der MySQL-Bibliothek durch Aufruf von `mysql_library_end()`.

`mysql_library_init()` und `mysql_library_end()` werden aufgerufen, um die MySQL-Bibliothek richtig zu initialisieren und zu finalisieren. Für Anwendungen, die mit der Clientbibliothek verlinkt sind, bietet diese Funktionen eine verbesserte Speicherverwaltung. Wenn Sie `mysql_library_end()` nicht aufrufen, bleibt weiterhin ein Arbeitsspeicherblock reserviert. (Zwar belegt die Anwendung deswegen nicht mehr Speicher, aber bestimmte Detektoren für Speicherlecks würden sich beschweren.) Für Anwendungen, die mit dem Embedded Server verlinkt sind, starten und stoppen diese Aufrufe den Server.

`mysql_library_init()` und `mysql_library_end()` sind in Wirklichkeit `#define`-Symbole und somit äquivalent zu `mysql_server_init()` und `mysql_server_end()`, aber die anderen Namen betonen stärker, dass diese Funktionen immer vor und nach der Benutzung einer MySQL-Bibliothek aufgerufen werden müssen, egal ob die Anwendung die `mysqlclient`- oder die `mysqld`-Bibliothek verwendet. In älteren MySQL-Versionen können Sie stattdessen `mysql_server_init()` und `mysql_server_end()` aufrufen.

Sie können den Aufruf von `mysql_library_init()` auch weglassen, da `mysql_init()` diese Funktion automatisch aufruft, wenn es notwendig ist.

Um sich mit dem Server zu verbinden, initialisieren Sie mit `mysql_init()` einen Verbindungs-Handler und rufen `mysql_real_connect()` mit diesem Handler (sowie anderen Informationen, wie zum Beispiel Hostname, Benutzername und Passwort) auf. Beim Verbinden setzt `mysql_real_connect()` das `reconnect`-Flag (ein Teil der `MYSQL`-Struktur) auf den Wert `1`, wenn die API-Version älter als 5.0.3 ist, oder auf `0`, wenn sie neuer ist. Wenn dieses Flag den Wert `1` hat, bedeutet dies: Falls eine Anweisung wegen Verbindungsabbruchs nicht ausgeführt werden kann, versucht das System, sich erneut mit dem Server zu verbinden, ehe es aufgibt. Seit MySQL 5.0.13 können Sie das Verhalten in Bezug auf Neuverbindungen mit der Option `MYSQL_OPT_RECONNECT` von `mysql_options()` steuern. Wenn Sie die Verbindung nicht mehr benötigen, beenden Sie sie mit `mysql_close()`.

Während eine Verbindung aktiv ist, kann der Client SQL-Anweisungen mit `mysql_query()` oder `mysql_real_query()` an den Server senden. Der Unterschied ist der, dass `mysql_query()` die Anfrage als auf null endenden String erwartet, während `mysql_real_query()` mit einem abgezählten String rechnet. Wenn der String Binärdaten enthält (die auch Nullbytes umfassen können), müssen Sie `mysql_real_query()` verwenden.

Für alle Nicht-`SELECT`-Anfragen (beispielsweise `INSERT`, `UPDATE`, `DELETE`) können Sie die Anzahl der betroffenen Zeilen durch `mysql_affected_rows()` ermitteln.

Bei `SELECT`-Anfragen rufen Sie die betroffenen Zeilen als Ergebnismenge ab. (Beachten Sie, dass manche Anweisungen insofern `SELECT`-ähnlich sind, als sie Zeilen zurückliefern. Dazu gehören `SHOW`, `DESCRIBE` und `EXPLAIN`. Diese sollten ebenso wie `SELECT`-Anweisungen behandelt werden.)

Ein Client hat zwei Möglichkeiten, mit Ergebnismengen umzugehen: Erstens kann er die gesamte Ergebnismenge in einem Schwung abholen, indem er `mysql_store_result()` aufruft. Diese Funktion holt sich vom Server alle von der Anfrage gelieferten Zeilen und speichert sie auf dem Client. Die zweite Möglichkeit besteht darin, die Ergebnismenge mit `mysql_use_result()` zeilenweise abzurufen. Diese Funktion initialisiert den Datenabruf, holt aber die Zeilen vom Server nicht wirklich ab.

In beiden Fällen greifen Sie mit `mysql_fetch_row()` auf die Zeilen zu. Mit `mysql_store_result()` greift sich `mysql_fetch_row()` Zeilen, die vom Server bereits abgeholt worden sind. Mit `mysql_use_result()` ruft `mysql_fetch_row()` die jeweilige Zeile selbst vom Server. Informationen über den Umfang der Daten in den Zeilen liefert Ihnen `mysql_fetch_lengths()`.

Wenn Sie mit einer Ergebnismenge fertig sind, geben Sie mit `mysql_free_result()` ihren Arbeitsspeicher wieder frei.

Die beiden Abrufmechanismen ergänzen einander. Clientprogramme sollten den Ansatz verfolgen, der für ihre Zwecke am besten geeignet ist. In der Praxis wird `mysql_store_result()` von den Clients häufiger verwendet.

`mysql_store_result()` hat einen Vorteil. Da bereits alle Zeilen auf den Client geladen wurden, können Sie nicht nur der Reihe nach auf sie zugreifen, sondern sich mit `mysql_data_seek()` oder `mysql_row_seek()` in der Ergebnismenge vor- und zurückbewegen und auf eine andere Zeilenposition in der Ergebnismenge gehen. Sie können überdies mit `mysql_num_rows()` herausfinden, wie viele Zeilen die Ergebnismenge hat. Allerdings kann `mysql_store_result()` bei großen Ergebnismengen auch viel Speicher belegen, wodurch die Gefahr von `out-of-memory`-Bedingungen wächst.

`mysql_use_result()` hat den Vorteil, dass der Client nicht so viel Arbeitsspeicher für die Ergebnismenge benötigt, da er immer nur eine einzige Zeile speichern muss (und durch den geringeren Aufwand bei der Zuweisung kann `mysql_use_result()` überdies schneller sein). Die Nachteile: Sie müssen jede Zeile schnell verarbeiten, um den Server nicht aufzuhalten, und Sie haben keinen beliebigen Zugriff auf die Ergebnismenge (sondern können nur sequenziell auf die Zeilen zugreifen). Außerdem kennen Sie die Anzahl der Zeilen in der Ergebnismenge erst, wenn Sie sie alle abgeholt haben. Hinzu kommt, dass Sie sämtliche Zeilen abholen müssen, und zwar selbst dann, wenn Sie mitten in der Verarbeitung die gesuchten Informationen bereits gefunden haben.

Den Clients ermöglicht diese API, auf Anweisungen in angemessener Form zu reagieren (also die Zeilen nur nach Bedarf abzuholen), ohne zu wissen, ob die Anweisung ein `SELECT` ist. Dies erreichen Sie, indem Sie `mysql_store_result()` nach jeder `mysql_query()` (oder `mysql_real_query()`) aufrufen. Wenn der Ergebnismengenaufruf Erfolg hat, war die Anweisung ein `SELECT` und Sie können die Zeilen einlesen. Schlägt der Ergebnismengenaufruf fehl, so ermitteln Sie mit `mysql_field_count()`, ob überhaupt ein Ergebnis zu erwarten war. Wenn `mysql_field_count()` null zurückliefert, ergab die Anweisung keine Daten (war also ein `INSERT`, `UPDATE`, `DELETE` oder etwas Ähnliches), von denen man auch keine Rückgabezeilen erwarten konnte. Wenn `mysql_field_count()` einen von null verschiedenen Wert hat, hätte die Anweisung eigentlich Zeilen zurückgeben sollen, hat es aber nicht getan. Dies deutet auf eine fehlgeschlagene `SELECT`-Anweisung hin. Ein Beispiel finden Sie unter `mysql_field_count()`.

Sowohl `mysql_store_result()` als auch `mysql_use_result()` liefern Ihnen Informationen über die Felder, aus denen die Ergebnismenge besteht (die Anzahl der Felder, ihre Namen und Typen und so weiter). Sie können auf die Feldinformationen in der Zeile sequenziell zugreifen, indem Sie wiederholt `mysql_fetch_field()` aufrufen, oder anhand der Feldnummer, indem Sie `mysql_fetch_field_direct()` aufrufen. Die aktuelle Cursor-Position für das Feld können Sie durch `mysql_field_seek()` ändern. Wenn Sie den Feld-Cursor verstellen, wirkt sich das auf nachfolgende `mysql_fetch_field()`-Aufrufe aus. Sie können die Feldinformationen auch alle auf einmal abholen, indem Sie `mysql_fetch_fields()` aufrufen.

Um Fehler zu entdecken und zu melden, gibt Ihnen MySQL über die Funktionen `mysql_errno()` und `mysql_error()` Zugriff auf Fehlerinformationen. Diese Funktionen geben den Fehlercode oder die Fehlermeldung für die zuletzt aufgerufene Funktion zurück, die mit oder ohne Erfolg gelaufen sein kann. So können Sie ermitteln, wann welcher Fehler aufgetreten ist.

### 24.2.3. C-API: Funktionsbeschreibungen

In den folgenden Beschreibungen meint ein Parameter oder Rückgabewert von `NULL` einen `NULL`-Wert im Sinne der Programmiersprache C und keinen `NULL`-Wert von MySQL.

Funktionen, die einen Wert liefern, geben normalerweise einen Zeiger oder einen Integer zurück. Wenn nichts anderes angegeben ist, liefern Funktionen, die einen Zeiger zurückgeben, bei Erfolg einen von `NULL` verschiedenen Wert und bei Misserfolg einen `NULL`-Wert, und Funktionen, die einen Integer liefern, geben bei Erfolg null und bei Misserfolg einen von null verschiedenen Wert zurück. Beachten Sie, dass „von null verschieden“ genau das meint, was es sagt: Sofern die Funktionsbeschreibung nichts Abweichendes festlegt, können Sie diesen Wert mit nichts anderem als null vergleichen:

    if (result)                   /* richtig */
        ... error ...

    if (result < 0)               /* falsch */
        ... error ...

      if (result == -1)             /* falsch */
        ... error ...

Wenn eine Funktion einen Fehler zurückliefert, finden Sie im Unterabschnitt Fehler der jeweiligen Funktionsbeschreibung eine Liste der möglichen Fehlertypen. Welcher dieser Fehler auftrat, ermitteln Sie mit `mysql_errno()`. Eine String-Darstellung des Fehlers erhalten Sie durch `mysql_error()`.

#### 24.2.3.1. `mysql_affected_rows()`

`my_ulonglong mysql_affected_rows(MYSQL *mysql)`

Beschreibung

Liefert die Anzahl der vom letzten `UPDATE` aktualisierten, vom letzten `DELETE` gelöschten oder vom letzten `INSERT` eingefügten Zeilen. Kann für `UPDATE`-, `DELETE`- oder `INSERT`-Anweisungen direkt nach `mysql_query()` aufgerufen werden. Bei `SELECT`-Anweisungen funktioniert `mysql_affected_rows()` genau wie `mysql_num_rows()`.

Rückgabewerte

Ein Integer größer null zeigt die Anzahl der betroffenen oder abgerufenen Zeilen an. Null bedeutet, dass mit dem `UPDATE` keine Zeilen aktualisiert wurden, dass keine Zeilen zu der `WHERE`-Klausel der Anfrage gepasst haben oder die Anfrage noch gar nicht ausgeführt worden ist. -1 bedeutet, dass die Anfrage einen Fehler zurückgeliefert hat oder, bei einer `SELECT`-Anfrage, dass `mysql_affected_rows()` vor `mysql_store_result()` aufgerufen wurde. Da `mysql_affected_rows()` einen vorzeichenlosen Wert liefert, können Sie -1 feststellen, indem Sie den Rückgabewert mit `(my_ulonglong)-1` vergleichen (oder mit `(my_ulonglong)~0`; das ist dasselbe).

Fehler

Keine.

Beispiel

    mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10");
    printf("%ld products updated",(long) mysql_affected_rows(&mysql));

Wenn Sie bei einer Verbindung mit mysqld das Flag `CLIENT_FOUND_ROWS` angeben, liefert `mysql_affected_rows()` die Anzahl der Zeilen, die die `WHERE`-Klausel von `UPDATE`-Anweisungen erkannt hat.

Beachten Sie, dass `mysql_affected_rows()` bei Verwendung eines `REPLACE`-Befehls 2 liefert, wenn die neue Zeile eine alte ersetzt, da hier eine Zeile eingefügt wird, nachdem das Duplikat gelöscht worden ist.

Wenn Sie mit `INSERT ... ON DUPLICATE KEY UPDATE` eine Zeile einfügen, liefert `mysql_affected_rows()` den Wert 1, wenn die Zeile als neue Zeile eingefügt wurde, und 2, wenn eine vorhandene Zeile geändert wurde.

#### 24.2.3.2. `mysql_autocommit()`

`my_bool mysql_autocommit(MYSQL *mysql, my_bool mode)`

Beschreibung

Schaltet den Autocommit-Modus ein, wenn `mode` 1 ist, und aus, wenn `mode` 0 ist.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

Fehler

Keine.

#### 24.2.3.3. `mysql_change_user()`

`my_bool mysql_change_user(MYSQL *mysql, const char *user, const char *password, const char *db)`

Beschreibung

Wechselt auf der durch `mysql` angegebenen Verbindung den Benutzer und macht die in `db` angegebene zur (aktuellen) Standarddatenbank. In nachfolgenden Anfragen ist diese Datenbank dann der Standardbezugsrahmen für Tabellenverweise, die nicht explizit eine Datenbank angeben.

`mysql_change_user()` scheitert, wenn der Benutzer sich nicht authentifizieren kann oder keine Berechtigung zur Nutzung der Datenbank hat. In diesem Fall werden Benutzer und Datenbank nicht geändert.

Der Parameter `db` kann auf `NULL` gesetzt werden, wenn keine Standarddatenbank vorgegeben werden soll.

Dieser Befehl veranlasst immer ein `ROLLBACK` aller laufenden Transaktionen, schließt alle temporären Tabellen, hebt Tabellensperren auf und setzt den Status so zurück, als hätte jemand eine ganz neue Verbindung aufgebaut. Das geschieht sogar dann, wenn der Benutzer nicht wechselt.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

Fehler

Dieselben wie bei `mysql_real_connect()`.

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

- `ER_UNKNOWN_COM_ERROR`

  Der MySQL Server implementiert diesen Befehl gar nicht (wahrscheinlich ein älterer Server).

- `ER_ACCESS_DENIED_ERROR`

  Benutzer oder Passwort ist falsch.

- `ER_BAD_DB_ERROR`

  Die Datenbank existiert nicht.

- `ER_DBACCESS_DENIED_ERROR`

  Der Benutzer hat keine Zugriffsrechte auf die Datenbank.

- `ER_WRONG_DB_NAME`

  Der Datenbankname war zu lang.

Beispiel

    if (mysql_change_user(&mysql, "user", "password", "new_database"))
    {
       fprintf(stderr, "Failed to change user.  Error: %s\n",
               mysql_error(&mysql));
    }

#### 24.2.3.4. `mysql_character_set_name()`

`const char *mysql_character_set_name(MYSQL *mysql)`

Beschreibung

Gibt den Standardzeichensatz für die aktuelle Verbindung zurück.

Rückgabewerte

Der Standardzeichensatz.

Fehler

Keine.

#### 24.2.3.5. `mysql_close()`

`void mysql_close(MYSQL *mysql)`

Beschreibung

`mysql_close()` schließt eine zuvor geöffnete Verbindung und gibt den Verbindungs-Handle frei, den `mysql` benutzt hat, wenn der Handle automatisch von `mysql_init()` oder `mysql_connect()` zugewiesen worden war.

Rückgabewerte

Keine.

Fehler

Keine.

#### 24.2.3.6. `mysql_commit()`

`my_bool mysql_commit(MYSQL *mysql)`

Beschreibung

Committet die laufende Transaktion.

Was diese Funktion tut, hängt von dem Wert der Systemvariablen `completion_type` ab. Wenn der `completion_type` 2 ist, gibt der Server nach Beendigung der Transaktion Ressourcen frei und schließt die Clientverbindung. Das Clientprogramm sollte `mysql_close()` aufrufen, um die Verbindung von der Clientseite aus zu schließen.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

Fehler

Keine.

#### 24.2.3.7. `mysql_connect()`

`MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)`

Beschreibung

Diese Funktion ist veraltet. Stattdessen sollte `mysql_real_connect()` verwendet werden.

`mysql_connect()` versucht, eine Verbindung zu einer auf dem `host` laufenden MySQL-Datenbank-Engine herzustellen. `mysql_connect()` muss erfolgreich gelaufen sein, ehe Sie irgendeine der anderen API-Funktionen ausführen können, ausgenommen `mysql_get_client_info()`.

Die Parameter haben dieselbe Bedeutung wie die entsprechenden Parameter für `mysql_real_connect()`, mit dem Unterschied, dass der Verbindungsparameter `NULL` sein kann. In diesem Fall weist die C-API automatisch Speicher für die Verbindungsstruktur zu und gibt ihn wieder frei, wenn Sie `mysql_close()` aufrufen. Der Nachteil: Sie können keine Fehlermeldung abrufen, wenn die Verbindung scheitert. (Um von `mysql_errno()` oder `mysql_error()` Fehlerinformationen zu bekommen, müssen Sie einen gültigen `MYSQL`-Zeiger zur Verfügung stellen.)

Rückgabewerte

Dieselben wie für `mysql_real_connect()`.

Fehler

Dieselben wie für `mysql_real_connect()`.

#### 24.2.3.8. `mysql_create_db()`

`int mysql_create_db(MYSQL *mysql, const char *db)`

Beschreibung

Legt die im `db`-Parameter genannte Datenbank an.

Diese Funktion ist veraltet. Bitte verwenden Sie stattdessen `mysql_query()`, um eine SQL-`CREATE DATABASE`-Anweisung zu geben.

Rückgabewerte

Null, wenn die Datenbank erfolgreich angelegt wurde, und ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

Beispiel

    if(mysql_create_db(&mysql, "my_database"))
    {
       fprintf(stderr, "Failed to create new database.  Error: %s\n",
               mysql_error(&mysql));
    }

#### 24.2.3.9. `mysql_data_seek()`

`void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset)`

Beschreibung

Findet eine beliebige Zeile in einer Ergebnismenge. Der `offset`-Wert ist eine Zeilennummer zwischen `0` und `mysql_num_rows(result)-1`.

Da für diese Funktion erforderlich ist, dass die Ergebnismengenstruktur die gesamte Ergebnismenge enthält, kann `mysql_data_seek()` nur in Verbindung mit `mysql_store_result()` und nicht mit `mysql_use_result()` verwendet werden.

Rückgabewerte

Keine.

Fehler

Keine.

#### 24.2.3.10. `mysql_debug()`

`void mysql_debug(const char *debug)`

Beschreibung

Führt `DBUG_PUSH` auf dem gegebenen String aus. `mysql_debug()` benutzt die Fred Fish-Debugbibliothek. Um diese Funktion benutzen zu können, müssen Sie die Clientbibliothek mit Debuggingunterstützung kompilieren. Siehe Abschnitt E.1, „Einen MySQL-Server debuggen“ und Abschnitt E.2, „Einen MySQL-Client debuggen“.

Rückgabewerte

Keine.

Fehler

Keine.

Beispiel

Dieser Aufruf lässt die Clientbibliothek eine Trace-Datei iin `/tmp/client.trace` auf dem Clientcomputer generieren:

    mysql_debug("d:t:O,/tmp/client.trace");

#### 24.2.3.11. `mysql_drop_db()`

`int mysql_drop_db(MYSQL *mysql, const char *db)`

Beschreibung

Löscht die im `db`-Parameter angegebene Datenbank.

Diese Funktion ist veraltet. Bitte benutzen Sie stattdessen `mysql_query()`, um eine SQL-`DROP DATABASE`-Anweisung zu erteilen.

Rückgabewerte

Null, wenn die Datenbank erfolgreich gelöscht wurde. Ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

Beispiel

    if(mysql_drop_db(&mysql, "my_database"))
      fprintf(stderr, "Failed to drop the database: Error: %s\n",
              mysql_error(&mysql));

#### 24.2.3.12. `mysql_dump_debug_info()`

`int mysql_dump_debug_info(MYSQL *mysql)`

Beschreibung

Weist den Server an, Debugginginformationen in das Log zu schreiben. Damit dies funktioniert, benötigt der Benutzer das `SUPER`-Recht.

Rückgabewerte

Null, wenn der Befehl Erfolg hatte. Ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.13. `mysql_eof()`

`my_bool mysql_eof(MYSQL_RES *result)`

Beschreibung

Diese Funktion ist veraltet. `mysql_errno()` oder `mysql_error()` können stattdessen verwendet werden.

`mysql_eof()` stellt fest, ob die letzte Zeile einer Ergebnismenge gelesen worden ist.

Wenn Sie eine Ergebnismenge mit einem erfolgreichen Aufruf von `mysql_store_result()` abrufen, empfängt der Client die gesamte Menge mit einer einzigen Operation. Der Rückgabewert `NULL` von `mysql_fetch_row()` bedeutet in diesem Fall immer, dass das Ende der Ergebnismenge erreicht wurde, sodass sich `mysql_eof()` erübrigt. In Verbindung mit `mysql_store_result()` liefert `mysql_eof()` immer TRUE.

Wenn Sie dagegen den Abruf einer Ergebnismenge mit `mysql_use_result()` initiieren, werden die Zeilen eine nach der anderen mit wiederholten `mysql_fetch_row()`-Aufrufen vom Server geholt. Da bei diesem Prozess ein Verbindungsfehler auftreten kann, bedeutet eine `NULL`-Rückgabe von `mysql_fetch_row()` nicht unbedingt, dass ganz normal das Ende der Ergebnismenge erreicht wurde. In diesem Fall können Sie mit `mysql_eof()` feststellen, was tatsächlich geschah. `mysql_eof()` liefert einen von null verschiedenen Wert, wenn das Ende der Ergebnismenge erreicht wurde, und null, wenn ein Fehler auftrat.

Eigentlich ist `mysql_eof()` älter als die MySQL-Standardfehlerfunktionen `mysql_errno()` und `mysql_error()`. Da diese Fehlerfunktionen dieselben Informationen liefern, bevorzugen wir sie gegenüber der veralteten Funktion `mysql_eof()`. (Eigentlich geben sie sogar mehr Informationen, da `mysql_eof()` nur einen booleschen Wert zurückgibt, während die Fehlerfunktionen auch den Grund für einen Fehler verraten.)

Rückgabewerte

Null, wenn kein Fehler auftrat. Ein von null verschiedener Wert, wenn das Ende der Ergebnismenge erreicht wurde.

Fehler

Keine.

Beispiel

Das folgende Beispiel zeigt, wie sich `mysql_eof()` einsetzen lässt:

    mysql_query(&mysql,"SELECT * FROM some_table");
    result = mysql_use_result(&mysql);
    while((row = mysql_fetch_row(result)))
    {
        // Tu etwas mit den Daten
    }
    if(!mysql_eof(result))  // mysql_fetch_row() scheiterte wegen eines Fehlers
    {
        fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
    }

Sie können jedoch denselben Effekt auch mit den Standardfehlerfunktionen von MySQL erzielen:

    mysql_query(&mysql,"SELECT * FROM some_table");
    result = mysql_use_result(&mysql);
    while((row = mysql_fetch_row(result)))
    {
      // Tu etwas mit den Daten
    }
      if(mysql_errno(&mysql))  // mysql_fetch_row() scheiterte wegen eines Fehlers
    {
        fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
    }

#### 24.2.3.14. `mysql_errno()`

`unsigned int mysql_errno(MYSQL *mysql)`

Beschreibung

Für die von `mysql` angegebene Verbindung liefert `mysql_errno()` den Fehlercode zu der zuletzt aufgerufenen API-Funktion, die mit Erfolg gelaufen oder gescheitert sein kann. Der Rückgabewert null bedeutet, dass kein Fehler auftrat. Die Nummern der Clientfehlermeldungen sind in der MySQL-Header-Datei `errmsg.h` aufgelistet. Die Nummern der Serverfehlermeldungen stehen in der Datei `mysqld_error.h`. Außerdem werden die Fehler in Anhang B, Fehlercodes und -meldungen, aufgeführt.

Beachten Sie, dass manche Funktionen, wie etwa `mysql_fetch_row()`, keine `mysql_errno()` setzen, wenn sie Erfolg haben.

Als Faustregel gilt: Alle Funktionen, die vom Server Informationen abfragen müssen, setzen `mysql_errno()` zurück, wenn sie Erfolg hatten.

Rückgabewerte

Ein Fehlercodewert für den letzten `mysql_`xxx`()`-Aufruf, wenn dieser gescheitert ist. Null bedeutet, dass kein Fehler auftrat.

Fehler

Keine.

#### 24.2.3.15. `mysql_error()`

`const char *mysql_error(MYSQL *mysql)`

Beschreibung

Für die durch `mysql` angegebene Verbindung liefert `mysql_error()` einen auf null endenden String mit der Fehlermeldung für die zuletzt aufgerufene API-Funktion, die gescheitert ist. Wenn keine Funktion gescheitert ist, kann der Rückgabewert von `mysql_error()` auch der vorherige Fehler oder ein leerer String sein, der anzeigt, dass kein Fehler auftrat.

Als Faustregel gilt: Alle Funktionen, die vom Server Informationen abfragen müssen, setzen `mysql_errno()` zurück, wenn sie Erfolg hatten.

Für Funktionen, die `mysql_errno()` zurücksetzen, sind die beiden folgenden Tests äquivalent:

    if(mysql_errno(&mysql))
    {
        // Ein Fehler ist aufgetreten
    }

    if(mysql_error(&mysql)[0] != '\0')
    {
      // Ein Fehler ist aufgetreten
    }

Sie können die Sprache für die Fehlermeldungen des Clients ändern, indem Sie die MySQL-Clientbibliothek neu kompilieren. Zurzeit haben Sie die Auswahl zwischen Fehlermeldungen in mehreren verschiedenen Sprachen. Siehe Abschnitt 5.11.2, „Nicht englische Fehlermeldungen“.

Rückgabewerte

Ein auf null endender Zeichen-String, der den Fehler beschreibt. Ein leerer String, wenn kein Fehler auftrat.

Fehler

Keine.

#### 24.2.3.16. `mysql_escape_string()`

Bitte verwenden Sie stattdessen `mysql_real_escape_string()`!

Diese Funktion gleicht `mysql_real_escape_string()`, mit dem Unterschied, dass `mysql_real_escape_string()` einen Verbindungs-Handler als erstes Argument entgegennimmt und den String entsprechend dem aktuellen Zeichensatz mit Escape-Zeichen versieht. `mysql_escape_string()` nimmt kein Verbindungsargument an und berücksichtigt auch nicht den aktuellen Zeichensatz.

#### 24.2.3.17. `mysql_fetch_field()`

`MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)`

Beschreibung

Liefert die Definition einer Spalte einer Ergebnismenge in Form einer `MYSQL_FIELD`-Struktur. Um Informationen über alle Spalten der Ergebnismenge zu erhalten, rufen Sie diese Funktion wiederholt auf. `mysql_fetch_field()` liefert `NULL`, wenn keine weiteren Felder mehr übrig sind.

Mit jeder neuen `SELECT`-Anfrage wird `mysql_fetch_field()` so zurückgesetzt, dass sie wieder Informationen über das erste Feld liefert. Auch `mysql_field_seek()` nimmt Einfluss darauf, welches Feld `mysql_fetch_field()` zurückgibt.

Wenn Sie mit `mysql_query()` ein `SELECT` auf einer Tabelle ausgeführt haben, ohne jedoch `mysql_store_result()` zu benutzen, dann liefert MySQL, wenn Sie mit `mysql_fetch_field()` die Länge eines `BLOB`-Felds erfragen, die Standardlänge eines Blob-Werts (8 Kbyte). (Die Größe von 8 Kbyte wird gewählt, weil MySQL die maximale Länge für den `BLOB` nicht kennt. Irgendwann soll dies einmal konfigurierbar gemacht werden.) Wenn Sie die Ergebnismenge abgeholt haben, enthält `field->max_length` die Länge des längsten Werts dieser Spalte für diese konkrete Anfrage.

Rückgabewerte

Die `MYSQL_FIELD`-Struktur der aktuellen Spalte. `NULL`, wenn keine Spalten mehr übrig sind.

Fehler

Keine.

Beispiel

    MYSQL_FIELD *field;

    while((field = mysql_fetch_field(result)))
    {
        printf("field name %s\n", field->name);
    }

#### 24.2.3.18. `mysql_fetch_field_direct()`

`MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)`

Beschreibung

Wenn man ihr die Feldnummer `fieldnr` einer Spalte aus einer Ergebnismenge übergibt, liefert die Funktion die Felddefinition dieser Spalte als `MYSQL_FIELD`-Struktur. Mit dieser Funktion können Sie die Definition einer beliebigen Spalte abfragen. Der Wert von `fieldnr` sollte zwischen 0 und `mysql_num_fields(result)-1` liegen.

Rückgabewerte

Die `MYSQL_FIELD`-Struktur für die angegebene Spalte.

Fehler

Keine.

Beispiel

    unsigned int num_fields;
    unsigned int i;
    MYSQL_FIELD *field;

    num_fields = mysql_num_fields(result);
    for(i = 0; i < num_fields; i++)
    {
        field = mysql_fetch_field_direct(result, i);
        printf("Field %u is %s\n", i, field->name);
    }

#### 24.2.3.19. `mysql_fetch_fields()`

`MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)`

Beschreibung

Gibt ein Array mit allen `MYSQL_FIELD`-Strukturen für eine Ergebnismenge zurück. Jede Struktur liefert die Felddefinition für eine Spalte der Ergebnismenge.

Rückgabewerte

Ein Array von `MYSQL_FIELD`-Strukturen für alle Spalten einer Ergebnismenge.

Fehler

Keine.

Beispiel

    unsigned int num_fields;
    unsigned int i;
    MYSQL_FIELD *fields;

    num_fields = mysql_num_fields(result);
    fields = mysql_fetch_fields(result);
    for(i = 0; i < num_fields; i++)
    {
       printf("Field %u is %s\n", i, fields[i].name);
    }

#### 24.2.3.20. `mysql_fetch_lengths()`

`unsigned long *mysql_fetch_lengths(MYSQL_RES *result)`

Beschreibung

Gibt die Länge der Spalten der aktuellen Zeile einer Ergebnismenge zurück. Wenn Sie planen, Feldwerte zu kopieren, sind diese Längenangaben auch für die Optimierung hilfreich, da Sie sich dadurch den Aufruf von `strlen()` ersparen können. Wenn die Ergebnismenge Binärdaten enthält, müssen Sie sogar diese Funktion zur Ermittlung der Datenlänge einsetzen, da `strlen()` für Felder mit Nullwerten verkehrte Ergebnisse liefert.

Die Länge von leeren Spalten und Spalten mit `NULL`-Werten ist null. Unter der Beschreibung von `mysql_fetch_row()` erfahren Sie, wie Sie diese beiden Fälle unterscheiden können.

Rückgabewerte

Ein Array von vorzeichenlosen Long-Integers, das die Größen der Spalten angibt (ausschließlich eventueller Nullzeichen am Ende). Ist `NULL`, wenn ein Fehler auftrat.

Fehler

`mysql_fetch_lengths()` ist nur für die aktuelle Zeile der Ergebnismenge gültig. Diese Funktion liefert `NULL`, wenn Sie sie vor `mysql_fetch_row()` oder nach dem Abruf aller Ergebniszeilen aufrufen.

Beispiel

    MYSQL_ROW row;
    unsigned long *lengths;
    unsigned int num_fields;
    unsigned int i;

    row = mysql_fetch_row(result);
    if (row)
    {
        num_fields = mysql_num_fields(result);
        lengths = mysql_fetch_lengths(result);
        for(i = 0; i < num_fields; i++)
        {
             printf("Column %u is %lu bytes in length.\n", i, lengths[i]);
        }
    }

#### 24.2.3.21. `mysql_fetch_row()`

`MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)`

Beschreibung

Ruft die nächste Zeile einer Ergebnismenge ab. Nach `mysql_store_result()` aufgerufen, liefert `mysql_fetch_row()` den Wert `NULL`, wenn keine weiteren Zeilen mehr abzuholen sind. Nach `mysql_use_result()` aufgerufen, liefert `mysql_fetch_row()` den Wert `NULL`, wenn keine Zeilen mehr vorliegen oder wenn ein Fehler auftrat.

`mysql_num_fields(result)` gibt die Anzahl der Werte in einer Zeile an. Wenn `row` den Rückgabewert eines `mysql_fetch_row()`-Aufrufs speichert, können Sie mit `row[0]` bis `row[mysql_num_fields(result)-1]` die Zeiger auf die Werte dieser Zeile ansprechen. `NULL`-Werte in der Zeile werden durch `NULL`-Zeiger angezeigt.

Die Längen der Feldwerte der Zeile können Sie sich mit `mysql_fetch_lengths()` beschaffen. Leere Felder und Felder mit `NULL` haben beide die Länge null. Sie können sie unterscheiden, indem Sie sich den Zeiger auf den Feldwert anschauen: Ist er `NULL`, speichert das Feld den Wert `NULL`; andernfalls ist es leer.

Rückgabewerte

Eine `MYSQL_ROW`-Struktur für die nächste Zeile oder `NULL`, wenn keine weiteren Zeilen mehr vorliegen oder ein Fehler aufgetreten ist.

Fehler

Beachten Sie, dass der Fehler zwischen zwei Aufrufen von `mysql_fetch_row()` nicht zurückgesetzt wird.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

Beispiel

    MYSQL_ROW row;
    unsigned int num_fields;
    unsigned int i;

    num_fields = mysql_num_fields(result);
    while ((row = mysql_fetch_row(result)))
    {
       unsigned long *lengths;
       lengths = mysql_fetch_lengths(result);
       for(i = 0; i < num_fields; i++)
       {
           printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL");
       }
       printf("\n");
    }

#### 24.2.3.22. `mysql_field_count()`

`unsigned int mysql_field_count(MYSQL *mysql)`

Beschreibung

Liefert die Anzahl der Spalten für die jüngste Anfrage auf dieser Verbindung.

Normalerweise benutzen Sie diese Funktion, wenn `mysql_store_result()` den Wert `NULL` zurückgegeben hat (und Sie deshalb keinen Zeiger auf die Ergebnismenge haben). In diesem Fall können Sie mit `mysql_field_count()` feststellen, ob `mysql_store_result()` ein nichtleeres Ergebnis hätte produzieren müssen. So kann das Clientprogramm die richtigen Maßnahmen ergreifen, ohne zu wissen, ob die Anfrage eine `SELECT`- (oder `SELECT`-ähnliche) Anweisung war. Wie dies funktioniert, zeigt das folgende Beispiel.

Siehe Abschnitt 24.2.13.1, „Warum gibt `mysql_store_result()` manchmal `NULL` zurück, nachdem `mysql_query()` Erfolg zurückgegeben hat?“.

Rückgabewerte

Ein vorzeichenloser Integer, der die Anzahl der Spalten einer Ergebnismenge angibt.

Fehler

Keine.

Beispiel

    MYSQL_RES *result;
    unsigned int num_fields;
    unsigned int num_rows;

    if (mysql_query(&mysql,query_string))
    {
        // Fehler
    }
    else // Anfrage erfolgreich, Rückgabedaten können verarbeitet werden
    {
        result = mysql_store_result(&mysql);
        if (result)  // Es sind Zeilen vorhanden
        {
            num_fields = mysql_num_fields(result);
            // Hole Zeilen ab und rufe dann mysql_free_result(result) auf
        }
        else  // mysql_store_result() gab nichts zurück. Hätte es sollen?
        {
            if(mysql_field_count(&mysql) == 0)
            {
                // Anfrage liefert keine Daten
                // (Es war kein SELECT)
                num_rows = mysql_affected_rows(&mysql);
            }
            else // mysql_store_result() hätte Daten zurückgeben müssen
            {
                fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
            }
        }
    }

Eine Alternative wäre es, den Aufruf von `mysql_field_count(&mysql)` durch `mysql_errno(&mysql)` zu ersetzen. In diesem Fall schauen Sie direkt in `mysql_store_result()` nach einem Fehler, anstatt aus dem Wert von `mysql_field_count()` zu erschließen, ob die Anweisung ein `SELECT` war.

#### 24.2.3.23. `mysql_field_seek()`

`MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)`

Beschreibung

Setzt den Feld-Cursor auf den gegebenen Offset. Der nächste `mysql_fetch_field()`-Aufruf fragt die Felddefinition der mit diesem Offset verbundenen Spalte ab.

Um den Zeilenanfang zu suchen, übergeben Sie den `offset`-Wert null.

Rückgabewerte

Der vorherige Wert des Feld-Cursors.

Fehler

Keine.

#### 24.2.3.24. `mysql_field_tell()`

`MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)`

Beschreibung

Liefert die Position des Feld-Cursors, der für den letzten `mysql_fetch_field()`-Aufruf verwendet wurde. Dieser Wert kann als Argument für `mysql_field_seek()` dienen.

Rückgabewerte

Der aktuelle Offset des Feld-Cursors.

Fehler

Keine.

#### 24.2.3.25. `mysql_free_result()`

`void mysql_free_result(MYSQL_RES *result)`

Beschreibung

Gibt den Speicher frei, der einer Ergebnismenge durch `mysql_store_result()`, `mysql_use_result()`, `mysql_list_dbs()` und so weiter zugewiesen wurde. Wenn Sie mit einer Ergebnismenge fertig sind, müssen Sie ihren Speicher mit `mysql_free_result()` wieder freigeben.

Versuchen Sie nicht mehr, auf eine Ergebnismenge zuzugreifen, nachdem Sie sie freigegeben haben.

Rückgabewerte

Keine.

Fehler

Keine.

#### 24.2.3.26. `mysql_get_character_set_info()`

`void mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *cs)`

Beschreibung

Diese Funktion liefert Informationen über den Standardzeichensatz des Clients. Dieser kann mit der Funktion `mysql_set_character_set()` geändert werden.

Diese Funktion kam in MySQL 5.0.10 hinzu.

Beispiel

    if (!mysql_set_character_set(&mysql, "utf8"))
    {
        MY_CHARSET_INFO cs;
        mysql_get_character_set_info(&mysql, &cs);
        printf("character set information:\n");
        printf("character set name: %s\n", cs.name);
        printf("collation name: %s\n", cs.csname);
        printf("comment: %s\n", cs.comment);
        printf("directory: %s\n", cs.dir);
        printf("multi byte character min. length: %d\n", cs.mbminlen);
        printf("multi byte character max. length: %d\n", cs.mbmaxlen);
    }

#### 24.2.3.27. `mysql_get_client_info()`

`char *mysql_get_client_info(void)`

Beschreibung

Liefert einen String, der die Version der Clientbibliothek darstellt.

Rückgabewerte

Ein Zeichen-String, der die Version der MySQL-Clientbibliothek darstellt.

Fehler

Keine.

#### 24.2.3.28. `mysql_get_client_version()`

`unsigned long mysql_get_client_version(void)`

Beschreibung

Liefert einen Integer, der die Version der Clientbibliothek darstellt. Der Wert hat das Format `XYYZZ`, wobei `X` die Hauptversion, `YY` der Release-Level und `ZZ` die Versionsnummer innerhalb des Releases ist. So bedeutet beispielsweise der Wert `40102` die Clientbibliotheksversion `4.1.2`.

Rückgabewerte

Ein Integer, der die Version der MySQL-Clientbibliothek angibt.

Fehler

Keine.

#### 24.2.3.29. `mysql_get_host_info()`

`char *mysql_get_host_info(MYSQL *mysql)`

Beschreibung

Liefert einen String, der den benutzten Verbindungstyp einschließlich des Hostnamens des Servers beschreibt.

Rückgabewerte

Ein Zeichen-String, der den Hostnamen des Servers und den Verbindungstyp darstellt.

Fehler

Keine.

#### 24.2.3.30. `mysql_get_proto_info()`

`unsigned int mysql_get_proto_info(MYSQL *mysql)`

Beschreibung

Liefert die Protokollversion der aktuellen Verbindung.

Rückgabewerte

Ein vorzeichenloser Integer, der die Protokollversion der aktuellen Verbindung darstellt.

Fehler

Keine.

#### 24.2.3.31. `mysql_get_server_info()`

`char *mysql_get_server_info(MYSQL *mysql)`

Beschreibung

Liefert einen String, der die Versionsnummer des Servers darstellt.

Rückgabewerte

Ein Zeichen-String, der die Versionsnummer des Servers darstellt.

Fehler

Keine.

#### 24.2.3.32. `mysql_get_server_version()`

`unsigned long mysql_get_server_version(MYSQL *mysql)`

Beschreibung

Liefert die Versionsnummer des Servers als Integer.

Rückgabewerte

Eine Zahl, welche die MySQL Server-Version in folgendem Format darstellt:

    major_version*10000 + minor_version *100 + sub_version

So wird beispielsweise 5.1.5 als 50105 zurückgegeben.

Diese Funktion ist nützlich, um in Clientprogrammen schnell herauszufinden, ob eine versionsspezifische Serverfähigkeit geboten wird.

Fehler

Keine.

#### 24.2.3.33. `mysql_hex_string()`

`unsigned long mysql_hex_string(char *to, const char *from, unsigned long length)`

Beschreibung

Diese Funktion dient der Erstellung eines gültigen SQL-Strings, den Sie in einer SQL-Anweisung benutzen können. Siehe Abschnitt 9.1.1, „Strings“.

Der String in `from` ist im Hexadezimalformat verschlüsselt, wobei jedes Zeichen als zwei Hexadezimalziffern kodiert ist. Das Ergebnis wird in `to` eingesetzt und ein Nullbyte als Abschlusszeichen angehängt.

Der String, auf den `from` verweist, muss `length` Bytes lang sein. Den `to`-Puffer müssen Sie mindestens mit einer Länge von `length*2+1` Bytes zuweisen. Wenn `mysql_hex_string()` zurückkehrt, ist der Inhalt von `to` ein auf null endender String. Der Rückgabewert ist die Länge des kodierten Strings ohne das abschließende Nullzeichen.

Der Rückgabewert kann in eine SQL-Anweisung in einem der Formate `0x`value`` oder `X'`value`'` eingesetzt werden. Allerdings enthält der Rückgabewert nicht das `0x` oder `X'...'`. Der Aufrufer muss dieses Element selbst beisteuern, je nachdem, für welches er sich entscheidet.

Beispiel

    char query[1000],*end;

    end = strmov(query,"INSERT INTO test_table values(");
    end = strmov(end,"0x");
    end += mysql_hex_string(end,"What's this",11);
    end = strmov(end,",0x");
    end += mysql_hex_string(end,"binary data: \0\r\n",16);
    *end++ = ')';

    if (mysql_real_query(&mysql,query,(unsigned int) (end - query)))
    {
       fprintf(stderr, "Failed to insert row, Error: %s\n",
               mysql_error(&mysql));
    }

Die im Beispiel verwendete Funktion `strmov()` stammt aus der `mysqlclient`-Bibliothek und funktioniert wie `strcpy()`, liefert jedoch einen Zeiger auf die abschließende Null des ersten Parameters.

Rückgabewerte

Die Länge des in `to` eingesetzten Werts ohne die abschließende Null.

Fehler

Keine.

#### 24.2.3.34. `mysql_info()`

`char *mysql_info(MYSQL *mysql)`

Beschreibung

Holt einen String mit Informationen über die zuletzt ausgeführte Anfrage ab, aber nur für die hier aufgeführten Anweisungen. Für andere Anweisungen liefert `mysql_info()` die Funktion `NULL`. Das Format des Strings hängt von der Art der Anfrage ab, wie hier beschrieben. Die Zahlen dienen nur der Veranschaulichung; der String enthält Werte, die für die Anfrage passend sind.

- `INSERT INTO ... SELECT ...`

  String-Format: `Records: 100 Duplicates: 0 Warnings: 0`

- `INSERT INTO ... VALUES (...),(...),(...)...`

  String-Format: `Records: 3 Duplicates: 0 Warnings: 0`

- `LOAD DATA INFILE ...`

  String-Format: `Records: 1 Deleted: 0 Skipped: 0 Warnings: 0`

- `ALTER TABLE`

  String-Format: `Records: 3 Duplicates: 0 Warnings: 0`

- `UPDATE`

  String-Format: `Rows matched: 40 Changed: 40 Warnings: 0`

Beachten Sie, dass `mysql_info()` bei `INSERT ... VALUES` lediglich für die mehrzeilige Form der Anweisung (also dann, wenn mehrere Wertelisten angegeben werden) einen von `NULL` verschiedenen Wert liefert.

Rückgabewerte

Ein Zeichen-String mit Zusatzinformationen über die zuletzt ausgeführte Anfrage. `NULL`, wenn keine Informationen über die Anfrage zur Verfügung stehen.

Fehler

Keine.

#### 24.2.3.35. `mysql_init()`

`MYSQL *mysql_init(MYSQL *mysql)`

Beschreibung

Reserviert oder initialisiert ein geeignetes `MYSQL`-Objekt für `mysql_real_connect()`. Wenn `mysql` ein `NULL`-Zeiger ist, reserviert, initialisiert und liefert die Funktion ein neues Objekt. Andernfalls wird das Objekt initialisiert und seine Adresse zurückgegeben. Wenn `mysql_init()` ein neues Objekt zuweist, wird dieses wieder freigegeben, wenn `mysql_close()` zum Schließen der Verbindung aufgerufen wird.

Rückgabewerte

Ein initialisierter `MYSQL*`-Handle. `NULL`, wenn nicht genügend Speicher zur Zuweisung eines neuen Objekts verfügbar war.

Fehler

Wenn der Speicher nicht ausreichte, wird `NULL` zurückgegeben.

#### 24.2.3.36. `mysql_insert_id()`

`my_ulonglong mysql_insert_id(MYSQL *mysql)`

Beschreibung

Liefert den von der vorherigen `INSERT`- oder `UPDATE`-Anweisung für eine `AUTO_INCREMENT`-Spalte generierten Wert. Verwenden Sie diese Funktion, wenn Sie eine `INSERT`-Anweisung auf einer Tabelle mit einem `AUTO_INCREMENT`-Feld ausgeführt haben.

Genauer gesagt: `mysql_insert_id()` wird unter folgenden Bedingungen aktualisiert:

- `INSERT`-Anweisungen, die einen Wert in einer `AUTO_INCREMENT`-Spalte speichern, und zwar unabhängig davon, ob der Wert automatisch durch Speichern der Spezialwerte `NULL` oder `0` in der Spalte generiert oder ob ein expliziter, nichtspezieller Wert gespeichert wurde.

- Bei einer mehrzeiligen `INSERT`-Anweisung liefert `mysql_insert_id()` den ersten automatisch generierten `AUTO_INCREMENT`-Wert. Wurde kein solcher Wert generiert, liefert die Funktion den letzten explizit in die `AUTO_INCREMENT`-Spalte eingefügten Wert.

- `INSERT`-Anweisungen, die einen `AUTO_INCREMENT`-Wert generieren, indem sie `LAST_INSERT_ID(`expr`)` in eine Spalte einfügen.

- `INSERT`-Anweisungen, die einen `AUTO_INCREMENT`-Wert generieren, indem sie eine Spalte auf `LAST_INSERT_ID(`expr`)` setzen.

- Der Wert von `mysql_insert_id()` wird nicht von Anweisungen wie `SELECT` beeinflusst, die eine Ergebnismenge zurückgeben.

- Wenn die obige Anweisung einen Fehler zurückgab, ist der Wert von `mysql_insert_id()` undefiniert.

Beachten Sie, dass `mysql_insert_id()` den Wert `0` liefert, wenn die Anweisung keinen `AUTO_INCREMENT`-Wert verwendet. Wenn Sie den Wert zur späteren Benutzung speichern möchten, müssen Sie unmittelbar nach der Anweisung, die den Wert generiert, `mysql_insert_id()` aufrufen.

Der Wert von `mysql_insert_id()` wird nur von Anweisungen beeinflusst, die innerhalb der aktuellen Clientverbindung gegeben werden, aber nicht durch Anweisungen von anderen Clients.

Siehe Abschnitt 12.10.3, „Informationsfunktionen“.

Bitte beachten Sie auch, dass der Wert der SQL-Funktion `LAST_INSERT_ID()` immer den zuletzt generierten `AUTO_INCREMENT`-Wert enthält. Dieser wird zwischen zwei Anweisungen nicht zurückgesetzt, da der Wert dieser Funktion im Server gespeichert ist. Ein weiterer Unterschied ist der, dass `LAST_INSERT_ID()` nicht aktualisiert wird, wenn Sie eine `AUTO_INCREMENT`-Spalte auf einen bestimmten Wert setzen, der kein Spezialwert ist.

Der Grund für den Unterschied zwischen `LAST_INSERT_ID()` und `mysql_insert_id()` besteht darin, dass `LAST_INSERT_ID()` in Skripten einfach zu benutzen sein soll, während `mysql_insert_id()` versucht, etwas genauere Informationen über die Vorgänge in der `AUTO_INCREMENT`-Spalte zu liefern.

Rückgabewerte

Siehe oben.

Fehler

Keine.

#### 24.2.3.37. `mysql_kill()`

`int mysql_kill(MYSQL *mysql, unsigned long pid)`

Beschreibung

Lässt den Server den Thread `pid` anhalten.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.38. `mysql_library_end()`

`void mysql_library_end(void)`

Beschreibung

Dies ist ein Synonym für die `mysql_server_end()`-Funktion.

Informationen zur Verwendung finden Sie unter Abschnitt 24.2.2, „C-API: Funktionsüberblick“.

#### 24.2.3.39. `mysql_library_init()`

`int mysql_library_init(int argc, char **argv, char **groups)`

Beschreibung

Dies ist ein Synonym für die `mysql_server_init()`-Funktion. Siehe Abschnitt 24.2.12.1, „`mysql_server_init()`“.

Informationen zur Verwendung finden Sie unter Abschnitt 24.2.2, „C-API: Funktionsüberblick“.

#### 24.2.3.40. `mysql_list_dbs()`

`MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)`

Beschreibung

Liefert eine Ergebnismenge mit Namen von Datenbanken auf dem Server, die mit dem einfachen regulären Ausdruck im Parameter `wild` übereinstimmen. `wild` kann die Wildcard-Zeichen ‘`%`’ oder ‘`_`’ enthalten oder aber ein `NULL`-Zeiger sein, der auf alle Datenbanken passt. Ein Aufruf von `mysql_list_dbs()` ist dasselbe wie die Anfrage `SHOW databases [LIKE wild]`.

Sie müssen die Ergebnismenge mit `mysql_free_result()` wieder freigeben.

Rückgabewerte

Bei einem Erfolg eine `MYSQL_RES`-Ergebnismenge und bei einem Fehler der Wert `NULL`.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.41. `mysql_list_fields()`

`MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)`

Beschreibung

Liefert eine Ergebnismenge mit Namen von Feldern aus der gegebenen Tabelle, die mit dem einfachen regulären Ausdruck im Parameter `wild` übereinstimmen. `wild` kann die Wildcard-Zeichen ‘`%`’ oder ‘`_`’ enthalten oder aber ein `NULL`-Zeiger sein, der auf alle Felder passt. Ein Aufruf von `mysql_list_fields()` ist dasselbe wie die Anfrage `SHOW COLUMNS FROM `tbl_name` [LIKE `wild`]`.

Wir empfehlen, `SHOW COLUMNS FROM `tbl_name`` anstelle von `mysql_list_fields()` zu benutzen.

Sie müssen die Ergebnismenge mit `mysql_free_result()` freigeben.

Rückgabewerte

Bei Erfolg eine `MYSQL_RES`-Ergebnismenge und bei einem Fehler der Wert `NULL`.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.42. `mysql_list_processes()`

`MYSQL_RES *mysql_list_processes(MYSQL *mysql)`

Beschreibung

Gibt eine Ergebnismenge mit einer Beschreibung der laufenden Server-Threads zurück. Dieselben Informationen erhalten Sie auch mit mysqladmin processlist oder der Anfrage `SHOW PROCESSLIST`.

Sie müssen die Ergebnismenge mit `mysql_free_result()` freigeben.

Rückgabewerte

Bei Erfolg eine `MYSQL_RES`-Ergebnismenge und bei einem Fehler der Wert `NULL`.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.43. `mysql_list_tables()`

`MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)`

Beschreibung

Liefert eine Ergebnismenge mit Namen von Tabellen aus der aktuellen Datenbank, die mit dem einfachen regulären Ausdruck im Parameter `wild` übereinstimmen. `wild` kann die Wildcard-Zeichen ‘`%`’ oder ‘`_`’ enthalten oder aber ein `NULL`-Zeiger sein, der auf alle Tabellen passt. Ein Aufruf von `mysql_list_tables()` ist dasselbe wie die Anfrage `SHOW tables [LIKE `wild`]`.

Sie müssen die Ergebnismenge mit `mysql_free_result()` freigeben.

Rückgabewerte

Bei Erfolg eine `MYSQL_RES`-Ergebnismenge und bei einem Fehler der Wert `NULL`.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.44. `mysql_more_results()`

`my_bool mysql_more_results(MYSQL *mysql)`

Beschreibung

Gibt TRUE zurück, wenn noch weitere Ergebnisse der aktuellen Anfrage vorliegen und die Anwendung `mysql_next_result()` aufrufen muss, um diese Ergebnisse abzuholen.

Rückgabewerte

`TRUE` (1), wenn noch weitere Ergebnisse existieren. `FALSE` (0), wenn keine Ergebnisse mehr vorhanden sind.

In den meisten Fällen können Sie stattdessen mit `mysql_next_result()` testen, ob noch Ergebnisse übrig sind, und den Abruf der Daten initiieren, wenn dies der Fall ist.

Siehe Abschnitt 24.2.9, „C-API: Behandlung der Ausführung mehrerer Anweisungen“, und Abschnitt 24.2.3.45, „`mysql_next_result()`“.

Fehler

Keine.

#### 24.2.3.45. `mysql_next_result()`

`int mysql_next_result(MYSQL *mysql)`

Beschreibung

Wenn noch Anfrageergebnisse vorliegen, liest `mysql_next_result()` die nächsten Ergebnisse und gibt den Status an die Anwendung zurück.

Sie müssen für die vorherige Anfrage `mysql_free_result()` aufrufen, falls diese eine Ergebnismenge zurückgegeben hat.

Nach einem Aufruf von `mysql_next_result()` hat die Verbindung denselben Status, als hätten Sie `mysql_real_query()` oder `mysql_query()` für die nächste Anfrage aufgerufen. Das bedeutet, dass Sie `mysql_store_result()`, `mysql_warning_count()`, `mysql_affected_rows()` und so weiter aufrufen können.

Wenn `mysql_next_result()` einen Fehler zurückgibt, werden andere Anweisungen ausgeführt und es liegen keine Ergebnisse mehr zum Abruf bereit.

Siehe Abschnitt 24.2.9, „C-API: Behandlung der Ausführung mehrerer Anweisungen“.

Rückgabewerte

Rückgabewert | Beschreibung
0 | Erfolg, und es gibt noch mehr Ergebnisse.
-1 | Erfolg, und es gibt keine Ergebnisse mehr.
>0 | Ein Fehler ist aufgetreten

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt, beispielsweise wenn Sie es versäumt haben, `mysql_use_result()` für die vorherige Ergebnismenge aufzurufen.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.46. `mysql_num_fields()`

`unsigned int mysql_num_fields(MYSQL_RES *result)`

Um stattdessen ein `MYSQL*`-Argument zu übergeben, sagen Sie `unsigned int mysql_field_count(MYSQL *mysql)`.

Beschreibung

Liefert die Anzahl der Spalten einer Ergebnismenge.

Beachten Sie, dass Sie die Anzahl der Spalten entweder aus einem Zeiger auf eine Ergebnismenge oder aus einem Verbindungs-Handle erfahren können. Den Verbindungs-Handle verwenden Sie, wenn `mysql_store_result()` oder `mysql_use_result()` den Wert `NULL` zurückgegeben hat (sodass kein Zeiger auf die Ergebnismenge zur Verfügung steht). In diesem Fall können Sie mit `mysql_field_count()` ermitteln, ob `mysql_store_result()` eigentlich ein nichtleeres Ergebnis hätte liefern sollen. So kann das Clientprogramm geeignete Maßnahmen ergreifen, ohne zu wissen, ob die Anfrage eine `SELECT`- (oder `SELECT`-ähnliche) Anweisung war. Das Beispiel zeigt, wie man dies macht.

Siehe Abschnitt 24.2.13.1, „Warum gibt `mysql_store_result()` manchmal `NULL` zurück, nachdem `mysql_query()` Erfolg zurückgegeben hat?“.

Rückgabewerte

Ein vorzeichenloser Integer, der die Anzahl der Spalten einer Ergebnismenge angibt.

Fehler

Keine.

Beispiel

    MYSQL_RES *result;
    unsigned int num_fields;
    unsigned int num_rows;

    if (mysql_query(&mysql,query_string))
    {
        // Fehler
    }
    else // Anfrage erfolgreich, Rückgabedaten werden verarbeitet
    {
        result = mysql_store_result(&mysql);
        if (result)  // Es liegen Zeilen vor
        {
            num_fields = mysql_num_fields(result);
            // Zeilen abrufen und dann mysql_free_result(result) aufrufen
        }
        else  // mysql_store_result() gab nichts zurück, hätte es sollen?
        {
            if (mysql_errno(&mysql))
            {
               fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
            }
            else if (mysql_field_count(&mysql) == 0)
            {
                // Anfrage liefert keine Daten
                // (war kein SELECT)
                num_rows = mysql_affected_rows(&mysql);
            }
        }
    }

Wenn Sie wissen, dass Ihre Anfrage eine Ergebnismenge hätte zurückgeben müssen, können Sie alternativ den Aufruf von `mysql_errno(&mysql)` durch eine Prüfung ersetzen, die feststellt, ob `mysql_field_count(&mysql)` gleich 0 ist. Das geschieht nur, wenn etwas schief gegangen ist.

#### 24.2.3.47. `mysql_num_rows()`

`my_ulonglong mysql_num_rows(MYSQL_RES *result)`

Beschreibung

Liefert die Anzahl der Zeilen in der Ergebnismenge.

Die Verwendung von `mysql_num_rows()` hängt davon ab, ob Sie die Ergebnismenge mit `mysql_store_result()` oder `mysql_use_result()` zurückgeben. Wenn Sie `mysql_store_result()` benutzen, kann `mysql_num_rows()` direkt aufgerufen werden, aber wenn Sie `mysql_use_result()` benutzen, gibt `mysql_num_rows()` erst dann den richtigen Wert zurück, wenn alle Zeilen der Ergebnismenge abgeholt worden sind.

Rückgabewerte

Die Anzahl der Zeilen in der Ergebnismenge.

Fehler

Keine.

#### 24.2.3.48. `mysql_options()`

`int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)`

Beschreibung

Kann verwendet werden, um zusätzliche Verbindungsoptionen einzustellen und das Verhalten einer Verbindung zu beeinflussen. Diese Funktion kann auch mehrmals aufgerufen werden, um mehrere Optionen zu setzen.

`mysql_options()` sollte nach `mysql_init()` und vor `mysql_connect()` oder `mysql_real_connect()` aufgerufen werden.

Das `option`-Argument ist die einzustellende Option und das `arg`-Argument ist ihr Wert. Ist die Option ein Integer, so sollte `arg` auf den Wert dieses Integers verweisen.

Mögliche Optionswerte:

Option | Argumenttyp | Funktion
`MYSQL_INIT_COMMAND` | `char *` | Befehl, der bei Verbindung mit dem MySQL Server auszuführen ist. Wird bei Neuverbindungen automatisch erneut ausgeführt.
`MYSQL_OPT_COMPRESS` | Nicht verwendet | Komprimiertes Client/Server-Protokoll soll verwendet werden.
`MYSQL_OPT_CONNECT_TIMEOUT` | `unsigned int *` | Verbindungs-Timeout in Sekunden.

`MYSQL_OPT_GUESS_CONNECTION`

Nicht verwendet

Für eine mit `libmysqld` verlinkte Anwendung, kann die Bibliothek hiermit erschließen, ob ein Embedded Server oder ein Remote Server verwendet wird. „Erschließen“ bedeutet: Wenn ein Hostname angegeben ist, der nicht auf `localhost` lautet, wird ein Remote-Server benutzt. Dieses voreingestellte Verhalten kann mit `MYSQL_OPT_USE_EMBEDDED_CONNECTION` und `MYSQL_OPT_USE_REMOTE_CONNECTION` außer Kraft gesetzt werden. Die Option wird von Anwendungen, die mit `libmysqlclient` verlinkt sind, ignoriert.

`MYSQL_OPT_LOCAL_INFILE` | Optionaler Zeiger auf uint | Wenn kein Zeiger angegeben ist oder wenn der Zeiger auf ein `unsigned int != 0` verweist, wird der Befehl `LOAD LOCAL INFILE` eingeschaltet.
`MYSQL_OPT_NAMED_PIPE` | Nicht verwendet | Zur Verbindung mit einem MySQL Server auf NT werden Named Pipes benutzt.
`MYSQL_OPT_PROTOCOL` | `unsigned int *` | Der zu verwendende Protokolltyp. Er sollte einer der Enumerationswerte von `mysql_protocol_type` sein, die in `mysql.h` definiert sind.
`MYSQL_OPT_READ_TIMEOUT` | `unsigned int *` | Timeout-Leseoperationen auf dem Server (funktioniert zurzeit nur für Windows und mit TCP/IP-Verbindungen).
`MYSQL_OPT_RECONNECT` | `my_bool *` | Aktiviert/deaktiviert die automatische Neuverbindung mit dem Server, wenn die Verbindung abgebrochen war. Die Neuverbindung ist seit MySQL 5.0.3 standardmäßig ausgeschaltet. Diese Option ist neu in 5.0.13 und bietet die Möglichkeit, das Verhalten in Bezug auf Neuverbindungen explizit vorzugeben.

`MYSQL_OPT_SET_CLIENT_IP`

`char *`

Für eine Anwendung, die mit `libmysqld` verlinkt ist (wobei `libmysqld` mit Authentifizierungsunterstützung kompiliert wurde), bedeutet dies, dass bei der Authentifizierung davon ausgegangen wird, dass sich der Benutzer von der (als String) angegebenen IP-Adresse aus verbindet. Bei Anwendungen, die mit `libmysqlclient` verlinkt sind, wird diese Option ignoriert.

`MYSQL_OPT_USE_EMBEDDED_CONNECTION` | Nicht verwendet | Für eine Anwendung, die mit `libmysqld` verlinkt ist, zwingt dies zur Benutzung des Embedded Servers für die Verbindung. Bei Anwendungen, die mit `libmysqlclient` verlinkt sind, wird diese Option ignoriert.
`MYSQL_OPT_USE_REMOTE_CONNECTION` | Nicht verwendet | Für eine Anwendung, die mit `libmysqld` verlinkt ist, zwingt dies zur Benutzung eines Remote-Servers für die Verbindung. Bei Anwendungen, die mit `libmysqlclient` verlinkt sind, wird diese Option ignoriert.
`MYSQL_OPT_USE_RESULT` | Nicht verwendet | Diese Option wird nicht benutzt.
`MYSQL_OPT_WRITE_TIMEOUT` | `unsigned int *` | Timeout für Schreiboperationen auf dem Server (funktioniert zurzeit nur für Windows und mit TCP/IP-Verbindungen).
`MYSQL_READ_DEFAULT_FILE` | `char *` | Leseoptionen werden aus der angegebenen Optionsdatei statt aus `my.cnf` entnommen.
`MYSQL_READ_DEFAULT_GROUP` | `char *` | Leseoptionen werden aus der angegebenen Gruppe aus `my.cnf` oder aus der Datei, die in `MYSQL_READ_DEFAULT_FILE` angegeben wurde, entnommen.
`MYSQL_REPORT_DATA_TRUNCATION` | `my_bool *` | Aktiviert oder deaktiviert die Meldung von Fehlern wegen des Abschneidens von Daten für vorbereitete Anweisungen mit `MYSQL_BIND.error`. (Standardeinstellung: Deaktiviert.)
`MYSQL_SECURE_AUTH` | `my_bool*` | Gibt an, ob eine Verbindung mit einem Server aufgebaut wird, der nicht das Passwort-Hashing von MySQL 4.1.1 und höher unterstützt.
`MYSQL_SET_CHARSET_DIR` | `char*` | Der Pfad zu dem Verzeichnis, das die Dateien mit den Zeichensatzdefinitionen enthält.
`MYSQL_SET_CHARSET_NAME` | `char*` | Der Name des Zeichensatzes, der als Standard zu verwenden ist.
`MYSQL_SHARED_MEMORY_BASE_NAME` | `char*` | Der Name des Shared Memory-Objekts für die Serverkommunikation. Sollte dasselbe sein wie die Option `--shared-memory-base-name` für den mysqld-Server, mit dem Sie sich verbinden möchten.

Beachten Sie, dass immer die `client`-Gruppe gelesen wird, wenn Sie `MYSQL_READ_DEFAULT_FILE` oder `MYSQL_READ_DEFAULT_GROUP` benutzen.

Die angegebene Gruppe in der Optionsdatei kann folgende Optionen enthalten:

Option | Beschreibung
`connect-timeout` | Verbindungs-Timeout in Sekunden. Bei Linux wird dieser Timeout auch verwendet, wenn das System auf die erste Antwort vom Server wartet.
`compress` | Verwendung des komprimierten Client/Server-Protokolls.
`database` | Wenn im Verbindungsbefehl keine Datenbank angegeben wurde, wird diese verwendet.
`debug` | Debuggingoptionen.
`disable-local-infile` | Deaktiviert `LOAD DATA LOCAL`.
`host` | Standardhostname.
`init-command` | Befehl, der bei Verbindung mit dem MySQL Server ausgeführt wird. Wird bei Neuverbindung automatisch erneut ausgeführt.
`interactive-timeout` | Dasselbe wie `CLIENT_INTERACTIVE` mit `mysql_real_connect()`. Siehe Abschnitt 24.2.3.51, „`mysql_real_connect()`“.
`local-infile[=(0|1)]` | Wenn kein Argument oder argument != 0 vorhanden ist, wird `LOAD DATA LOCAL` aktiviert.
`max_allowed_packet` | Maximalgröße der Pakete, die der Client vom Server lesen kann.
`multi-results` | Mehrfachergebnismengen von Mehrfachanweisungen oder mehrfach gespeicherten Prozeduren sind zulässig.
`multi-statements` | Client darf mehrere Anweisungen in einem einzigen String senden (getrennt durch ‘`;`’).
`password` | Standardpasswort.
`pipe` | Zur Verbindung mit einem MySQL Server auf NT werden Named Pipes benutzt.
`protocol={TCP|SOCKET|PIPE|MEMORY}` | Das Protokoll für die Serververbindung.
`port` | Standardportnummer.
`return-found-rows` | Lässt `mysql_info()` bei einem `UPDATE` die gefundenen anstatt der aktualisierten Zeilen zurückgeben.
`shared-memory-base-name=`name`` | Shared Memory-Name für die Serververbindung (Standardwert ist "MYSQL").
`socket` | Standardsocketdatei.
`user` | Standardbenutzer.

Beachten Sie, dass `timeout` zwar durch `connect-timeout` ersetzt, aber `timeout` in MySQL 5.1.5-alpha aus Gründen der Abwärtskompatibilität immer noch unterstützt wird.

Weitere Informationen über Optionsdateien finden Sie unter Abschnitt 4.3.2, „my.cnf-Optionsdateien“.

Rückgabewerte

Bei Erfolg null und bei Verwendung einer unbekannten Option ein von null verschiedener Wert.

Beispiel

    MYSQL mysql;

    mysql_init(&mysql);
    mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);
    mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");
    if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
    {
        fprintf(stderr, "Failed to connect to database: Error: %s\n",
              mysql_error(&mysql));
    }

Dieser Code veranlasst den Client, das komprimierte Client/Server-Protokoll zu verwenden und die zusätzlichen Optionen aus dem Abschnitt `odbc` der Datei `my.cnf` zu lesen.

#### 24.2.3.49. `mysql_ping()`

`int mysql_ping(MYSQL *mysql)`

Beschreibung

Prüft, ob die Serververbindung funktioniert. Wenn die Verbindung abgebrochen ist, wird automatisch eine Neuverbindung versucht.

Mit dieser Funktion können Clients, die geraume Zeit untätig waren, prüfen, ob der Server die Verbindung geschlossen hat, und sich notfalls neu verbinden.

Rückgabewerte

Null, wenn die Serververbindung noch steht, und ein von null verschiedener Wert, wenn ein Fehler auftrat. Ein von null verschiedener Wert bedeutet nicht unbedingt, dass der MySQL Server selbst abgestürzt ist, sondern kann auch bedeuten, dass die Verbindung aus anderen Gründen abgebrochen ist, etwa wegen eines Netzwerkproblems.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.50. `mysql_query()`

`int mysql_query(MYSQL *mysql, const char *query)`

Beschreibung

Führt die SQL-Anfrage in dem auf null endenden String `query` aus. Normalerweise muss der String eine einzige SQL-Anweisung ohne abschließendes Semikolon (‘`;`’) oder `\g` enthalten. Wenn die Ausführung von Mehrfachanweisungen aktiviert wurde, kann der String auch mehrere, durch Semikola getrennte Anweisungen enthalten. Siehe Abschnitt 24.2.9, „C-API: Behandlung der Ausführung mehrerer Anweisungen“.

`mysql_query()` darf nicht für Anfragen mit Binärdaten verwendet werden. Hierfür müssen Sie stattdessen `mysql_real_query()` aufrufen. (Binärdaten können das Zeichen ‘`\0`’ enthalten, das `mysql_query()` als Ende des Anfrage-Strings interpretiert.)

Wenn Sie wissen möchten, ob die Anfrage eine Ergebnismenge liefern sollte, können Sie dies mit `mysql_field_count()` überprüfen. Siehe Abschnitt 24.2.3.22, „`mysql_field_count()`“.

Rückgabewerte

Null, wenn die Anfrage Erfolg hatte. Ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.51. `mysql_real_connect()`

`MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)`

Beschreibung

`mysql_real_connect()` versucht, eine Verbindung zu einer MySQL-Datenbank-Engine auf `host` herzustellen. `mysql_real_connect()` muss erfolgreich zum Abschluss kommen, ehe Sie irgendwelche anderen API-Funktionen ausführen können, die eine gültige `MYSQL`-Verbindungs-Handle-Struktur erfordern.

Die Parameter werden folgendermaßen angegeben:

- Der erste Parameter sollte die Adresse einer bestehenden `MYSQL`-Struktur sein. Bevor Sie `mysql_real_connect()` aufrufen können, müssen Sie die `MYSQL`-Struktur mit `mysql_init()` initialisieren. Mit dem `mysql_options()`-Aufruf können Sie viele Verbindungsoptionen ändern. Siehe Abschnitt 24.2.3.48, „`mysql_options()`“.

- Der Wert von `host` ist entweder ein Hostname oder eine IP-Adresse. Wenn `host` der Wert `NULL` oder der String `"localhost"` ist, wird eine Verbindung mit dem lokalen Host zugrunde gelegt. Wenn das Betriebssystem Sockets (Unix) oder Named Pipes (Windows) unterstützt, werden diese anstelle von TCP/IP für die Serververbindung benutzt.

- Der Parameter `user` enthält die MySQL-Kennung für die Anmeldung des Benutzers. Wenn `user` `NULL` oder der leere String `""` ist, wird der aktuelle Benutzer vorausgesetzt. Bei Unix ist dies der aktuelle Login-Name und bei Windows ODBC muss der aktuelle Benutzername explizit angegeben werden. Siehe Abschnitt 25.1.3.2, „Konfiguration einer MyODBC-DSN unter Windows“.

- Der Parameter `passwd` enthält das Passwort für den `user`. Wenn `passwd` `NULL` ist, werden nur diejenigen Einträge der `user`-Tabelle, die ein leeres Passwortfeld aufweisen, auf Übereinstimmung mit dem Benutzer überprüft. Dadurch kann der Datenbankadministrator das Berechtigungssystem von MySQL so einrichten, dass die Benutzer je nachdem, ob sie ein Passwort angegeben haben oder nicht, unterschiedliche Rechte bekommen.

  Hinweis: Versuchen Sie nicht, das Passwort zu verschlüsseln, ehe Sie `mysql_real_connect()` aufrufen. Die Passwortverschlüsselung wird automatisch von der Client-API vorgenommen.

- `db` ist der Datenbankname. Wenn `db` nicht `NULL` ist, stellt die Verbindung diesen Wert als Standarddatenbank ein.

- Wenn `port` nicht 0 ist, wird dieser Wert als Portnummer für die TCP/IP-Verbindung benutzt. Beachten Sie, dass der Parameter `host` den Verbindungstyp definiert.

- Wenn `unix_socket` nicht `NULL` ist, gibt der String den Socket oder die Named Pipe für die Verbindung an. Beachten Sie, dass der Parameter `host` den Verbindungstyp definiert.

- Der Wert von `client_flag` ist normalerweise 0, kann aber auf eine Kombination der folgenden Flags eingestellt werden, um bestimmte Features einzuschalten:

  Flag-Name | Flag-Beschreibung
  `CLIENT_COMPRESS` | Verwendet das komprimierte Protokoll.
  `CLIENT_FOUND_ROWS` | Liefert die Anzahl der gefundenen (erkannten) anstatt der Anzahl der betroffenen Zeilen.
  `CLIENT_IGNORE_SPACE` | Erlaubt Leerzeichen hinter Funktionsnamen. Macht alle Funktionsnamen zu reservierten Wörtern.
  `CLIENT_INTERACTIVE` | Erlaubt `interactive_timeout` Sekunden (anstatt `wait_timeout` Sekunden) Müßiggang, bevor die Verbindung geschlossen wird. Die `wait_timeout`-Variable der Client-Session wird auf den Wert der Session-Variablen `interactive_timeout` gesetzt.
  `CLIENT_LOCAL_FILES` | Ermöglicht `LOAD DATA LOCAL`.
  `CLIENT_MULTI_STATEMENTS` | Teilt dem Server mit, dass der Client mehrere Anweisungen (durch ‘`;`’ getrennt) in einem einzigen String senden darf. Ist dieses Flag nicht gesetzt, ist die Ausführung von Mehrfachanweisungen nicht möglich.
  `CLIENT_MULTI_RESULTS` | Teilt dem Server mit, dass der Client mehrere Ergebnismengen von Mehrfachanweisungen oder mehrfachen gespeicherten Prozeduren behandeln kann. Wird automatisch gesetzt, wenn `CLIENT_MULTI_STATEMENTS` eingestellt ist.
  `CLIENT_NO_SCHEMA` | Verbietet die `db_name.tbl_name.col_name`-Syntax. Dies gilt für ODBC. Der Parser löst bei Verwendung dieser Syntax einen Fehler aus, was für die Fehlerdiagnose in manchen ODBC-Programmen nützlich ist.
  `CLIENT_ODBC` | Der Client ist ein ODBC-Client. Damit wird mysqld ODBC-freundlicher.
  `CLIENT_SSL` | Verwendet SSL (verschlüsseltes Protokoll). Diese Option sollte nicht von Anwendungsprogrammen gesetzt werden, sondern intern in der Clientbibliothek. Verwenden Sie stattdessen `mysql_ssl_set()` vor dem Aufruf von `mysql_real_connect()`.

Manche Parameterwerte können einer Optionsdatei entnommen werden, anstatt sie explizit im Aufruf von `mysql_real_connect()` zu setzen. Um dies zu tun, rufen Sie `mysql_options()` mit der Option `MYSQL_READ_DEFAULT_FILE` oder `MYSQL_READ_DEFAULT_GROUP` auf, bevor Sie `mysql_real_connect()` verwenden. Danach geben Sie im Aufruf von `mysql_real_connect()` den Wert „no-value“ für jeden Parameter an, der seinen Wert aus einer Optionsdatei holen soll:

- Für `host` geben Sie `NULL` oder den leeren String (`""`) an.

- Für `user` geben Sie `NULL` oder den leeren String (`""`) an.

- Für `passwd` geben Sie `NULL` an. (Ein leerer String als Passwortwert kann im `mysql_real_connect()`-Aufruf nicht durch einen Wert aus einer Optionsdatei überschrieben werden, da der leere String ausdrücklich besagt, dass das MySQL-Konto ein leeres Passwort besitzen muss.)

- Für `db` geben Sie `NULL` oder den leeren String (`""`) an.

- Für `port` geben Sie den Wert 0 an.

- Für `unix_socket` geben Sie den Wert `NULL` an.

Wenn in der Optionsdatei für einen Parameter kein Wert gefunden wird, wird sein Standardwert gemäß der Beschreibung weiter oben in diesem Abschnitt verwendet.

Rückgabewerte

Ein `MYSQL*`-Verbindungs-Handle, wenn die Verbindung erfolgreich eingerichtet wurde, und `NULL`, wenn der Verbindungsversuch keinen Erfolg hatte. Der Rückgabewert für eine erfolgreiche Verbindung ist derselbe wie der Wert des ersten Parameters.

Fehler

- `CR_CONN_HOST_ERROR`

  Verbindung zum MySQL Server konnte nicht hergestellt werden.

- `CR_CONNECTION_ERROR`

  Verbindung zum lokalen MySQL Server konnte nicht hergestellt werden.

- `CR_IPSOCK_ERROR`

  Es konnte kein IP-Socket hergestellt werden.

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_SOCKET_CREATE_ERROR`

  Es konnte kein Unix-Socket erzeugt werden.

- `CR_UNKNOWN_HOST`

  Die IP-Adresse des Hostnamens konnte nicht gefunden werden.

- `CR_VERSION_ERROR`

  Bei einem Versuch einer Verbindungsaufnahme zwischen einem Server und einer Clientbibliothek, die eine andere Protokollversion verwendet, wurde eine Diskrepanz der Protokolle festgestellt. Das kann geschehen, wenn Sie eine sehr alte Clientbibliothek zur Verbindung mit einem neuen Server verwenden, der nicht mit der Option `--old-protocol` gestartet wurde.

- `CR_NAMEDPIPEOPEN_ERROR`

  Es konnte keine Named Pipe für Windows hergestellt werden.

- `CR_NAMEDPIPEWAIT_ERROR`

  Es konnte nicht auf eine Named Pipe auf Windows gewartet werden.

- `CR_NAMEDPIPESETSTATE_ERROR`

  Es konnte kein Pipe-Handler auf Windows beschafft werden.

- `CR_SERVER_LOST`

  Wenn `connect_timeout` > 0 und es mehr als `connect_timeout` Sekunden dauerte, eine Verbindung mit dem Server herzustellen, oder wenn der Server während der Ausführung des Befehls `init-command` abgestürzt ist.

Beispiel

    MYSQL mysql;

    mysql_init(&mysql);
    mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
    if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
    {
        fprintf(stderr, "Failed to connect to database: Error: %s\n",
              mysql_error(&mysql));
    }

Wenn Sie `mysql_options()` aufrufen, liest die MySQL-Bibliothek die Abschnitte `[client]` und `[your_prog_name]` in der Datei `my.cnf`. So ist gewährleistet, dass Ihr Programm auch dann funktioniert, wenn jemand MySQL in nichtstandardmäßiger Weise eingerichtet hat.

Beachten Sie, dass `mysql_real_connect()` beim Einrichten einer Verbindung das Flag `reconnect` (ein Teil der `MYSQL`-Struktur) bei API-Versionen vor 5.0.3 auf `1` und bei neueren Versionen auf `0` setzt. Hat das Flag den Wert `1`, versucht sich das System erneut mit dem Server zu verbinden, wenn eine Anweisung wegen einer abgebrochenen Verbindung nicht ausgeführt werden konnte. Seit MySQL 5.0.13 können Sie das Verhalten in Bezug auf Neuverbindungen mit der Option `MYSQL_OPT_RECONNECT` zu `mysql_options()` steuern.

#### 24.2.3.52. `mysql_real_escape_string()`

`unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length)`

Beachten Sie, dass `mysql` eine gültige, offene Verbindung sein muss. Diese ist erforderlich, da das Escape-Verhalten von dem Zeichensatz des Servers abhängt.

Beschreibung

Diese Funktion wird verwendet, um einen gültigen SQL-String zu erzeugen, den Sie in einer SQL-Anweisung benutzen können. Siehe Abschnitt 9.1.1, „Strings“.

Der String in `from` ist als SQL-String mit Escape-Zeichen unter Berücksichtigung des aktuellen Zeichensatzes der Verbindung kodiert. Das Ergebnis wird in `to` platziert und ein abschließendes Nullbyte angehängt. Kodierte Zeichen sind `NUL` (ASCII 0), ‘`\n`’, ‘`\r`’, ‘`\`’, ‘`'`’, ‘`"`’ und Strg-Z (siehe Abschnitt 9.1, „Literale: wie Strings und Zahlen geschrieben werden“). (Streng genommen verlangt MySQL ein Escape-Zeichen im Anfrage-String nur für den Backslash und die Sorte Anführungszeichen, in welche der String eingefasst ist. Diese Funktion setzt auch die anderen Zeichen in Anführungszeichen, damit sie in Logdateien leichter zu lesen sind.)

Der String, auf den `from` verweist, muss `length` Bytes lang sein. Den Puffer für `to` müssen Sie mit einer Länge von mindestens `length*2+1` Bytes zuweisen. (Im schlimmsten Fall braucht vielleicht jedes Zeichen 2 Byte für die Kodierung und am Ende muss noch Platz für das Nullbyte vorhanden sein.) Wenn `mysql_real_escape_string()` zurückkehrt, ist der Inhalt von `to` ein auf null endender String. Der Rückgabewert ist die Länge des kodierten Strings ohne das abschließende Nullzeichen.

Wenn Sie den Zeichensatz für die Verbindung umstellen müssen, sollten Sie die Funktion `mysql_set_character_set()` anstelle einer `SET NAMES`- (oder `SET CHARACTER SET`-)Anweisung verwenden. `mysql_set_character_set()` arbeitet wie `SET NAMES`, beeinflusst aber auch den von `mysql_real_escape_string()` verwendeten Zeichensatz. Das tut `SET NAMES` nicht.

Beispiel

    char query[1000],*end;

    end = strmov(query,"INSERT INTO test_table values(");
    *end++ = '\'';
    end += mysql_real_escape_string(&mysql, end,"What's this",11);
    *end++ = '\'';
    *end++ = ',';
    *end++ = '\'';
    end += mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16);
    *end++ = '\'';
    *end++ = ')';

    if (mysql_real_query(&mysql,query,(unsigned int) (end - query)))
    {
       fprintf(stderr, "Failed to insert row, Error: %s\n",
               mysql_error(&mysql));
    }

Die im Beispiel verwendete `strmov()`-Funktion gehört zur `mysqlclient`-Bibliothek und funktioniert wie `strcpy()`, gibt jedoch einen Zeiger auf die abschließende Null des ersten Parameters zurück.

Rückgabewerte

Die Länge des in `to` gesetzten Werts ohne das abschließende Nullzeichen.

Fehler

Keine.

#### 24.2.3.53. `mysql_real_query()`

`int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length)`

Beschreibung

Führt die SQL-Anfrage aus, auf die `query` verweist. Diese sollte ein `length` Bytes langer String sein. Normalerweise muss der String eine einzelne SQL-Anweisung ohne abschließendes Semikolon (‘`;`’) oder `\g` enthalten. Wenn Mehrfachanweisungen aktiviert sind, kann der String auch mehrere durch Semikola getrennte Anweisungen enthalten. Siehe Abschnitt 24.2.9, „C-API: Behandlung der Ausführung mehrerer Anweisungen“.

Sie müssen `mysql_real_query()` anstelle von `mysql_query()` benutzen, wenn Ihre Anfragen Binärdaten enthalten, da diese das ‘`\0`’-Zeichen enthalten können. Überdies ist die Funktion `mysql_real_query()` schneller als `mysql_query()`, da sie nicht `strlen()` auf dem Anfrage-String aufruft.

Wenn Sie wissen möchten, ob die Anfrage eigentlich eine Ergebnismenge zurückliefern sollte, können Sie dies mit `mysql_field_count()` überprüfen. Siehe Abschnitt 24.2.3.22, „`mysql_field_count()`“.

Rückgabewerte

Null, wenn die Anfrage Erfolg hatte. Ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.54. `mysql_refresh()`

`int mysql_refresh(MYSQL *mysql, unsigned int options)`

Beschreibung

Diese Funktionen leeren Tabellen oder Caches oder setzen Replikationsserver-Informationen zurück. Der Benutzer, der die Verbindung innehat, benötigt hierzu das `RELOAD`-Recht.

Das `options`-Argument ist eine Bitmaske, die sich aus einer beliebigen Kombination von folgenden Werten zusammensetzt. Mehrere Werte können mit OR verknüpft werden, um mehrere Operationen mit einem einzigen Aufruf zu erledigen.

- `REFRESH_GRANT`

  Aktualisiert die Berechtigungstabellen, wie `FLUSH PRIVILEGES`.

- `REFRESH_LOG`

  Leert die Logs, wie `FLUSH LOGS`.

- `REFRESH_TABLES`

  Leert den Tabellen-Cache, wie `FLUSH TABLES`.

- `REFRESH_HOSTS`

  Leert den Host-Cache, wie `FLUSH HOSTS`.

- `REFRESH_STATUS`

  Setzt die Statusvariablen zurück, wie `FLUSH STATUS`.

- `REFRESH_THREADS`

  Leert den Thread-Cache.

- `REFRESH_SLAVE`

  Setzt auf einem Slave-Replikationsserver die Informationen über den Master-Server zurück und startet den Slave neu, wie `RESET SLAVE`.

- `REFRESH_MASTER`

  Entfernt auf einem Master-Replikationsserver die im Binärlogindex aufgeführten Binärlogdateien und schneidet die Indexdatei ab, wie `RESET MASTER`.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.55. `mysql_reload()`

`int mysql_reload(MYSQL *mysql)`

Beschreibung

Veranlasst den MySQL Server, die Berechtigungstabellen neu zu laden. Der verbundene Benutzer benötigt hierzu das `RELOAD`-Recht.

Diese Funktion ist veraltet. Bitte benutzen Sie stattdessen `mysql_query()`, um die SQL-Anweisung `FLUSH PRIVILEGES` zu erteilen.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.56. `mysql_rollback()`

`my_bool mysql_rollback(MYSQL *mysql)`

Beschreibung

Rollt die aktuelle Transaktion zurück.

Was diese Funktion tut, hängt von dem Wert der Systemvariablen `completion_type` ab. Wenn der Wert von `completion_type` 2 ist, gibt der Server nach dem Abschluss der Transaktion Ressourcen frei und schließt die Clientverbindung. Das Clientprogramm sollte `mysql_close()` aufrufen, um die Verbindung auf der Clientseite zu schließen.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

Fehler

Keine.

#### 24.2.3.57. `mysql_row_seek()`

`MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)`

Beschreibung

Setzt den Zeilen-Cursor auf eine beliebige Zeile in der Ergebnismenge einer Anfrage. Der `offset`-Wert ist ein Zeilen-Offset. Dieser sollte ein von `mysql_row_tell()` oder `mysql_row_seek()` zurückgegebener Wert sein. Er ist keine Zeilennummer; wenn Sie eine Zeile einer Ergebnismenge anhand ihrer Nummer suchen möchten, müssen Sie stattdessen `mysql_data_seek()` aufrufen.

Da für diese Funktion erforderlich ist, dass die Ergebnismengenstruktur das gesamte Anfrageergebnis enthält, kann `mysql_row_seek()` nur in Verbindung mit `mysql_store_result()` und nicht mit `mysql_use_result()` benutzt werden.

Rückgabewerte

Der vorherige Wert des Zeilen-Cursors. Dieser Wert kann an einen nachfolgenden `mysql_row_seek()`-Aufruf übergeben werden.

Fehler

Keine.

#### 24.2.3.58. `mysql_row_tell()`

`MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)`

Beschreibung

Gibt die aktuelle Position des Zeilen-Cursors für den letzten `mysql_fetch_row()`-Aufruf zurück. Dieser Wert kann als Argument an `mysql_row_seek()` übergeben werden.

Verwenden Sie `mysql_row_tell()` bitte nur nach `mysql_store_result()` und nicht nach `mysql_use_result()`.

Rückgabewerte

Der aktuelle Offset des Zeilen-Cursors.

Fehler

Keine.

#### 24.2.3.59. `mysql_select_db()`

`int mysql_select_db(MYSQL *mysql, const char *db)`

Beschreibung

Macht die Datenbank `db` zur Standarddatenbank auf der durch `mysql` angegebenen Verbindung. In den nachfolgenden Anfragen ist diese Datenbank der Standard für Tabellenreferenzen, die keine explizite Datenbankbezeichnung enthalten.

`mysql_select_db()` funktioniert nur, wenn der verbundene Benutzer mit der Berechtigung, die Datenbank zu nutzen, authentifiziert werden kann.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.60. `mysql_set_character_set()`

`int mysql_set_character_set(MYSQL *mysql, char *csname)`

Beschreibung

Diese Funktion stellt den Standardzeichensatz für die laufende Verbindung ein. Der String `csname` ist ein gültiger Zeichensatzname. Die Sortierreihenfolge der Verbindung wird die Standardsortierreihenfolge dieses Zeichensatzes. Die Funktion arbeitet wie die `SET NAMES`-Anweisung, stellt jedoch auch den Wert von `mysql->charset` ein und beeinflusst dadurch den von `mysql_real_escape_string()` verwendeten Zeichensatz.

Diese Funktion wurde in MySQL 5.0.7 hinzugefügt.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

Beispiel

    MYSQL mysql;

    mysql_init(&mysql);
    if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
    {
        fprintf(stderr, "Failed to connect to database: Error: %s\n",
              mysql_error(&mysql));
    }

    if (!mysql_set_charset_name(&mysql, "utf8"))
    {
        printf("New client character set: %s\n", mysql_character_set_name(&mysql));
    }

#### 24.2.3.61. `mysql_set_server_option()`

`int mysql_set_server_option(MYSQL *mysql, enum enum_mysql_set_option option)`

Beschreibung

Aktiviert oder deaktiviert eine Verbindungsoption. `option` kann einen der folgenden Werte haben:

MYSQL_OPTION_MULTI_STATEMENTS_ON | Schaltet Unterstützung für Mehrfachanweisungen ein.
MYSQL_OPTION_MULTI_STATEMENTS_OFF | Schaltet Unterstützung für Mehrfachanweisungen aus.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `ER_UNKNOWN_COM_ERROR`

  Der Server unterstützte `mysql_set_server_option()` nicht (das ist der Fall, wenn der Server älter als 4.1.1 ist) oder er unterstützte die Option nicht, die man versuchte, einzustellen.

#### 24.2.3.62. `mysql_shutdown()`

`int mysql_shutdown(MYSQL *mysql, enum enum_shutdown_level shutdown_level)`

Beschreibung

Veranlasst den Datenbankserver, herunterzufahren. Der Benutzer der Verbindung muss die`SHUTDOWN`-Rechte besitzen. MySQL 5.1 Server unterstützen nur eine einzige Art von Shutdown; der `shutdown_level` muss der `SHUTDOWN_DEFAULT` sein. Wir planen, noch weitere Shutdown-Level einzuführen, um eine Wahlmöglichkeit zu eröffnen. Dynamisch verlinkte Executables, die mit älteren Versionen der `libmysqlclient`-Header kompiliert wurden und `mysql_shutdown()` aufrufen, müssen mit der älteren dynamischen Bibliothek `libmysqlclient` benutzt werden.

Der Shutdown-Prozess wird in Abschnitt 5.2.6, „Herunterfahren des MySQL Servers“, beschrieben.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.63. `mysql_sqlstate()`

`const char *mysql_sqlstate(MYSQL *mysql)`

Beschreibung

Gibt einen auf null endenden String mit dem SQLSTATE-Fehlercode für den letzten Fehler zurück. Der Fehlercode besteht aus fünf Zeichen. `'00000'` bedeutet „kein Fehler“. Die Werte sind durch ANSI-SQL und ODBC spezifiziert. Eine Liste der möglichen Werte finden Sie unter Anhang B, Fehlercodes und -meldungen.

Beachten Sie, dass sich nicht alle MySQL-Fehler SQLSTATE-Fehlercodes zuordnen lassen. Der Wert `'HY000'` (allgemeiner Fehler) wird für Fehler verwendet, die nicht zuzuordnen sind.

Rückgabewerte

Ein auf null endender Zeichen-String mit dem SQLSTATE-Fehlercode.

Siehe auch

Siehe Abschnitt 24.2.3.14, „`mysql_errno()`“, Abschnitt 24.2.3.15, „`mysql_error()`“, und Abschnitt 24.2.7.26, „`mysql_stmt_sqlstate()`“.

#### 24.2.3.64. `mysql_ssl_set()`

`int mysql_ssl_set(MYSQL *mysql, const char *key, const char *cert, const char *ca, const char *capath, const char *cipher)`

Beschreibung

`mysql_ssl_set()` richtet sichere SSL-Verbindungen ein. Diese Funktion muss vor `mysql_real_connect()` aufgerufen werden.

`mysql_ssl_set()` arbeitet nur, wenn in der Clientbibliothek die OpenSSL-Unterstützung aktiviert ist.

`mysql` ist der Verbindungs-Handler, der von `mysql_init()` zurückgegeben wird. Die anderen Parameter sind folgendermaßen spezifiziert:

- `key` ist der Pfad zur Schlüsseldatei.

- `cert` ist der Pfad zur Zertifikatsdatei.

- `ca` ist der Pfad zur Certificate-Authority-Datei.

- `capath` ist der Pfad zu einem Verzeichnis, das vertrauenswürdige SSL-CA-Zertifikate im Pem-Format enthält.

- `cipher` ist eine Liste der zulässigen Chiffren für die SSL-Verschlüsselung.

Ungenutzte SSL-Parameter können mit `NULL` angegeben werden.

Rückgabewerte

Diese Funktion liefert immer `0`. Wenn SSL verkehrt eingerichtet ist, gibt `mysql_real_connect()` bei Verbindungsversuchen einen Fehler zurück.

#### 24.2.3.65. `mysql_stat()`

`char *mysql_stat(MYSQL *mysql)`

Beschreibung

Gibt einen Zeichen-String mit ähnlichen Informationen wie der Befehl mysqladmin status zurück. Dazu gehört die Uptime in Sekunden und die Anzahl der laufenden Threads, Fragen, Reloads und offenen Tabellen.

Rückgabewerte

Ein Zeichen-String, der den Serverstatus beschreibt. `NULL`, wenn ein Fehler auftrat.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.66. `mysql_store_result()`

`MYSQL_RES *mysql_store_result(MYSQL *mysql)`

Beschreibung

Sie müssen `mysql_store_result()` oder `mysql_use_result()` für jede Anfrage aufrufen, die erfolgreich Daten abruft (`SELECT`, `SHOW`, `DESCRIBE`, `EXPLAIN`, `CHECK TABLE`, und so weiter).

Für andere Anfragen brauchen Sie `mysql_store_result()` oder `mysql_use_result()` nicht zu verwenden, aber es schadet auch nichts und bringt keine spürbaren Leistungseinbußen, wenn Sie in jedem Fall `mysql_store_result()` aufrufen. Sie können erkennen, ob die Anfrage eine Ergebnismenge hatte oder nicht, indem Sie prüfen, ob `mysql_store_result()` 0 zurückgibt (darüber später mehr).

Wenn Sie wissen möchten, ob die Anfrage eine Ergebnismenge zurückgeben müsste, prüfen Sie dies mit `mysql_field_count()`. Siehe Abschnitt 24.2.3.22, „`mysql_field_count()`“.

`mysql_store_result()` liest das gesamte Anfrageergebnis auf den Client ein, weist eine `MYSQL_RES`-Struktur zu und setzt das Resultat in diese Struktur ein.

`mysql_store_result()` liefert einen Nullzeiger, wenn die Anfrage keine Ergebnismenge zurückgab (also beispielsweise eine `INSERT`-Anweisung war).

`mysql_store_result()` liefert auch einen Nullzeiger, wenn die Ergebnismenge nicht gelesen werden konnte. Ein Fehler ist aufgetreten, wenn `mysql_error()` einen nichtleeren String oder einen von null verschiedenen Wert liefert oder wenn `mysql_field_count()` null zurückgibt.

Eine leere Ergebnismenge bedeutet, dass keine Zeilen zurückgegeben wurden. (Eine leere Ergebnismenge ist etwas anderes als ein Nullzeiger als Rückgabewert.)

Wenn Sie `mysql_store_result()` aufgerufen und ein Ergebnis erhalten haben, das kein Nullzeiger ist, können Sie mit `mysql_num_rows()` ermitteln, wie viele Zeilen die Ergebnismenge hat.

Sie können mit `mysql_fetch_row()` Zeilen aus der Ergebnismenge abrufen oder mit `mysql_row_seek()` und `mysql_row_tell()` die aktuelle Zeilenposition in der Ergebnismenge ermitteln oder einstellen.

Wenn Sie mit der Ergebnismenge fertig sind, rufen Sie `mysql_free_result()` auf.

Siehe Abschnitt 24.2.13.1, „Warum gibt `mysql_store_result()` manchmal `NULL` zurück, nachdem `mysql_query()` Erfolg zurückgegeben hat?“.

Rückgabewerte

Eine `MYSQL_RES`-Ergebnisstruktur mit den Resultaten. `NULL`, wenn ein Fehler auftrat.

Fehler

Die Funktion `mysql_store_result()` setzt `mysql_error()` und `mysql_errno()` zurück, wenn sie erfolgreich gelaufen ist.

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.67. `mysql_thread_id()`

`unsigned long mysql_thread_id(MYSQL *mysql)`

Beschreibung

Gibt die Thread-ID der aktuellen Verbindung zurück. Dieser Wert kann als Argument für `mysql_kill()` verwendet werden, um den Thread anzuhalten.

Wenn die Verbindung abgebrochen ist und Sie sich mit `mysql_ping()` erneut zu verbinden versuchen, ändert sich die Thread-ID. Daher sollten Sie keine Thread-ID zur späteren Benutzung speichern, sondern sie erst dann erfragen, wenn Sie sie benötigen.

Rückgabewerte

Die Thread-ID der aktuellen Verbindung.

Fehler

Keine.

#### 24.2.3.68. `mysql_use_result()`

`MYSQL_RES *mysql_use_result(MYSQL *mysql)`

Beschreibung

Sie müssen `mysql_store_result()` oder `mysql_use_result()` für jede Anfrage aufrufen, die erfolgreich Daten abruft (`SELECT`, `SHOW`, `DESCRIBE`, `EXPLAIN`).

`mysql_use_result()` initiiert den Abruf einer Ergebnismenge, lädt sie jedoch im Gegensatz zu `mysql_store_result()` nicht komplett auf den Client herunter. Stattdessen wird jede Zeile einzeln mit einem Aufruf von `mysql_fetch_row()` abgefragt. So wird ein Anfrageergebnis direkt vom Server gelesen, ohne es in einer temporären Tabelle oder in einem lokalen Puffer zwischenzuspeichern. Das geht schneller und belegt weniger Speicher als `mysql_store_result()`. Der Client weist nur für die aktuelle Zeile Speicher zu und reserviert einen Kommunikationspuffer, der bis zur Größe von `max_allowed_packet` Bytes anwachsen kann.

Demgegenüber sollten Sie `mysql_use_result()` nicht verwenden, wenn Sie jede Zeile auf der Clientseite aufwändig vearbeiten oder die Ausgabe an einen Bildschirm senden, in den der Benutzer `^S` (Stop Scroll) eintippen kann. Dies würde den Server sperren und verhindern, dass andere Threads Tabellen aktualisieren können, aus denen die Daten abgerufen werden.

Wenn Sie mit `mysql_use_result()` arbeiten, müssen Sie `mysql_fetch_row()` so oft ausführen, bis ein `NULL`-Wert zurückgeliefert wird. Sonst werden die nicht abgerufenen Zeilen zu einem Teil der Ergebnismenge der nächsten Anfrage. Wenn Sie dies vergessen, meldet die C-API den Fehler `Commands out of sync; you can't run this command now`!

Die Funktionen `mysql_data_seek()`, `mysql_row_seek()`, `mysql_row_tell()`, `mysql_num_rows()` oder `mysql_affected_rows()` können nicht mit einer Ergebnisrückgabe von `mysql_use_result()` benutzt werden. Ebenso wenig können Sie andere Anfragen absetzen, bevor die Funktion `mysql_use_result()` ihre Arbeit beendet hat. (Immerhin liefert `mysql_num_rows()` ein akkurates Ergebnis, wenn Sie alle Zeilen abgeholt haben.)

Sie müssen `mysql_free_result()` aufrufen, wenn Sie mit der Ergebnismenge fertig sind.

Bei Verwendung des Embedded Servers `libmysqld` geht der Vorteil des geringen Speicherbedarfs verloren, da die Speicherbelegung inkrementell mit jeder abgeholten Zeile anwächst, bis Sie `mysql_free_result()` aufrufen.

Rückgabewerte

Eine `MYSQL_RES`-Ergebnisstruktur. `NULL`, wenn ein Fehler auftrat.

Fehler

`mysql_use_result()` setzt bei Erfolg `mysql_error()` und `mysql_errno()` zurück.

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.3.69. `mysql_warning_count()`

`unsigned int mysql_warning_count(MYSQL *mysql)`

Beschreibung

Gibt die Anzahl der während der Ausführung der vorangegangenen SQL-Anweisung ausgelösten Warnungen zurück.

Rückgabewerte

Die Anzahl der Warnungen.

Fehler

Keine.

### 24.2.4. C-API: Prepared Statements

Das Client/Server-Protokoll von MySQL ermöglicht auch vorbereitete Anweisungen. Diese nutzen die Datenstruktur eines `MYSQL_STMT`-Anweisungs-Handles, der von der Initialisierungsfunktion `mysql_stmt_init()` zurückgegeben wird. Die vorbereitete Ausführung ist ein effizientes Mittel, um eine Anweisung mehrmals laufen zu lassen. Zuerst wird sie geparst, um sie auf die Ausführung vorzubereiten, und später wird sie einmal oder mehrmals mithilfe des von der Initialisierungsfunktion zurückgelieferten Anweisungs-Handles benutzt.

Die vorbereitete Ausführung ist für Anweisungen, die mehrmals laufen, schneller als eine direkte Ausführung, da die Anfrage nur ein einziges Mal geparst werden muss. Bei einer direkten Ausführung muss die Anfrage dagegen jedes Mal von Neuem geparst werden. Eine vorbereitete Ausführung kann außerdem die Netzwerklast reduzieren, da bei jeder Ausführung der vorbereiteten Anweisung lediglich die Parameterdaten übermittelt werden müssen.

Ein weiterer Vorteil vorbereiteter Anweisungen besteht darin, dass sie ein Binärprotokoll benutzen, das den Datentransfer zwischen Client und Server effizienter gestaltet.

Die folgenden Anweisungen können als vorbereitete Anweisungen verwendet werden: `CREATE TABLE`, `DELETE`, `DO`, `INSERT`, `REPLACE`, `SELECT`, `SET`, `UPDATE` und die meisten `SHOW`-Anweisungen. Andere Anweisungen werden in MySQL 5.1 nicht unterstützt.

### 24.2.5. C-API: Prepared Statement-Datentypen

Vorbereitete Anweisungen nutzen hauptsächlich die Datenstrukturen `MYSQL_STMT` und `MYSQL_BIND`. Eine dritte Datenstruktur, nämlich `MYSQL_TIME`, wird zur Übertragung von Temporaldaten verwendet.

- `MYSQL_STMT`

  Diese Struktur stellt eine vorbereitete Anweisung dar. Eine Anweisung wird mit der Funktion `mysql_stmt_init()` angelegt, die einen Anweisungs-Handle liefert (d. h. einen Zeiger auf `MYSQL_STMT`). Der Handle wird für alle folgenden mit der Anweisung verbundenen Funktionen benutzt, bis Sie ihn mit `mysql_stmt_close()` wieder schließen.

  Die `MYSQL_STMT`-Struktur hat keine Bestandteile für Anwendungen. Legen Sie bitte auch keine Kopie einer `MYSQL_STMT`-Struktur an, da nicht garantiert werden kann, dass eine solche Kopie benutzbar sein wird.

  Mehrere Anweisungs-Handles können mit einer einzigen Verbindung verknüpft werden. Wie viele Handles möglich sind, hängt von den Systemressourcen ab.

- `MYSQL_BIND`

  Diese Struktur wird sowohl für die Eingabe einer Anweisung (der Datenwerte, die an den Server gesandt werden) als auch für ihre Ausgabe verwendet (die Ergebnisse, die vom Server zurückkommen). Für die Eingabe wird sie mit `mysql_stmt_bind_param()` benutzt, um die Parameterwerte an die Puffer zu binden, die `mysql_stmt_execute()` verwenden. Für die Ausgabe wird sie mit `mysql_stmt_bind_result()` benutzt, um die Ergebnismengenpuffer zu binden, die zum Abholen der Zeilen mit `mysql_stmt_fetch()` verwendet werden.

  Die `MYSQL_BIND`-Struktur enthält folgende Bestandteile zur Nutzung durch Anwendungsprogramme. Jeder Bestandteil wird sowohl für die Ein- als auch für die Ausgabe verwendet, allerdings manchmal zu unterschiedlichen Zwecken, je nachdem, in welche Richtung die Daten übertragen werden.

  - `enum enum_field_types buffer_type`

    Der Puffertyp. Die zulässigen `buffer_type`-Werte werden weiter unten in diesem Abschnitt aufgeführt. Für die Eingabe zeigt `buffer_type` an, welchen Werttyp Sie mit einem Anweisungsparameter verbinden. Für die Ausgabe zeigt er an, welchen Werttyp Sie in einem Ergebnispuffer erwarten.

  - `void *buffer`

    Für die Eingabe ist dies ein Zeiger auf den Puffer, in welchem die Parameterwerte einer Anweisung gespeichert werden. Für die Ausgabe ist es ein Zeiger auf den Puffer, in welchen die Spaltenwerte einer Ergebnismenge zurückgeliefert werden. Für numerische Datentypen sollte `buffer` auf eine Variable des korrekten C-Typs verweisen. (Wenn Sie die Variable mit einer Spalte verbinden, die das `UNSIGNED`-Attribut hat, sollte sie ein `unsigned`-C-Typ sein. Ob die Variable ein Vorzeichen hat oder nicht, geben Sie mithilfe des weiter unten beschriebenen Strukturbestandteils `is_unsigned` an.) Für Datums- und Uhrzeittypen sollte `buffer` auf eine `MYSQL_TIME`-Struktur verweisen. Für Zeichen- und Binär-String-Typen sollte `buffer` auf einen Zeichenpuffer verweisen.

  - `unsigned long buffer_length`

    Die tatsächliche Größe von `*buffer` in Bytes. Dies zeigt an, wie viele Daten maximal in dem Puffer gespeichert werden können. Für Zeichen und binäre C-Daten ist der `buffer_length`-Wert die Länge von `*buffer`, wenn er mit `mysql_stmt_bind_param()` gebraucht wird, beziehungsweise die Höchstzahl der Datenbytes, die in den Puffer zu laden sind, wenn er mit `mysql_stmt_bind_result()` gebraucht wird.

  - `unsigned long *length`

    Ein Zeiger auf eine `unsigned long`-Variable, die angibt, wie viele Bytes tatsächlich in `*buffer` gespeichert sind. `length` wird für Zeichen- oder Binärdaten in C verwendet. Zum Binden der Eingabeparameterdaten verweist `length` auf eine `unsigned long`-Variable, welche die Länge des in `*buffer` gespeicherten Parameterwerts angibt. Diese wird von `mysql_stmt_execute()` benutzt. Zum Binden der Ausgabewerte speichert `mysql_stmt_fetch()` die Länge des Rückgabespaltenwerts in der Variablen, auf die `length` verweist.

    `length` wird bei numerischen und temporalen Datentypen ignoriert, weil die Länge des Datenwerts anhand des Werts von `buffer_type` ermittelt wird.

  - `my_bool *is_null`

    Dies verweist auf eine `my_bool`-Variable, die TRUE ist, wenn ein Wert `NULL` ist, und FALSE, wenn er nicht `NULL` ist. Für die Eingabe setzen Sie `*is_null` auf TRUE, wenn Sie mitteilen möchten, dass Sie einen `NULL`-Wert als Anweisungsparameter übergeben. Für die Ausgabe wird dieser Wert nach dem Abruf einer Zeile der Ergebnismenge immer dann auf TRUE gesetzt, wenn der Spaltenwert, den die Anweisung zurückliefert, `NULL` ist.

    `is_null` ist ein Zeiger auf einen booleschen Wert anstatt auf einen booleschen Skalar. Daher kann er auf folgende Weise eingesetzt werden:

    - Wenn Ihre Datenwerte immer `NULL` sind, verwenden Sie `MYSQL_TYPE_NULL`, um die Spalte zu binden.

    - Wenn Ihre Datenwerte immer `NOT NULL` sind, stellen Sie ein: `is_null = (my_bool*) 0`.

    - In allen anderen Fällen sollten Sie `is_null` auf die Adresse einer `my_bool`-Variablen einstellen und deren Wert zwischen den Ausführungen jeweils so einstellen, dass sie anzeigt, ob Datenwerte `NULL` oder `NOT NULL` sind.

  - `my_bool is_unsigned`

    Dies wird für Integer-Typen benutzt (die den Typcodes `MYSQL_TYPE_TINY`, `MYSQL_TYPE_SHORT`, `MYSQL_TYPE_LONG` und `MYSQL_TYPE_LONGLONG` entsprechen.) `is_unsigned` sollte für vorzeichenlose Typen auf TRUE und für vorzeichenbehaftete auf FALSE gesetzt werden.

  - `my_bool error`

    Für die Ausgabe wird dieser Strukturbestandteil zur Meldung von Fehlern wegen abgeschnittener Datenwerte eingesetzt. Sie müssen diese Meldungen aktivieren, indem Sie `mysql_options()` mit der Option `MYSQL_REPORT_DATA_TRUNCATION` aufrufen. Wenn dies aktiviert ist, liefert `mysql_stmt_fetch()` die `MYSQL_DATA_TRUNCATED`-Meldungen und `error` ist in den `MYSQL_BIND`-Strukturen für Parameter, deren Datenwerte abgeschnitten wurden, TRUE. Beim Abschneiden geht ein Vorzeichen oder eine signifikante Ziffer verloren oder ein String hat nicht in eine Spalte gepasst.

  Um eine `MYSQL_BIND`-Struktur zu verwenden, müssen Sie zur Initialisierung ihren Inhalt auf null setzen und dann die soeben beschriebenen Bestandteile in geeigneter Weise einstellen. Wenn Sie beispielsweise ein Array von drei `MYSQL_BIND`-Strukturen deklarieren und initialisieren möchten, verfahren Sie folgendermaßen:

      MYSQL_BIND    bind[3];
      memset(bind, 0, sizeof(bind));

- `MYSQL_TIME`

  Diese Struktur sendet und empfängt Daten vom Typ `DATE`, `TIME`, `DATETIME` und `TIMESTAMP` direkt an den bzw. von dem Server. Dies tut sie, indem der `buffer_type`-Teil einer `MYSQL_BIND`-Struktur auf einen der temporalen Datentypen und der `buffer` auf eine `MYSQL_TIME`-Struktur eingestellt wird.

  Die `MYSQL_TIME`-Struktur enthält folgende Bestandteile:

  - `unsigned int year`

    Das Jahr.

  - `unsigned int month`

    Der Monat des Jahres.

  - `unsigned int day`

    Der Tag des Monats.

  - `unsigned int hour`

    Die Stunde des Tages.

  - `unsigned int minute`

    Die Minute der Stunde.

  - `unsigned int second`

    Die Sekunde der Minute.

  - `my_bool neg`

    Ein boolesches Flag, das angibt, ob der Zeitwert negativ ist.

  - `unsigned long second_part`

    Ein Sekundenbruchteil. Dieser Teil wird zurzeit nicht benutzt.

  Es werden nur diejenigen Teile einer `MYSQL_TIME`-Struktur benutzt, die auf einen gegebenen Temporalwerttyp anwendbar sind: Die Elemente `year`, `month` und `day` werden für `DATE`-, `DATETIME`- und `TIMESTAMP`-Werte gebraucht und die Elemente `hour`, `minute` und `second` für `TIME`-, `DATETIME`- und `TIMESTAMP`-Werte. Siehe Abschnitt 24.2.10, „C-API: Behandlung von Datums- und Zeitwerten“.

Die folgende Tabelle zeigt die zulässigen Werte an, die im `buffer_type`-Teil von `MYSQL_BIND`-Strukturen angegeben werden können. Sie dokumentiert auch, welche SQL-Typen am ehesten den `buffer_type`-Werten entsprechen, sowie den entsprechenden C-Typ für numerische und temporale Typen.

`buffer_type` Wert | SQL-Typ | C-Typ
`MYSQL_TYPE_BIT` | `BIT` | ``
`MYSQL_TYPE_TINY` | `TINYINT` | `char`
`MYSQL_TYPE_SHORT` | `SMALLINT` | `short int`
`MYSQL_TYPE_LONG` | `INT` | `int`
`MYSQL_TYPE_LONGLONG` | `BIGINT` | `long long int`
`MYSQL_TYPE_FLOAT` | `FLOAT` | `float`
`MYSQL_TYPE_DOUBLE` | `DOUBLE` | `double`
`MYSQL_TYPE_TIME` | `TIME` | `MYSQL_TIME`
`MYSQL_TYPE_DATE` | `DATE` | `MYSQL_TIME`
`MYSQL_TYPE_DATETIME` | `DATETIME` | `MYSQL_TIME`
`MYSQL_TYPE_TIMESTAMP` | `TIMESTAMP` | `MYSQL_TIME`
`MYSQL_TYPE_STRING` | `CHAR` |
`MYSQL_TYPE_VAR_STRING` | `VARCHAR` |
`MYSQL_TYPE_TINY_BLOB` | `TINYBLOB/TINYTEXT` |
`MYSQL_TYPE_BLOB` | `BLOB/TEXT` |
`MYSQL_TYPE_MEDIUM_BLOB` | `MEDIUMBLOB/MEDIUMTEXT` |
`MYSQL_TYPE_LONG_BLOB` | `LONGBLOB/LONGTEXT` |

Eine implizite Typumwandlung ist in beiden Richtungen möglich.

### 24.2.6. C-API Prepared Statements: Funktionsüberblick

Die Funktionen für vorbereitete Anweisungen werden hier zusammengefasst und im Weiteren genauer beschrieben. Siehe Abschnitt 24.2.7, „C-API Prepared Statements: Funktionsbeschreibungen“.

Funktion | Beschreibung
mysql_stmt_affected_rows() | Liefert die Anzahl der Änderungen, Löschungen und Einfügungen in Zeilen durch eine vorbereitete `UPDATE`-, `DELETE`- oder `INSERT`-Anweisung.
mysql_stmt_attr_get() | Holt den Wert eines Attributs für eine vorbereitete Anweisung.
mysql_stmt_attr_set() | Setzt ein Attribut für eine vorbereitete Anweisung.
mysql_stmt_bind_param() | Verbindet Anwendungsdatenpuffer mit den Parametermarkern einer vorbereiteten SQL-Anweisung.
mysql_stmt_bind_result() | Verbindet Anwendungsdatenpuffer mit den Spalten der Ergebnismenge.
mysql_stmt_close() | Gibt den von einer vorbereiteten Anweisung benutzten Speicher frei.
mysql_stmt_data_seek() | Sucht nach einer beliebigen Zeilennummer in der Ergebnismenge einer Anweisung.
mysql_stmt_errno() | Liefert die Fehlernummer für die letzte Ausführung einer Anweisung.
mysql_stmt_error() | Liefert die Fehlermeldung für die letzte Ausführung einer Anweisung.
mysql_stmt_execute() | Führt die vorbereitete Anweisung aus.
mysql_stmt_fetch() | Holt die nächste Datenzeile aus der Ergebnismenge und liefert Daten für alle gebundenen Spalten.
mysql_stmt_fetch_column() | Holt Daten einer Spalte aus der aktuellen Zeile der Ergebnismenge.
mysql_stmt_field_count() | Liefert die Anzahl der Ergebnisspalten für die letzte Anweisung.
mysql_stmt_free_result() | Gibt die für den Anweisungs-Handle zugewiesenen Ressourcen frei.
mysql_stmt_init() | Weist der `MYSQL_STMT`-Struktur Speicher zu und initialisiert sie.
mysql_stmt_insert_id() | Liefert die für eine `AUTO_INCREMENT`-Spalte von einer vorbereiteten Anweisung generierte ID.
mysql_stmt_num_rows() | Liefert die Gesamtzahl der Zeilen in der gepufferten Ergebnismenge der Anweisung.
mysql_stmt_param_count() | Liefert die Anzahl der Parameter in einer vorbereiteten SQL-Anweisung.
mysql_stmt_param_metadata() | Liefert Parametermetadaten in Form einer Ergebnismenge.
mysql_stmt_prepare() | Bereitet einen SQL-String zur Ausführung vor.
mysql_stmt_reset() | Setzt die Anweisungspuffer im Server zurück.
mysql_stmt_result_metadata() | Liefert Metadaten zu einer vorbereiteten Anweisung in Form einer Ergebnismenge.
mysql_stmt_row_seek() | Sucht einen Zeilen-Offset in der Ergebnismenge einer Anweisung und verwendet dazu den Rückgabewert von `mysql_stmt_row_tell()`.
mysql_stmt_row_tell() | Liefert die Zeilen-Cursor-Position der Anweisung.
mysql_stmt_send_long_data() | Sendet lange Daten stückweise an den Server.
mysql_stmt_sqlstate() | Liefert den SQLSTATE-Fehlercode für die letzte Anweisungsausführung.
mysql_stmt_store_result() | Lädt die gesamte Ergebnismenge auf den Client herunter.

Rufen Sie zuerst `mysql_stmt_init()` auf, um einen Anweisungs-Handle zu erzeugen, dann `mysql_stmt_prepare`, um die Anweisung vorzubereiten, dann `mysql_stmt_bind_param()`, um die Parameterdaten zu liefern, und zum Schluss `mysql_stmt_execute()`, um die Anweisung auszuführen. Sie können den `mysql_stmt_execute()`-Aufruf wiederholen, indem Sie die Parameterwerte in den jeweiligen von `mysql_stmt_bind_param()` zur Verfügung gestellten Puffern ändern.

Ist die Anweisung ein `SELECT` oder eine andere Anweisung, die eine Ergebnismenge erstellt, liefert `mysql_stmt_prepare()` zu dieser Ergebnismenge auch Metadaten in Form einer von `mysql_stmt_result_metadata()` zurückgegebenen `MYSQL_RES`-Ergebnismenge.

Sie können die Ergebnispuffer mit `mysql_stmt_bind_result()` zur Verfügung stellen, sodass `mysql_stmt_fetch()` automatisch Daten an diese Puffer liefert. Dabei handelt es sich um einen zeilenweisen Datenabruf.

Sie können auch die Text- oder Binärdaten mit `mysql_stmt_send_long_data()` stückweise an den Server senden. Siehe Abschnitt 24.2.7.25, „`mysql_stmt_send_long_data()`“.

Wenn die Anweisungsausführung abgeschlossen ist, muss der Anweisungs-Handle mit `mysql_stmt_close()` geschlossen werden, damit alle seine Ressourcen freigegeben werden können.

Wenn Sie mit `mysql_stmt_result_metadata()` Metadaten zur Ergebnismenge einer `SELECT`-Anweisung beschafft haben, müssen Sie mit `mysql_free_result()` auch diese Metadaten freigeben.

Ausführungsschritte

Um eine Anweisung zur Nutzung in einer Anwendung vorzubereiten und auszuführen, müssen Sie Folgendes tun:

1. Mit `msyql_stmt_init()` erzeugen Sie einen Handle für eine vorbereitete Anweisung. Um die Anweisung auf dem Server vorzubereiten, müssen Sie die Funktion `mysql_stmt_prepare()` aufrufen und ihr einen String mit der SQL-Anweisung übergeben.

2. Wenn die Anweisung eine Ergebnismenge erstellt, müssen Sie die Metadaten dieser Ergebnismenge mit `mysql_stmt_result_metadata()` abholen. Die Metadaten liegen selbst ebenfalls in Form einer Ergebnismenge vor, allerdings einer anderen als der, die die Rückgabezeilen der Anfrage enthält. Die Metadatenergebnismenge gibt an, wie viele Spalten das Ergebnis enthält, und gibt Informationen über jede dieser Spalten.

3. Die Parameterwerte setzen Sie mit `mysql_stmt_bind_param()`. Alle Parameter müssen gesetzt werden. Andernfalls gibt die Anweisungsausführung einen Fehler zurück oder liefert unerwartete Resultate.

4. Mit einem Aufruf von `mysql_stmt_execute()` führen Sie die Anweisung aus.

5. Wenn die Anweisung eine Ergebnismenge erstellt, binden Sie die Datenpuffer zum Abruf der Zeilenwerte mit `mysql_stmt_bind_result()`.

6. Laden Sie die Daten zeilenweise durch wiederholten Aufruf von `mysql_stmt_fetch()` in die Puffer herunter, bis keine weiteren Zeilen mehr vorliegen.

7. Wiederholen Sie die Schritte 3 bis 6 so oft wie nötig, indem Sie die Parameterwerte ändern und die Anweisung erneut ausführen.

Bei einem Aufruf von `mysql_stmt_prepare()` tut das MySQL-Client/Server-Protokoll Folgendes:

- Der Server parst die Anweisung und sendet den Okay-Status an den Client, indem er eine Anweisungs-ID zuweist. Außerdem sendet er, falls die Anweisung eine Ergebnismenge liefert, die Gesamtzahl der Parameter, eine Zeilenzahl und die Metadaten. Die Syntax und Semantik der Anweisung werden auf dem Server während dieses Aufrufs überprüft.

- Der Client verwendet diese Anweisungs-ID für weitere Operationen, damit der Server die Anweisung in seinem Anweisungspool wiederfinden kann.

Bei einem Aufruf von `mysql_stmt_execute()` geht das MySQL-Client/Server-Protokoll folgendermaßen vor:

- Der Client nutzt den Anweisungs-Handle und sendet die Parameterdaten an den Server.

- Der Server findet die Anweisung anhand der vom Client übergebenen ID wieder, ersetzt die Parametermarker mit den frisch gelieferten Daten und führt die Anweisung aus. Wenn die Anweisung eine Ergebnismenge erstellt, sendet der Server die Daten an den Client zurück, ansonsten sendet er einen Okay-Status und die Gesamtzahl der geänderten, gelöschten oder eingefügten Zeilen.

Bei einem Aufruf von `mysql_stmt_fetch()` geht das MySQL-Client/Server-Protokoll folgendermaßen vor:

- Der Client liest die Daten zeilenweise aus dem Paket ein und setzt sie in die Datenpuffer der Anwendung, indem er die notwendigen Typkonvertierungen vornimmt. Hat der Anwendungsdatenpuffer denselben Typ wie das vom Server zurückgegebene Feld, ist die Konvertierung einfach.

Wenn ein Fehler auftritt, können Sie den Anweisungsfehlercode, die Fehlermeldung und den SQLSTATE-Wert mit den Funktionen `mysql_stmt_errno()`, `mysql_stmt_error()` und `mysql_stmt_sqlstate()` erhalten.

Protokollierung vorbereiteter Anweisungen

Für vorbereitete Anweisungen, die mit den C-API-Funktionen `mysql_stmt_prepare()` und `mysql_stmt_execute()` ausgeführt werden, schreibt der Server `Prepare`- und `Execute`-Zeilen in das allgemeine Anfragenlog, damit Sie hinterher wissen, wann Anweisungen vorbereitet und ausgeführt wurden.

Angenommen, Sie bereiten eine Anweisung folgendermaßen vor und führen sie aus:

1. Sie rufen `mysql_stmt_prepare()` auf, um den Anweisungs-String `"SELECT ?"` vorzubereiten.

2. Sie rufen `mysql_stmt_bind_param()` auf, um den Wert `3` an den Parameter der vorbereiteten Anweisung zu binden.

3. Sie rufen `mysql_stmt_execute()` auf, um die vorbereitete Anweisung auszuführen.

Aufgrund dieser Funktionsaufrufe schreibt der Server folgende Zeilen in das allgemeine Anfragenlog:

    Prepare  [1] SELECT ?
    Execute  [1] SELECT 3

Jede `Prepare`- und `Execute`-Zeile im Log wird mit einem `[`N`]`-Anweisungsbezeichner markiert, damit Sie nachvollziehen können, welche vorbereitete Anweisung gerade protokolliert wird. `N` ist ein positiver Integer. Wenn mehrere vorbereitete Anweisungen zugleich für den Client aktiv sind, kann `N` größer als 1 sein. Jede `Execute`-Zeile zeigt eine vorbereitete Anweisung nach Einsetzung der Datenwerte in die `?`-Parameter an.

Versionshinweise: `Prepare`-Zeilen werden vor MySQL 4.1.10 ohne `[`N`]` angezeigt. `Execute`-Zeilen werden vor MySQL 4.1.10 überhaupt nicht angezeigt.

### 24.2.7. C-API Prepared Statements: Funktionsbeschreibungen

Um Anfragen vorzubereiten und auszuführen, verwenden Sie die Funktionen, die in den folgenden Abschnitten genauer beschrieben werden.

Beachten Sie, dass alle Funktionen, die mit der `MYSQL_STMT`-Struktur arbeiten, mit dem Präfix `mysql_stmt_` anfangen.

Um einen `MYSQL_STMT`-Handle anzulegen, verwenden Sie die `mysql_stmt_init()`-Funktion.

#### 24.2.7.1. `mysql_stmt_affected_rows()`

`my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt)`

Beschreibung

Diese Funktion gibt die Gesamtzahl der von der zuletzt ausgeführten Anweisung geänderten, gelöschten oder eingefügten Zeilen zurück. Für `UPDATE`-, `DELETE`- oder `INSERT`-Anweisungen kann sie unmittelbar nach `mysql_stmt_execute()` aufgerufen werden. Für `SELECT`-Anweisungen arbeitet `mysql_stmt_affected_rows()` genau wie `mysql_num_rows()`.

Rückgabewerte

Ein Integer größer null zeigt die Anzahl der betroffenen oder abgerufenen Zeilen an. Null zeigt für eine `UPDATE`-Anweisung an, dass keine Zeilen aktualisiert wurden, für eine `WHERE`-Klausel in der Anfrage, dass keine Zeilen gepasst haben, oder ansonsten, dass die Anfrage noch gar nicht ausgeführt wurde. -1 bedeutet, dass die Anfrage einen Fehler zurückgeliefert hat oder, bei einer `SELECT`-Anfrage, dass `mysql_stmt_affected_rows()` vor `mysql_stmt_store_result()` aufgerufen wurde. Da `mysql_stmt_affected_rows()` einen vorzeichenlosen Wert liefert, können Sie -1 überprüfen, indem Sie den Rückgabewert mit `(my_ulonglong)-1` (oder dem Äquivalent `(my_ulonglong)~0`) vergleichen.

Weitere Informationen über den Rückgabewert finden Sie unter Abschnitt 24.2.3.1, „`mysql_affected_rows()`“.

Fehler

Keine.

Beispiel

Ein Anwendungsbeispiel für `mysql_stmt_affected_rows()` finden Sie im Beispiel von Abschnitt 24.2.7.10, „`mysql_stmt_execute()`“.

#### 24.2.7.2. `mysql_stmt_attr_get()`

`int mysql_stmt_attr_get(MYSQL_STMT *stmt, enum enum_stmt_attr_type option, void *arg)`

Beschreibung

Kann genutzt werden, um den aktuellen Wert eines Anweisungsattributs abzufragen.

Das `option`-Argument ist die abzufragende Option; das `arg` sollte auf eine Variable mit dem Optionswert verweisen. Wenn die Option ein Integer ist, sollte `arg` auf den Wert dieses Integers verweisen.

Eine Liste aller Optionen und Optionstypen finden Sie unter Abschnitt 24.2.7.3, „`mysql_stmt_attr_set()`“.

Rückgabewerte

`0`, wenn alles okay ist. Ein von null verschiedener Wert, wenn `option` unbekannt ist.

Fehler

Keine.

#### 24.2.7.3. `mysql_stmt_attr_set()`

`int mysql_stmt_attr_set(MYSQL_STMT *stmt, enum enum_stmt_attr_type option, const void *arg)`

Beschreibung

Kann genutzt werden, um das Verhalten einer vorbereiteten Anweisung zu beeinflussen. Diese Funktion kann auch mehrmals aufgerufen werden, um mehrere Optionen zu setzen.

Das `option`-Argument ist die Option, die Sie einstellen möchten, und `arg` ist ihr Wert. Wenn die Option ein Integer ist, muss `arg` auf den Wert eines Integers verweisen.

Mögliche `option`-Werte:

Option | Argumenttyp | Funktion
`STMT_ATTR_UPDATE_MAX_LENGTH` | `my_bool *` | Wenn 1: Metadaten zum Update `MYSQL_FIELD->max_length` in `mysql_stmt_store_result()`.
`STMT_ATTR_CURSOR_TYPE` | `unsigned long *` | Typ des Cursors, der bei Aufruf von `mysql_stmt_execute()` für die Anweisung geöffnet wird. `*arg` kann `CURSOR_TYPE_NO_CURSOR` (Standardwert) oder `CURSOR_TYPE_READ_ONLY` sein.
`STMT_ATTR_PREFETCH_ROWS` | `unsigned long *` | Anzahl der Zeilen, die mit einem Cursor gleichzeitig vom Server geholt werden. `*arg` liegt zwischen 1 und dem Maximalwert von `unsigned long`. Der Standardwert ist 1.

Wenn Sie die Option `STMT_ATTR_CURSOR_TYPE` mit `CURSOR_TYPE_READ_ONLY` verwenden, wird ein Cursor für die Anweisung geöffnet, sobald Sie `mysql_stmt_execute()` aufrufen. Existiert bereits ein geöffneter Cursor aus einem früheren `mysql_stmt_execute()`-Aufruf, schließt die Option diesen Cursor, bevor ein neuer geöffnet wird. Die Funktion `mysql_stmt_reset()` schließt auch offene Cursors, bevor sie die Anweisung zur erneuten Ausführung vorbereitet. `mysql_stmt_free_result()` schließt ebenfalls einen eventuell noch offenen Cursor.

Wenn Sie einen Cursor für eine vorbereitete Anweisung öffnen, ist `mysql_stmt_store_result()` überflüssig, da diese Funktion die Ergebnismenge auf der Clientseite puffern lässt.

Die Option `STMT_ATTR_CURSOR_TYPE` wurde in MySQL 5.0.2 hinzugefügt. Die Option `STMT_ATTR_PREFETCH_ROWS` wurde in MySQL 5.0.6 hinzugefügt.

Rückgabewerte

`0`, wenn alles okay ist. Ein von null verschiedener Wert, wenn `option` unbekannt ist.

Fehler

Keine.

Beispiel

Das folgende Beispiel öffnet einen Cursor für eine vorbereitete Anweisung und setzt die Anzahl der in einem Schwung abzuholenden Zeilen auf 5:

    MYSQL_STMT *stmt;
    int rc;
    unsigned long type;
    unsigned long prefetch_rows = 5;

    stmt = mysql_stmt_init(mysql);
    type = (unsigned long) CURSOR_TYPE_READ_ONLY;
    rc = mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
    /* ... prüfe Rückgabewert... */
    rc = mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS,
                             (void*) &prefetch_rows);
      /* ... prüfe Rückgabewert ... */

#### 24.2.7.4. `mysql_stmt_bind_param()`

`my_bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)`

Beschreibung

Die Funktion `mysql_stmt_bind_param()` bindet Daten an die Parametermarker in der SQL-Anweisung, die an `mysql_stmt_prepare()` übergeben wurde. Zur Übergabe der Daten verwendet sie `MYSQL_BIND`-Strukturen. `bind` ist die Adresse eines Arrays von `MYSQL_BIND`-Strukturen. Die Clientbibliothek erwartet, dass das Array für jeden ‘`?`’-Parametermarker in der Anfrage einen Wert enthält.

Angenommen, Sie bereiten folgende Anweisung vor:

    INSERT INTO mytbl VALUES(?,?,?)

Wenn Sie die Parameter binden, muss das Array von `MYSQL_BIND`-Strukturen drei Elemente enthalten. Es kann wie folgt deklariert werden:

    MYSQL_BIND bind[3];

Die Bestandteile jedes `MYSQL_BIND`-Elements, das gesetzt werden muss, sind in Abschnitt 24.2.5, „C-API: Prepared Statement-Datentypen“, beschrieben.

Rückgabewerte

Null, wenn das Binden erfolgreich verlief. Ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_INVALID_BUFFER_USE`

  Zeigt an, ob lange Daten beim Binden stückweise an einen Puffer übergeben werden, der kein String- oder Binärpuffer ist.

- `CR_UNSUPPORTED_PARAM_TYPE`

  Die Konvertierung wird nicht unterstützt. Eventuell ist der `buffer_type`-Wert unzulässig oder hat keinen der unterstützten Typen.

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

Beispiel

Wie man `mysql_stmt_bind_param()` verwendet, sehen Sie im Beispiel von Abschnitt 24.2.7.10, „`mysql_stmt_execute()`“.

#### 24.2.7.5. `mysql_stmt_bind_result()`

`my_bool mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)`

Beschreibung

`mysql_stmt_bind_result()` bindet Spalten der Ergebnismenge an Daten- und Längenpuffer. Wenn Daten mit `mysql_stmt_fetch()` abgeholt werden, setzt das MySQL-Client/Server-Protokoll die Daten für gebundene Spalten in die angegebenen Puffer ein.

Alle Spalten müssen an ihre Puffer gebunden sein, bevor `mysql_stmt_fetch()` aufgerufen wird. `bind` ist die Adresse eines Arrays von `MYSQL_BIND`-Strukturen. Die Clientbibliothek erwartet, dass dieses Array für jede Spalte der Ergebnismenge ein Element enthält. Wenn Sie es versäumen, Spalten an `MYSQL_BIND`-Strukturen zu binden, ignoriert `mysql_stmt_fetch()` einfach den Datenabruf. Die Puffer sollten groß genug sein, um die Datenwerte speichern zu können, da dieses Protokoll die Daten nicht stückweise zurückgeben kann.

Eine Spalte kann jederzeit gebunden oder neu gebunden werden, auch dann, wenn eine Ergebnismenge teilweise abgeholt wurde. Die neue Bindung tritt beim nächsten Aufruf von `mysql_stmt_fetch()` in Kraft. Nehmen wir an, eine Anwendung bindet die Spalten in einer Ergebnismenge und ruft `mysql_stmt_fetch()` auf. Das Client/Server-Protokoll liefert die Daten in die gebundenen Puffer. Wenn die Anwendung nun aber die Spalten an andere Puffer bindet, schreibt das Protokoll die Daten erst beim nächsten Aufruf von `mysql_stmt_fetch()` in diese anderen Puffer.

Um eine Spalte zu binden, ruft eine Anwendung `mysql_stmt_bind_result()` auf und übergibt den Typ, die Adresse und die Adresse des Längenpuffers. Die Bestandteile der `MYSQL_BIND`-Elemente sollten so eingestellt werden wie in Abschnitt 24.2.5, „C-API: Prepared Statement-Datentypen“, beschrieben.

Rückgabewerte

Null, wenn das Binden erfolgreich verlief. Ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_UNSUPPORTED_PARAM_TYPE`

  Die Konvertierung wird nicht unterstützt. Möglicherweise ist der `buffer_type`-Wert unzulässig oder hat keinen Typ, der unterstützt wird.

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

Beispiel

Die Verwendung von `mysql_stmt_bind_result()` wird im Beispiel von Abschnitt 24.2.7.11, „`mysql_stmt_fetch()`“, gezeigt.

#### 24.2.7.6. `mysql_stmt_close()`

`my_bool mysql_stmt_close(MYSQL_STMT *)`

Beschreibung

Schließt die vorbereitete Anweisung. Außerdem gibt `mysql_stmt_close()` den Anweisungs-Handle von `stmt` frei.

Wenn die aktuelle Anweisung noch ausstehende oder ungelesene Ergebnisse hat, werden sie durch diese Funktion annulliert, damit die nächste Anfrage ausgeführt werden kann.

Rückgabewerte

Null, wenn die Anweisung erfolgreich freigegeben wurde. Ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

Beispiel

Die Anwendung von `mysql_stmt_close()` sehen Sie im Beispiel zu Abschnitt 24.2.7.10, „`mysql_stmt_execute()`“.

#### 24.2.7.7. `mysql_stmt_data_seek()`

`void mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset)`

Beschreibung

Findet eine beliebige Zeile in einer Ergebnismenge einer Anweisung. Der `offset`-Wert ist eine Zeilennummer zwischen `0` und `mysql_stmt_num_rows(stmt)-1`.

Für diese Funktion ist erforderlich, dass die Ergebnismengenstruktur der Anweisung das gesamte Ergebnis der zuletzt ausgeführten Anfrage enthält. Daher kann `mysql_stmt_data_seek()` nur in Verbindung mit `mysql_stmt_store_result()` eingesetzt werden.

Rückgabewerte

Keine.

Fehler

Keine.

#### 24.2.7.8. `mysql_stmt_errno()`

`unsigned int mysql_stmt_errno(MYSQL_STMT *stmt)`

Beschreibung

Für die durch `stmt` spezifizierte Anweisung liefert `mysql_stmt_errno()` den Fehlercode der zuletzt aufgerufenen Anweisungs-API-Funktion, die erfolgreich laufen oder scheitern kann. Null wird zurückgegeben, wenn kein Fehler auftrat. Die Nummern der Clientfehlermeldungen sind in der MySQL-Header-Datei `errmsg.h` aufgeführt. Die Nummern der Serverfehlermeldungen finden Sie in `mysqld_error.h`. Außerdem sind die Fehler in Anhang B, Fehlercodes und -meldungen, aufgelistet.

Rückgabewerte

Der Wert eines Fehlercodes. Null, wenn kein Fehler auftrat.

Fehler

Keine.

#### 24.2.7.9. `mysql_stmt_error()`

`const char *mysql_stmt_error(MYSQL_STMT *stmt)`

Beschreibung

Für die durch `stmt` spezifizierte Anweisung liefert `mysql_stmt_error()` einen auf null endenden String mit der Fehlermeldung für die zuletzt aufgerufene Anweisungs-API-Funktion, die erfolgreich laufen oder scheitern kann. Ein leerer String (`""`) wird zurückgegeben, wenn kein Fehler auftrat. Das bedeutet, dass die beiden folgenden Tests äquivalent sind:

    if (mysql_stmt_errno(stmt))
    {
      // Ein Fehler trat auf
    }

    if (mysql_stmt_error(stmt)[0])
    {
      // Ein Fehler trat auf
    }

Die Sprache der Clientfehlermeldungen kann sich durch Rekompilieren der MySQL-Clientbibliothek ändern. Zurzeit haben Sie die Wahl zwischen Fehlermeldungen in mehreren verschiedenen Sprachen.

Rückgabewerte

Ein Zeichen-String, der den Fehler beschreibt. Ein leerer String, wenn kein Fehler auftrat.

Fehler

Keine.

#### 24.2.7.10. `mysql_stmt_execute()`

`int mysql_stmt_execute(MYSQL_STMT *stmt)`

Beschreibung

`mysql_stmt_execute()` führt die vorbereitete Anfrage aus, die zu dem Anweisungs-Handle gehört. Die aktuellen Werte der gebundenen Parametermarker werden bei diesem Aufruf an den Server geschickt, und der Server ersetzt die Marker durch die frisch gelieferten Daten.

Wenn die Anweisung ein `UPDATE`, `DELETE` oder `INSERT` ist, erfahren Sie durch einen Aufruf von `mysql_stmt_affected_rows()`, wie viele Zeilen geändert, gelöscht oder eingefügt wurden. Ist es eine Anweisung wie `SELECT`, die eine Ergebnismenge generiert, müssen Sie zuerst mit `mysql_stmt_fetch()` die Daten abholen, bevor Sie irgendwelche Funktionen aufrufen, um die Anfrage zu verarbeiten. Weitere Informationen über den Abruf von Ergebnissen finden Sie in Abschnitt 24.2.7.11, „`mysql_stmt_fetch()`“.

Für Anweisungen, die eine Ergebnismenge generieren, können Sie verlangen, dass `mysql_stmt_execute()` einen Cursor öffnet, indem Sie vor Ausführung der Anweisung `mysql_stmt_attr_set()` aufrufen. Wenn Sie eine Anweisung mehrmals ausführen, schließt `mysql_stmt_execute()` einen eventuell noch offenen Cursor, ehe es einen neuen öffnet.

Rückgabewerte

Null, wenn die Ausführung Erfolg hatte. Ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

Beispiel

Das folgende Beispiel zeigt, wie eine Tabelle mithilfe von `mysql_stmt_init()`, `mysql_stmt_prepare()`, `mysql_stmt_param_count()`, `mysql_stmt_bind_param()`, `mysql_stmt_execute()` und `mysql_stmt_affected_rows()` angelegt und mit Daten gefüllt wird. Die `mysql`-Variable sei ein gültiger Verbindungs-Handle.

    #define STRING_SIZE 50

    #define DROP_SAMPLE_TABLE "DROP TABLE IF EXISTS test_table"
    #define CREATE_SAMPLE_TABLE "CREATE TABLE test_table(col1 INT,\
                                                     col2 VARCHAR(40),\
                                                     col3 SMALLINT,\
                                                     col4 TIMESTAMP)"
    #define INSERT_SAMPLE "INSERT INTO test_table(col1,col2,col3) VALUES(?,?,?)"

    MYSQL_STMT    *stmt;
    MYSQL_BIND    bind[3];
    my_ulonglong  affected_rows;
    int           param_count;
    short         small_data;
    int           int_data;
    char          str_data[STRING_SIZE];
    unsigned long str_length;
    my_bool       is_null;

    if (mysql_query(mysql, DROP_SAMPLE_TABLE))
    {
      fprintf(stderr, " DROP TABLE failed\n");
      fprintf(stderr, " %s\n", mysql_error(mysql));
      exit(0);
    }

    if (mysql_query(mysql, CREATE_SAMPLE_TABLE))
    {
      fprintf(stderr, " CREATE TABLE failed\n");
      fprintf(stderr, " %s\n", mysql_error(mysql));
      exit(0);
    }

    /* Bereite eine INSERT-Anfrage mit 3 Parametern vor */
    /* (Die TIMESTAMP-Spalte ist nicht benannt; der Server */
    /*  stellt sie auf das aktuelle Datum und die Uhrzeit ein.) */
    stmt = mysql_stmt_init(mysql);
    if (!stmt)
    {
      fprintf(stderr, " mysql_stmt_init(), out of memory\n");
      exit(0);
    }
    if (mysql_stmt_prepare(stmt, INSERT_SAMPLE, strlen(INSERT_SAMPLE)))
    {
      fprintf(stderr, " mysql_stmt_prepare(), INSERT failed\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(0);
    }
    fprintf(stdout, " prepare, INSERT successful\n");

    /* Hole die Zahl der Parameter aus der Anweisung */
    param_count= mysql_stmt_param_count(stmt);
    fprintf(stdout, " total parameters in INSERT: %d\n", param_count);

    if (param_count != 3) /* Validiere Parameterzahl */
    {
      fprintf(stderr, " invalid parameter count returned by MySQL\n");
      exit(0);
    }

    /* Binde die Daten für alle 3 Parameter */

    memset(bind, 0, sizeof(bind));

    /* INTEGER PARAM */
    /* Da dies ein Zahlentyp ist, muss buffer_length nicht angegeben werden */
    bind[0].buffer_type= MYSQL_TYPE_LONG;
    bind[0].buffer= (char *)&int_data;
    bind[0].is_null= 0;
    bind[0].length= 0;

    /* STRING PARAM */
    bind[1].buffer_type= MYSQL_TYPE_STRING;
    bind[1].buffer= (char *)str_data;
    bind[1].buffer_length= STRING_SIZE;
    bind[1].is_null= 0;
    bind[1].length= &str_length;

    /* SMALLINT PARAM */
    bind[2].buffer_type= MYSQL_TYPE_SHORT;
    bind[2].buffer= (char *)&small_data;
    bind[2].is_null= &is_null;
    bind[2].length= 0;

    /* Binde die Puffer */
    if (mysql_stmt_bind_param(stmt, bind))
    {
      fprintf(stderr, " mysql_stmt_bind_param() failed\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(0);
    }

    /* Gib Datenwerte für die erste Zeile an */
    int_data= 10;             /* Integer */
    strncpy(str_data, "MySQL", STRING_SIZE); /* String  */
    str_length= strlen(str_data);

    /* INSERT SMALLINT-Daten als NULL */
    is_null= 1;

    /* Führe die INSERT-Anweisung aus - 1*/
    if (mysql_stmt_execute(stmt))
    {
      fprintf(stderr, " mysql_stmt_execute(), 1 failed\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(0);
    }

    /* Hole Gesamtzahl der betroffenen Zeilen */
    affected_rows= mysql_stmt_affected_rows(stmt);
    fprintf(stdout, " total affected rows(insert 1): %lu\n",
                    (unsigned long) affected_rows);

    if (affected_rows != 1) /* validiere betroffene Zeilen */
    {
      fprintf(stderr, " invalid affected rows by MySQL\n");
      exit(0);
    }

    /* Gib Datenwerte für zweite Zeile an und führe Anweisung erneut aus */
    int_data= 1000;
    strncpy(str_data, "The most popular Open Source database", STRING_SIZE);
    str_length= strlen(str_data);
    small_data= 1000;         /* smallint */
    is_null= 0;               /* Zurücksetzen */

    /* Führe die INSERT-Anweisung aus - 2*/
    if (mysql_stmt_execute(stmt))
    {
      fprintf(stderr, " mysql_stmt_execute, 2 failed\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(0);
    }

      /* Hole Gesamtzahl der betroffenen Zeilen */
    affected_rows= mysql_stmt_affected_rows(stmt);
    fprintf(stdout, " total affected rows(insert 2): %lu\n",
                    (unsigned long) affected_rows);

      if (affected_rows != 1) /* validiere betroffene Zeilen */
    {
      fprintf(stderr, " invalid affected rows by MySQL\n");
      exit(0);
    }

    /* Schließe die Anweisung */
    if (mysql_stmt_close(stmt))
    {
      fprintf(stderr, " failed while closing the statement\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(0);
    }

Hinweis: Vollständigere Beispiele für die Nutzung von Funktionen für vorbereitete Anweisungen finden Sie in der Datei `tests/mysql_client_test.c`. Diese liegt in der MySQL-Quelldistribution und im BitKeeper-Quellarchiv.

#### 24.2.7.11. `mysql_stmt_fetch()`

`int mysql_stmt_fetch(MYSQL_STMT *stmt)`

Beschreibung

Die Funktion `mysql_stmt_fetch()` liefert die nächste Zeile der Ergebnismenge und kann nur aufgerufen werden, während die Ergebnismenge besteht, also nach einem `mysql_stmt_execute()`-Aufruf, der eine Ergebnismenge produziert, oder nach einem `mysql_stmt_store_result()`-Aufruf, der im Anschluss an `mysql_stmt_execute()` die gesamte Ergebnismenge puffert.

Die Funktion `mysql_stmt_fetch()` liefert Zeilendaten über alle Spalten der aktuellen Zeilenmenge an die in `mysql_stmt_bind_result()` gebundenen Puffer. Die Längen werden an den `length`-Zeiger zurückgegeben.

Alle Spalten müssen von der Anwendung gebunden werden, ehe `mysql_stmt_fetch()` aufgerufen werden kann.

Ist ein abgerufener Datenwert `NULL`, ist der `*is_null`-Wert der zugehörigen `MYSQL_BIND`-Struktur TRUE (1). Andernfalls werden die Daten und ihre Länge in die Elemente `*buffer` und `*length` zurückgegeben, und zwar basierend auf dem von der Anwendung angegebenen Puffertyp. Jeder numerische und temporale Typ hat eine festgelegte Länge, wie in der folgenden Tabelle angegeben. Die Länge von String-Typen hängt von der Länge des tatsächlichen Datenwerts ab, wie in `data_length` angegeben.

Typ | Länge
`MYSQL_TYPE_TINY` | 1
`MYSQL_TYPE_SHORT` | 2
`MYSQL_TYPE_LONG` | 4
`MYSQL_TYPE_LONGLONG` | 8
`MYSQL_TYPE_FLOAT` | 4
`MYSQL_TYPE_DOUBLE` | 8
`MYSQL_TYPE_TIME` | `sizeof(MYSQL_TIME)`
`MYSQL_TYPE_DATE` | `sizeof(MYSQL_TIME)`
`MYSQL_TYPE_DATETIME` | `sizeof(MYSQL_TIME)`
`MYSQL_TYPE_STRING` | `data_length`
`MYSQL_TYPE_BLOB` | `data_length`

Rückgabewerte

Rückgabewert | Beschreibung
0 | Erfolg, die Daten wurden in die Anwendungsdatenpuffer geladen.
1 | Fehler. Den Fehlercode und die Fehlermeldung erhalten Sie von `mysql_stmt_errno()` und `mysql_stmt_error()`.
`MYSQL_NO_DATA` | Keine weiteren Zeilen/Daten vorhanden.
`MYSQL_DATA_TRUNCATED` | Daten wurden abgeschnitten.

`MYSQL_DATA_TRUNCATED`-Meldungen werden nur zurückgegeben, wenn dies mit `mysql_options()` eingestellt wurde. Um bei einer Rückgabe dieses Werts festzustellen, welche Daten abgeschnitten wurden, schauen Sie sich die `error`-Bestandteile der `MYSQL_BIND`-Parameterstrukturen an.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

- `CR_UNSUPPORTED_PARAM_TYPE`

  Der Puffertyp ist `MYSQL_TYPE_DATE`, `MYSQL_TYPE_TIME`, `MYSQL_TYPE_DATETIME` oder `MYSQL_TYPE_TIMESTAMP`, aber der Datentyp ist nicht `DATE`, `TIME`, `DATETIME` oder `TIMESTAMP`.

- Alle anderen Fehler wegen nicht unterstützter Konvertierungen werden von `mysql_stmt_bind_result()` zurückgegeben.

Beispiel

Das folgende Beispiel zeigt, wie man Daten aus einer Tabelle mit `mysql_stmt_result_metadata()`, `mysql_stmt_bind_result()` und `mysql_stmt_fetch()` abholt. (Es wird erwartet, dass mit diesem Beispiel die beiden Zeilen abgerufen werden, die in Abschnitt 24.2.7.10, „`mysql_stmt_execute()`“, eingefügt wurden.) Die Variable `mysql` sei ein gültiger Verbindungs-Handle.

    #define STRING_SIZE 50

    #define SELECT_SAMPLE "SELECT col1, col2, col3, col4 FROM test_table"

    MYSQL_STMT    *stmt;
    MYSQL_BIND    bind[4];
    MYSQL_RES     *prepare_meta_result;
    MYSQL_TIME    ts;
    unsigned long length[4];
    int           param_count, column_count, row_count;
    short         small_data;
    int           int_data;
    char          str_data[STRING_SIZE];
    my_bool       is_null[4];

    /* SELECT-Anfrage vorbereiten, um Daten aus test_table zu holen*/
    stmt = mysql_stmt_init(mysql);
    if (!stmt)
    {
      fprintf(stderr, " mysql_stmt_init(), out of memory\n");
      exit(0);
    }
    if (mysql_stmt_prepare(stmt, SELECT_SAMPLE, strlen(SELECT_SAMPLE)))
    {
      fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(0);
    }
    fprintf(stdout, " prepare, SELECT successful\n");

    /* Hole Zahl der Parameter aus der Anweisung */
    param_count= mysql_stmt_param_count(stmt);
    fprintf(stdout, " total parameters in SELECT: %d\n", param_count);

    if (param_count != 0) /* validiere Zahl der Parameter */
    {
      fprintf(stderr, " invalid parameter count returned by MySQL\n");
      exit(0);
    }

    /* Hole Metainformationen zur Ergebnismenge */
    prepare_meta_result = mysql_stmt_result_metadata(stmt);
    if (!prepare_meta_result)
    {
      fprintf(stderr,
             " mysql_stmt_result_metadata(), returned no meta information\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(0);
    }

    /* Hole Gesamtzahl der Spalten in der Anfrage */
    column_count= mysql_num_fields(prepare_meta_result);
    fprintf(stdout, " total columns in SELECT statement: %d\n", column_count);

    if (column_count != 4) /* Validiere Spaltenzahl*/
    {
      fprintf(stderr, " invalid column count returned by MySQL\n");
      exit(0);
    }

    /* Führe die SELECT-Anfrage aus */
    if (mysql_stmt_execute(stmt))
    {
      fprintf(stderr, " mysql_stmt_execute(), failed\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(0);
    }

    /* Binde die Ergebnispuffer für alle 4 Spalten, bevor sie abgeholt werden */

    memset(bind, 0, sizeof(bind));

    /* INTEGER COLUMN */
    bind[0].buffer_type= MYSQL_TYPE_LONG;
    bind[0].buffer= (char *)&int_data;
    bind[0].is_null= &is_null[0];
    bind[0].length= &length[0];

    /* STRING COLUMN */
    bind[1].buffer_type= MYSQL_TYPE_STRING;
    bind[1].buffer= (char *)str_data;
    bind[1].buffer_length= STRING_SIZE;
    bind[1].is_null= &is_null[1];
    bind[1].length= &length[1];

    /* SMALLINT COLUMN */
    bind[2].buffer_type= MYSQL_TYPE_SHORT;
    bind[2].buffer= (char *)&small_data;
    bind[2].is_null= &is_null[2];
    bind[2].length= &length[2];

    /* TIMESTAMP COLUMN */
    bind[3].buffer_type= MYSQL_TYPE_TIMESTAMP;
    bind[3].buffer= (char *)&ts;
    bind[3].is_null= &is_null[3];
    bind[3].length= &length[3];

    /* Binde die Ergebnispuffer */
    if (mysql_stmt_bind_result(stmt, bind))
    {
      fprintf(stderr, " mysql_stmt_bind_result() failed\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(0);
    }

    /* Alle Ergebnisse auf dem Client zwischenspeichern */
    if (mysql_stmt_store_result(stmt))
    {
      fprintf(stderr, " mysql_stmt_store_result() failed\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(0);
    }

    /* Alle Zeilen abholen */
    row_count= 0;
    fprintf(stdout, "Fetching results ...\n");
    while (!mysql_stmt_fetch(stmt))
    {
      row_count++;
      fprintf(stdout, "  row %d\n", row_count);

      /* Spalte 1 */
      fprintf(stdout, "   column1 (integer)  : ");
      if (is_null[0])
        fprintf(stdout, " NULL\n");
      else
        fprintf(stdout, " %d(%ld)\n", int_data, length[0]);

      /* Spalte 2 */
      fprintf(stdout, "   column2 (string)   : ");
      if (is_null[1])
        fprintf(stdout, " NULL\n");
      else
        fprintf(stdout, " %s(%ld)\n", str_data, length[1]);

      /* Spalte 3 */
      fprintf(stdout, "   column3 (smallint) : ");
      if (is_null[2])
        fprintf(stdout, " NULL\n");
      else
        fprintf(stdout, " %d(%ld)\n", small_data, length[2]);

      /* Spalte 4 */
      fprintf(stdout, "   column4 (timestamp): ");
      if (is_null[3])
        fprintf(stdout, " NULL\n");
      else
        fprintf(stdout, " %04d-%02d-%02d %02d:%02d:%02d (%ld)\n",
                         ts.year, ts.month, ts.day,
                         ts.hour, ts.minute, ts.second,
                         length[3]);
      fprintf(stdout, "\n");
    }

    /* Abgeholte Zeilen validieren */
    fprintf(stdout, " total rows fetched: %d\n", row_count);
    if (row_count != 2)
    {
      fprintf(stderr, " MySQL failed to return all rows\n");
      exit(0);
    }

    /* Vorbereitete Ergebnismetadaten freigeben */
    mysql_free_result(prepare_meta_result);

    /* Anweisung schließen */
    if (mysql_stmt_close(stmt))
    {
      fprintf(stderr, " failed while closing the statement\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(0);
    }

#### 24.2.7.12. `mysql_stmt_fetch_column()`

`int mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind, unsigned int column, unsigned long offset)`

Beschreibung

Holt eine Spalte aus der aktuellen Zeile der Ergebnismenge. `bind` sagt, in welchen Puffer die Daten geschrieben werden sollen. Dieser sollte wie für `mysql_stmt_bind_result()` eingestellt sein. `column` gibt an, welche Spalte abgefragt wird. Die erste Spalte hat die Nummer 0. `offset` ist der Offset im Datenwert, wo der Datenabruf beginnen soll. Dieser kann genutzt werden, um die Daten stückweise abzuholen. Der Anfang des Werts hat den Offset 0.

Rückgabewerte

Null, wenn der Wert erfolgreich abgeholt wurde. Ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_INVALID_PARAMETER_NO`

  Ungültige Spaltennummer.

- `CR_NO_DATA`

  Das Ende der Ergebnismenge wurde schon erreicht.

#### 24.2.7.13. `mysql_stmt_field_count()`

`unsigned int mysql_stmt_field_count(MYSQL_STMT *stmt)`

Beschreibung

Liefert die Anzahl der Spalten für die letzte Anweisung des Anweisungs-Handlers. Dieser Wert ist für Anweisungen wie `INSERT` oder `DELETE`, die keine Ergebnismengen produzieren, null.

`mysql_stmt_field_count()` kann nach der Vorbereitung einer Anweisung mit `mysql_stmt_prepare()` aufgerufen werden.

Rückgabewerte

Ein vorzeichenloser Integer, der die Anzahl der Spalten in einer Ergebnismenge angibt.

Fehler

Keine.

#### 24.2.7.14. `mysql_stmt_free_result()`

`my_bool mysql_stmt_free_result(MYSQL_STMT *stmt)`

Beschreibung

Gibt den Speicher für die Ergebnismenge frei, die von der Ausführung der vorbereiteten Anweisung erstellt wurde. Wenn noch ein Cursor für die Anweisung geöffnet ist, wird er von `mysql_stmt_free_result()` geschlossen.

Rückgabewerte

Null, wenn die Ergebnismenge erfolgreich freigegeben wurde, und ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

(nicht verfügbar)

#### 24.2.7.15. `mysql_stmt_init()`

`MYSQL_STMT *mysql_stmt_init(MYSQL *mysql)`

Beschreibung

Erzeugt einen `MYSQL_STMT`-Handle. Der Handle sollte mit `mysql_stmt_close(MYSQL_STMT *)` wieder freigegeben werden.

Rückgabewerte

Bei Erfolg ein Zeiger auf eine `MYSQL_STMT`-Struktur. Bei einem Speicherüberlauf `NULL`.

Fehler

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

#### 24.2.7.16. `mysql_stmt_insert_id()`

`my_ulonglong mysql_stmt_insert_id(MYSQL_STMT *stmt)`

Beschreibung

Gibt den Wert zurück, der für eine `AUTO_INCREMENT`-Spalte von der vorbereiteten `INSERT`- oder `UPDATE`-Anweisung generiert wurde. Diese Funktion verwenden Sie nach Ausführung einer vorbereiteten `INSERT`-Anweisung auf einer Tabelle, die ein `AUTO_INCREMENT`-Feld enthält.

Siehe auch Abschnitt 24.2.3.36, „`mysql_insert_id()`“.

Rückgabewerte

Der Wert der `AUTO_INCREMENT`-Spalte, der automatisch generiert oder während der Ausführung einer vorbereiteten Anweisung explizit gesetzt wurde, oder der Wert, der von der Funktion `LAST_INSERT_ID(`expr`)` generiert wurde. Wenn die Anweisung keinen `AUTO_INCREMENT`-Wert setzt, ist der Rückgabewert undefiniert.

Fehler

Keine.

#### 24.2.7.17. `mysql_stmt_num_rows()`

`my_ulonglong mysql_stmt_num_rows(MYSQL_STMT *stmt)`

Beschreibung

Liefert die Anzahl der Zeilen in der Ergebnismenge.

`mysql_stmt_num_rows()` können Sie nur benutzen, wenn Sie die gesamte Ergebnismenge im Anweisungs-Handle mit `mysql_stmt_store_result()` gepuffert haben.

Wenn Sie `mysql_stmt_store_result()` verwenden, können Sie `mysql_stmt_num_rows()` sofort aufrufen.

Rückgabewerte

Die Anzahl der Zeilen in der Ergebnismenge.

Fehler

Keine.

#### 24.2.7.18. `mysql_stmt_param_count()`

`unsigned long mysql_stmt_param_count(MYSQL_STMT *stmt)`

Beschreibung

Liefert die Anzahl der Parametermarker in der vorbereiteten Anweisung.

Rückgabewerte

Ein vorzeichenloser Long-Integer, der die Anzahl der Parameter in einer Anweisung darstellt.

Fehler

Keine.

Beispiel

Wie man `mysql_stmt_param_count()` einsetzt, sehen Sie im Beispiel zu Abschnitt 24.2.7.10, „`mysql_stmt_execute()`“.

#### 24.2.7.19. `mysql_stmt_param_metadata()`

`MYSQL_RES *mysql_stmt_param_metadata(MYSQL_STMT *stmt)`

Diese Funktion tut zurzeit gar nichts.

Beschreibung

Rückgabewerte

Fehler

#### 24.2.7.20. `mysql_stmt_prepare()`

`int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned long length)`

Beschreibung

Wenn man ihr den von `mysql_stmt_init()` gelieferten Anweisungs-Handle übergibt, bereitet diese Funktion die SQL-Anweisung vor, auf die der String `query` verweist, und liefert einen Statuswert. Die Länge des Strings sollte im `length`-Argument angegeben werden. Der String muss aus einer einzigen SQL-Anweisung bestehen. Bitte fügen Sie am Ende der Anweisung kein Semikolon (‘`;`’) oder `\g` an.

Die Anwendung kann einen oder mehrere Parametermarker in die SQL-Anweisung einbinden, indem sie die Fragezeichen (‘`?`’) an den passenden Stellen in den SQL-String einbettet.

Die Marker sind nur an bestimmten Stellen in den SQL-Anweisungen erlaubt, beispielsweise in der `VALUES()`-Liste einer `INSERT` Anweisung (um Spaltenwerte für eine Zeile vorzugeben) oder um einen Vergleichswert zum Vergleich mit einer Spalte einer `WHERE`-Klausel anzugeben. Sie dürfen jedoch nicht für Bezeichner (wie etwa Tabellen- oder Spaltennamen) oder für die Operanden eines Binäroperators wie etwa des Gleichheitszeichens `=` benutzt werden. Die zweite Beschränkung ist notwendig, weil es ansonsten unmöglich wäre, den Parametertyp festzustellen. Generell sind Parameter nur in Data Manipulation Language(DML)-Anweisungen und nicht in Data Definition Language(DDL)-Anweisungen zulässig.

Die Parametermarker müssen mit `mysql_stmt_bind_param()` an die Anwendungsvariablen gebunden werden, bevor die Anweisung ausgeführt wird.

Rückgabewerte

Null, wenn die Anweisung erfolgreich vorbereitet wurde, und ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

Wenn die Vorbereitung gescheitert ist (d. h., wenn `mysql_stmt_prepare()` nicht null zurückliefert), können Sie die Fehlermeldung mit `mysql_stmt_error()` abrufen.

Beispiel

Wie `mysql_stmt_prepare()` eingesetzt wird, erfahren Sie im Beispiel von Abschnitt 24.2.7.10, „`mysql_stmt_execute()`“.

#### 24.2.7.21. `mysql_stmt_reset()`

`my_bool mysql_stmt_reset(MYSQL_STMT *stmt)`

Beschreibung

Setzt die vorbereitete Anweisung auf dem Client und Server in den Zustand zurück, den sie nach der Vorbereitung hatte. Wird vor allen Dingen genutzt, um die mit `mysql_stmt_send_long_data()` übersandten Daten zurückzusetzen und eventuell noch offene Anweisungs-Cursors zu schließen.

Um die Anweisung mit einer anderen Anfrage erneut vorzubereiten, rufen Sie `mysql_stmt_prepare()` auf.

Rückgabewerte

Null, wenn die Anweisung erfolgreich zurückgesetzt wurde, und ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

#### 24.2.7.22. `mysql_stmt_result_metadata()`

`MYSQL_RES *mysql_stmt_result_metadata(MYSQL_STMT *stmt)`

Beschreibung

Wenn an `mysql_stmt_prepare()` eine Anweisung übergeben wird, die eine Ergebnismenge produziert, liefert `mysql_stmt_result_metadata()` die Metadaten zu dieser Ergebnismenge in Form eines Zeigers auf eine `MYSQL_RES`-Struktur, die genutzt werden kann, um solche Daten wie etwa die Gesamtzahl der Felder und Informationen über einzelne Felder zu verarbeiten. Dieser Ergebnismengenzeiger kann als Argument an API-Feldfunktionen übergeben werden, die Metadaten von Ergebnismengen verarbeiten, wie zum Beispiel:

- `mysql_num_fields()`

- `mysql_fetch_field()`

- `mysql_fetch_field_direct()`

- `mysql_fetch_fields()`

- `mysql_field_count()`

- `mysql_field_seek()`

- `mysql_field_tell()`

- `mysql_free_result()`

Die Ergebnismengenstruktur sollte nach Abschluss der Verarbeitung freigegeben werden, indem man sie an `mysql_free_result()` übergibt. Auf dieselbe Weise wird eine Ergebnismenge aus einem `mysql_store_result()`-Aufruf freigegeben.

Die von `mysql_stmt_result_metadata()` zurückgegebene Ergebnismenge enthält nur Metadaten und keine Ergebniszeilen. Diese rufen Sie ab, indem Sie den Anweisungs-Handle in Verbindung mit `mysql_stmt_fetch()` benutzen.

Rückgabewerte

Eine `MYSQL_RES`-Ergebnisstruktur oder `NULL`, wenn keine Metainformationen über die vorbereitete Anfrage existieren.

Fehler

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

Beispiel

Die Benutzung von `mysql_stmt_result_metadata()` wird aus dem Beispiel von Abschnitt 24.2.7.11, „`mysql_stmt_fetch()`“, ersichtlich.

#### 24.2.7.23. `mysql_stmt_row_seek()`

`MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET offset)`

Beschreibung

Setzt den Zeilen-Cursor auf eine beliebige Zeile in der Ergebnismenge einer Anweisung. Der `offset`-Wert ist ein Zeilen-Offset. Dieser sollte ein Rückgabewert von `mysql_stmt_row_tell()` oder von `mysql_stmt_row_seek()` sein. Er ist keine Zeilennummer; wenn Sie in einer Ergebnismenge eine Zeile anhand ihrer Nummer ausfindig machen möchten, verwenden Sie stattdessen `mysql_stmt_data_seek()`.

Da für diese Funktion erforderlich ist, dass die Ergebnismengenstruktur die gesamte Ergebnismenge der Anfrage enthält, kann `mysql_stmt_row_seek()` nur in Verbindung mit `mysql_stmt_store_result()` benutzt werden.

Rückgabewerte

Der vorherige Wert des Zeilen-Cursors. Dieser Wert kann an einen nachfolgenden `mysql_stmt_row_seek()`-Aufruf übergeben werden.

Fehler

Keine.

#### 24.2.7.24. `mysql_stmt_row_tell()`

`MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT *stmt)`

Beschreibung

Gibt die aktuelle Position des Zeilen-Cursors für die letzte `mysql_stmt_fetch()`-Operation zurück. Dieser Wert kann als Argument für `mysql_stmt_row_seek()` verwendet werden.

`mysql_stmt_row_tell()` sollte nur nach `mysql_stmt_store_result()` benutzt werden.

Rückgabewerte

Der aktuelle Offset des Zeilen-Cursors.

Fehler

Keine.

#### 24.2.7.25. `mysql_stmt_send_long_data()`

`my_bool mysql_stmt_send_long_data(MYSQL_STMT *stmt, unsigned int parameter_number, const char *data, unsigned long length)`

Beschreibung

Ermöglicht es einer Anwendung, Parameterdaten in Stücken (oder „Chunks“) an den Server zu schicken. Diese Funktion kann mehrmals aufgerufen werden, um die Teile eines Zeichen- oder Binärdatenwerts für eine Spalte zu übergeben. Die Werte müssen den Datentyp `TEXT` oder `BLOB` haben.

`parameter_number` gibt an, mit welchem Parameter die Daten verbunden werden sollen. Die Parameter werden beginnend mit 0 nummeriert. `data` ist ein Zeiger auf einen Puffer, der die zu übermittelnden Daten enthält, und `length` ist die Anzahl der Bytes im Puffer.

Hinweis: Der nächste Aufruf von `mysql_stmt_execute()` ignoriert den Bind-Puffer für alle Parameter, die seit dem letzten `mysql_stmt_execute()` oder `mysql_stmt_reset()` mit `mysql_stmt_send_long_data()` benutzt worden sind.

Wenn Sie die gesendeten Daten zurücksetzen/vergessen möchten, tun Sie dies mit `mysql_stmt_reset()`. Siehe Abschnitt 24.2.7.21, „`mysql_stmt_reset()`“.

Rückgabewerte

Null, wenn die Daten erfolgreich an den Server gesandt wurden. Ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

Beispiel

Das folgende Beispiel zeigt, wie die Daten für eine `TEXT`-Spalte stückchenweise übermittelt werden. Es fügt den Datenwert `'MySQL - The most popular Open Source database'` in die Spalte `text_column` ein. Die Variable `mysql` sei ein gültiger Verbindungs-Handle.

    #define INSERT_QUERY "INSERT INTO test_long_data(text_column) VALUES(?)"

    MYSQL_BIND bind[1];
    long       length;

    smtt = mysql_stmt_init(mysql);
    if (!stmt)
    {
      fprintf(stderr, " mysql_stmt_init(), out of memory\n");
      exit(0);
    }
    if (mysql_stmt_prepare(stmt, INSERT_QUERY, strlen(INSERT_QUERY)))
    {
      fprintf(stderr, "\n mysql_stmt_prepare(), INSERT failed");
      fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
      exit(0);
    }
     memset(bind, 0, sizeof(bind));
     bind[0].buffer_type= MYSQL_TYPE_STRING;
     bind[0].length= &length;
     bind[0].is_null= 0;

    /* Binde die Puffer */
    if (mysql_stmt_bind_param(stmt, bind))
    {
      fprintf(stderr, "\n param bind failed");
      fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
      exit(0);
    }

     /* Liefere Daten stückweise an den Server */
     if (!mysql_stmt_send_long_data(stmt,0,"MySQL",5))
    {
      fprintf(stderr, "\n send_long_data failed");
      fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
      exit(0);
    }

     /* Sende das nächste Datenstück */
     if (mysql_stmt_send_long_data(stmt,0," - The most popular Open Source database",40))
    {
      fprintf(stderr, "\n send_long_data failed");
      fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
      exit(0);
    }

     /* Führe nun die Anfrage aus */
     if (mysql_stmt_execute(stmt))
    {
      fprintf(stderr, "\n mysql_stmt_execute failed");
      fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
      exit(0);
    }

#### 24.2.7.26. `mysql_stmt_sqlstate()`

`const char *mysql_stmt_sqlstate(MYSQL_STMT *stmt)`

Beschreibung

Für die Anweisung `stmt` liefert `mysql_stmt_sqlstate()` einen auf null endenden String mit dem SQLSTATE-Fehlercode für die zuletzt aufgerufene Funktion der API für vorbereitete Anweisungen, die Erfolg haben oder scheitern kann. Der Fehlercode besteht aus fünf Zeichen. `"00000"` bedeutet „kein Fehler“. Die Werte sind durch ANSI-SQL und ODBC vorgegeben. Eine Liste der möglichen Werte finden Sie unter Anhang B, Fehlercodes und -meldungen.

Beachten Sie, dass noch nicht alle MySQL-Fehler SQLSTATE-Codes zugeordnet sind. Für Fehler, die sich nicht zuordnen lassen, wird der Wert `"HY000"` (allgemeiner Fehler) verwendet.

Rückgabewerte

Ein auf null endender Zeichen-String, der den SQLSTATE-Fehlercode enthält.

#### 24.2.7.27. `mysql_stmt_store_result()`

`int mysql_stmt_store_result(MYSQL_STMT *stmt)`

Beschreibung

Sie können `mysql_stmt_store_result()` für jede Anweisung aufrufen, die eine Ergebnismenge erstellt (`SELECT`, `SHOW`, `DESCRIBE`, `EXPLAIN`), sofern Sie die gesamte Ergebnismenge im Client puffern wollen, damit der nachfolgende `mysql_stmt_fetch()`-Aufruf die gepufferten Daten zurückgibt.

Es ist zwar nicht nötig, `mysql_stmt_store_result()` für andere Anweisungen aufzurufen, aber es schadet auch nichts und hat keine spürbaren Leistungseinbußen zur Folge. Ob die Anweisung eine Ergebnismenge erzeugt hat, können Sie ermitteln, indem Sie nachschauen, ob `mysql_stmt_result_metadata()` den Wert `NULL` zurückgibt. Weitere Informationen gibt es unter Abschnitt 24.2.7.22, „`mysql_stmt_result_metadata()`“.

Hinweis: MySQL berechnet nach Voreinstellung nicht die `MYSQL_FIELD->max_length` für alle Spalten in `mysql_stmt_store_result()`, da dieser Rechenaufwand `mysql_stmt_store_result()` deutlich verlangsamen würde und die meisten Anwendungen auf `max_length` gut verzichten können. Wenn Sie `max_length` aktualisieren möchten, können Sie dies mit `mysql_stmt_attr_set(MYSQL_STMT, STMT_ATTR_UPDATE_MAX_LENGTH, &flag)` ermöglichen. Siehe Abschnitt 24.2.7.3, „`mysql_stmt_attr_set()`“.

Rückgabewerte

Null, wenn die Ergebnisse erfolgreich gepuffert wurden, und ein von null verschiedener Wert, wenn ein Fehler auftrat.

Fehler

- `CR_COMMANDS_OUT_OF_SYNC`

  Befehle wurden in der falschen Reihenfolge ausgeführt.

- `CR_OUT_OF_MEMORY`

  Speicherüberlauf.

- `CR_SERVER_GONE_ERROR`

  Der MySQL Server ist nicht mehr verfügbar.

- `CR_SERVER_LOST`

  Die Serververbindung brach während der Anfrage ab.

- `CR_UNKNOWN_ERROR`

  Ein unbekannter Fehler ist aufgetreten.

### 24.2.8. C-API: Probleme bei Prepared Statements

Im Folgenden werden einige bekannte Probleme mit vorbereiteten Anweisungen angesprochen:

- `TIME`, `TIMESTAMP` und `DATETIME` unterstützen keine Sekundenbruchteile (beispielsweise von `DATE_FORMAT()`.

- Beim Konvertieren eines Integers in einen String wird `ZEROFILL` in vorbereiteten Anweisungen in manchen Fällen umgesetzt, ohne dass der MySQL Server die vorangestellten Nullen ausgibt (beispielsweise bei `MIN(number-with-zerofill)`).

- Wird im Client eine Fließkommazahl in einen String konvertiert, können die rechten Ziffern des konvertierten Werts leicht vom Originalwert abweichen.

- Vorbereitete Anweisungen verwenden nicht den Query Cache, auch dann nicht, wenn eine Anfrage keine Platzhalter enthält. Siehe Abschnitt 5.14.1, „Wie der Anfragen-Cache funktioniert“.

### 24.2.9. C-API: Behandlung der Ausführung mehrerer Anweisungen

MySQL 5.1 unterstützt die Ausführung von Mehrfachanweisungen, die in einem einzigen Anfrage-String angegeben werden. Um diese Fähigkeit auf einer gegebenen Verbindung nutzen zu können, müssen Sie die Option `CLIENT_MULTI_STATEMENTS` im Parameter `flags` der Funktion `mysql_real_connect()` angeben, wenn Sie die Verbindung öffnen. Sie können dies jedoch mit `mysql_set_server_option(MYSQL_OPTION_MULTI_STATEMENTS_ON)` auch für eine laufende Verbindung tun.

Nach Voreinstellung geben `mysql_query()` und `mysql_real_query()` nur den ersten Anfragestatus zurück; der Status der nachfolgenden Anfragen kann mit `mysql_more_results()` und `mysql_next_result()` verarbeitet werden.

    /* Richte Serververbindung mit der Option CLIENT_MULTI_STATEMENTS ein */
    mysql_real_connect(..., CLIENT_MULTI_STATEMENTS);

    /* Führe mehrere Anfragen aus */
    mysql_query(mysql,"DROP TABLE IF EXISTS test_table;\
                       CREATE TABLE test_table(id INT);\
                       INSERT INTO test_table VALUES(10);\
                       UPDATE test_table SET id=20 WHERE id=10;\
                       SELECT * FROM test_table;\
                       DROP TABLE test_table");
    do
    {
      /* Verarbeite alle Ergebnisse */
      ...
      printf("total affected rows: %lld", mysql_affected_rows(mysql));
      ...
      if (!(result= mysql_store_result(mysql)))
      {
         printf(stderr, "Got fatal error processing query\n");
         exit(1);
      }
      process_result_set(result); /* Clientfunktion */
      mysql_free_result(result);
    } while (!mysql_next_result(mysql));

Die Fähigkeit zu Mehrfachanweisungen kann mit `mysql_query()` oder `mysql_real_query()` genutzt werden, aber nicht mit der Schnittstelle für vorbereitete Anweisungen. Handles für vorbereitete Anweisungen sind so definiert, dass sie nur mit Strings funktionieren, die lediglich eine einzelne Anweisung enthalten.

### 24.2.10. C-API: Behandlung von Datums- und Zeitwerten

Das Binärprotokoll ermöglicht das Senden und Empfangen von Datums- und Uhrzeitwerten (`DATE`, `TIME`, `DATETIME` und `TIMESTAMP`) mithilfe der `MYSQL_TIME`-Struktur. Die Bestandteile dieser Struktur werden in Abschnitt 24.2.5, „C-API: Prepared Statement-Datentypen“, beschrieben.

Um temporale Datenwerte zu senden, legen Sie eine vorbereitete Anweisung mit `mysql_stmt_prepare()` an und richten die Temporalparameter, bevor Sie die Anweisung mit `mysql_stmt_execute()` ausführen, folgendermaßen ein:

1. In der `MYSQL_BIND`-Struktur, die mit dem Datenwert verbunden ist, stellen Sie den `buffer_type`-Teil auf den Typ, der die Art des zu sendenden Temporalwerts angibt. Für `DATE`-, `TIME`-, `DATETIME`- oder `TIMESTAMP`-Werte setzen Sie `buffer_type` auf `MYSQL_TYPE_DATE`, `MYSQL_TYPE_TIME`, `MYSQL_TYPE_DATETIME` oder `MYSQL_TYPE_TIMESTAMP`.

2. Stellen Sie den `buffer`-Teil der `MYSQL_BIND`-Struktur auf die Adresse der `MYSQL_TIME`-Struktur ein, in die Sie den Temporalwert übergeben.

3. Füllen Sie die Bestandteile der `MYSQL_TIME`-Struktur aus, die sich für den Typ des zu übergebenden Temporalwerts eignen.

Binden Sie mit `mysql_stmt_bind_param()` die Parameterdaten an die Anweisung. Dann können Sie `mysql_stmt_execute()` aufrufen.

Abgerufen werden die Temporalwerte ganz ähnlich, nur dass Sie beim Abruf den `buffer_type`-Teil auf den Typ des Werts einstellen, den Sie empfangen wollen, und den `buffer`-Teil auf die Adresse einer `MYSQL_TIME`-Struktur, in die der Rückgabewert eingesetzt werden soll. Mit `mysql_bind_results()` binden Sie die Puffer an die Anweisung, nachdem Sie `mysql_stmt_execute()` aufgerufen haben und bevor Sie die Ergebnisse abholen.

Das folgende einfache Beispiel fügt `DATE`-, `TIME`- und `TIMESTAMP`-Daten ein. Die `mysql`-Variable sei ein gültiger Verbindungs-Handle.

      MYSQL_TIME  ts;
      MYSQL_BIND  bind[3];
      MYSQL_STMT  *stmt;

      strmov(query, "INSERT INTO test_table(date_field, time_field,
                                            timestamp_field) VALUES(?,?,?");

      stmt = mysql_stmt_init(mysql);
      if (!stmt)
      {
        fprintf(stderr, " mysql_stmt_init(), out of memory\n");
        exit(0);
      }
      if (mysql_stmt_prepare(mysql, query, strlen(query)))
      {
        fprintf(stderr, "\n mysql_stmt_prepare(), INSERT failed");
        fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
        exit(0);
      }

      /* Richte Eingabepuffer für alle 3 Parameter ein */
      bind[0].buffer_type= MYSQL_TYPE_DATE;
      bind[0].buffer= (char *)&ts;
      bind[0].is_null= 0;
      bind[0].length= 0;
      ...
      bind[1]= bind[2]= bind[0];
      ...

      mysql_stmt_bind_param(stmt, bind);

      /* Liefere die Daten für die ts-Struktur*/
      ts.year= 2002;
      ts.month= 02;
      ts.day= 03;

      ts.hour= 10;
      ts.minute= 45;
      ts.second= 20;

      mysql_stmt_execute(stmt);
      ..

### 24.2.11. C-Threaded-Funktionsbeschreibungen

Wenn Sie einen Threaded Client erstellen möchten, verwenden Sie folgende Funktionen. Siehe Abschnitt 24.2.15, „Wie man einen Thread-Client herstellt“.

#### 24.2.11.1. `my_init()`

`void my_init(void)`

Beschreibung

Diese Funktion muss einmalig vor dem Aufruf jeder anderen MySQL-Funktion in einem Programm aufgerufen werden. Sie initialisiert einige globale Variablen, die MySQL benötigt. Wenn Sie eine Thread-sichere Clientbibliothek benutzen, wird auch für diesen Thread `mysql_thread_init()` aufgerufen.

Diese Funktion wird automatisch von `mysql_init()`, `mysql_library_init()`, `mysql_server_init()` und `mysql_connect()` aufgerufen.

Rückgabewerte

Keine.

#### 24.2.11.2. `mysql_thread_init()`

`my_bool mysql_thread_init(void)`

Beschreibung

Diese Funktion muss für jeden erzeugten Thread aufgerufen werden, um Thread-spezifische Variablen zu initialisieren.

Die Funktion wird automatisch von `my_init()` und `mysql_connect()` aufgerufen.

Rückgabewerte

Null bei Erfolg und ein von null verschiedener Wert bei einem Fehler.

#### 24.2.11.3. `mysql_thread_end()`

`void mysql_thread_end(void)`

Beschreibung

Diese Funktion muss vor `pthread_exit()` benutzt werden, um den von `mysql_thread_init()` zugewiesenen Speicher wieder freizugeben.

Beachten Sie, dass diese Funktion nicht automatisch von der Clientbibliothek aufgerufen wird. Sie muss explizit aufgerufen werden, um ein Speicherleck zu verhindern.

Rückgabewerte

Keine.

#### 24.2.11.4. `mysql_thread_safe()`

`unsigned int mysql_thread_safe(void)`

Beschreibung

Diese Funktion zeigt an, ob der Client als Thread-sicher kompiliert wurde.

Rückgabewerte

1, wenn der Client Thread-sicher ist, andernfalls 0.

### 24.2.12. C Embedded Server: Funktionsbeschreibungen

Wenn Sie es Ihrer Anwendung ermöglichen wollen, mit der MySQL Embedded Server-Bibliothek verknüpft zu werden, müssen Sie die Funktionen `mysql_server_init()` und `mysql_server_end()` benutzen. Siehe Abschnitt 24.1, „libmysqld, die eingebettete MySQL Server-Bibliothek“.

Für eine bessere Speicherverwaltung sollten allerdings auch Programme, die mit `-lmysqlclient` statt `-lmysqld` verknüpft sind, Aufrufe enthalten, um die Benutzung der Bibliothek zu beginnen und zu beenden. Hierzu dienen die Funktionen `mysql_library_init()` und `mysql_library_end()`. Diese sind in Wirklichkeit `#define`-Symbole und somit äquivalent zu `mysql_server_init()` und `mysql_server_end()`, aber die anderen Namen betonen stärker, dass diese Funktionen immer vor und nach der Benutzung einer MySQL-C-API-Bibliothek aufgerufen werden müssen, egal ob die Anwendung `libmysqlclient` oder `libmysqld` verwendet. Weitere Informationen finden Sie unter Abschnitt 24.2.2, „C-API: Funktionsüberblick“.

#### 24.2.12.1. `mysql_server_init()`

`int mysql_server_init(int argc, char **argv, char **groups)`

Beschreibung

Diese Funktion muss in einem Programm, das den Embedded Server benutzt, einmalig vor jeder anderen MySQL-Funktion aufgerufen werden. Sie startet den Server und initialisiert eventuelle Subsysteme (`mysys`, `InnoDB` und so weiter), die der Server benötigt. Wird diese Funktion nicht aufgerufen, führt der nächste `mysql_init()`-Aufruf `mysql_server_init()` aus. Wenn Sie das mit MySQL gelieferte DBUG-Paket benutzen, sollten Sie die Funktion nach `my_init()` aufrufen.

Die Argumente `argc` und `argv` entsprechen den Argumenten von `main()`. Das erste Element von `argv` wird ignoriert (es enthält typischerweise den Namen des Programms). Der Bequemlichkeit halber kann `argc` den Wert `0` (null) haben, wenn keine Kommandozeilenargumente für den Server vorhanden sind. Da `mysql_server_init()` die Argumente kopiert, kann `argv` oder `groups` nach dem Aufruf getrost zerstört werden.

Wenn Sie sich mit einem externen Server verbinden möchten, ohne den Embedded Server zu starten, müssen Sie einen negativen Wert für `argc` angeben.

Die mit `NULL` endende Liste der Strings in `groups` wählt die Gruppen aus den Optionsdateien aus, die aktiv sein sollen. Siehe Abschnitt 4.3.2, „my.cnf-Optionsdateien“. Der Bequemlichkeit halber kann `groups` den Wert `NULL` haben. In diesem Fall sind die Gruppen `[server]` und `[embedded]` aktiv.

Beispiel

    #include <mysql.h>
    #include <stdlib.h>

    static char *server_args[] = {
      "this_program",       /* Dieser String wird nicht benutzt */
      "--datadir=.",
      "--key_buffer_size=32M"
    };
    static char *server_groups[] = {
      "embedded",
      "server",
      "this_program_SERVER",
      (char *)NULL
    };

    int main(void) {
      if (mysql_server_init(sizeof(server_args) / sizeof(char *),
                            server_args, server_groups))
        exit(1);

      /* Hier werden MySQL-API-Funktionen benutzt */

      mysql_server_end();

      return EXIT_SUCCESS;
    }

Rückgabewerte

0, wenn alles okay ist, 1, wenn ein Fehler auftrat.

#### 24.2.12.2. `mysql_server_end()`

`void mysql_server_end(void)`

Beschreibung

Diese Funktion muss unbedingt einmalig im Programm aufgerufen werden, und zwar nach allen anderen MySQL-Funktionen. Sie fährt den Embedded Server herunter.

Rückgabewerte

Keine.

### 24.2.13. Häufige Fragen und Probleme bei der Benutzung der C-API

#### 24.2.13.1. Warum gibt `mysql_store_result()` manchmal `NULL` zurück, nachdem `mysql_query()` Erfolg zurückgegeben hat?

Es ist möglich, dass `mysql_store_result()` nach einem erfolgreichen Aufruf von `mysql_query()` den Wert `NULL` zurückgibt. Wenn dies geschieht, so bedeutet es, dass eine der folgenden Bedingungen eingetreten ist:

- Es gab einen Fehler in `malloc()` (beispielsweise, wenn die Ergebnismenge zu groß war).

- Die Daten konnten nicht gelesen werden (ein Verbindungsfehler).

- Die Anfrage hat keine Daten geliefert (beispielsweise wenn sie ein `INSERT`, `UPDATE` oder `DELETE` war).

Sie können immer mit `mysql_field_count()` prüfen, ob die Anweisung eine nichtleere Ergebnismenge hätte produzieren sollen. Wenn `mysql_field_count()` null liefert, ist das Ergebnis leer und es handelte sich um eine Anweisung, die keine Werte zurückgibt (beispielsweise ein `INSERT` oder `DELETE`). Wenn `mysql_field_count()` einen von null verschiedenen Wert liefert, hätte die Anweisung eigentlich ein nichtleeres Ergebnis zurückgeben müssen. Ein Beispiel finden Sie in der Beschreibung der `mysql_field_count()`-Funktion.

Ob ein Fehler auftrat, verrät Ihnen `mysql_error()` oder `mysql_errno()`.

#### 24.2.13.2. Welche Ergebnisse kann ich von einer Anfrage bekommen?

Zusätzlich zu der Frage, ob eine Anfrage eine Ergebnismenge zurückgibt, können Sie auch die folgenden Informationen herausfinden:

- `mysql_affected_rows()` liefert die Anzahl der von der letzten Anfrage betroffenen Zeilen, wenn die Anfrage ein `INSERT`, `UPDATE` oder `DELETE` war.

  Für eine schnelle Rekonstruktion verwenden Sie `TRUNCATE TABLE`.

- `mysql_num_rows()` liefert die Anzahl der Zeilen in einer Ergebnismenge. Bei `mysql_store_result()` kann `mysql_num_rows()` aufgerufen werden, sobald `mysql_store_result()` zurückkehrt. Bei `mysql_use_result()` kann `mysql_num_rows()` erst aufgerufen werden, nachdem alle Zeilen mit `mysql_fetch_row()` abgeholt worden sind.

- `mysql_insert_id()` liefert die ID, welche die letzte Anfrage, die eine Zeile in eine Tabelle mit einem `AUTO_INCREMENT`-Index eingefügt hat, generierte. Siehe Abschnitt 24.2.3.36, „`mysql_insert_id()`“.

- Manche Anfragen (`LOAD DATA INFILE ...`, `INSERT INTO ... SELECT ...`, `UPDATE`) geben weitere Informationen zurück. Das Ergebnis erhalten Sie von `mysql_info()`. In der Beschreibung zu `mysql_info()` erfahren Sie, welches String-Format diese Funktion liefert. `mysql_info()` gibt einen `NULL`-Zeiger zurück, wenn keine weiteren Informationen mehr vorliegen.

#### 24.2.13.3. Wie erhalte ich die eindeutige Kennung für die letzte eingefügte Zeile?

Wenn Sie einen Datensatz in eine Tabelle mit einer `AUTO_INCREMENT`-Spalte einfügen, können Sie den in dieser Spalte gespeicherten Wert mit der Funktion `mysql_insert_id()` erhalten.

In Ihren C-Anwendungen können Sie überprüfen, ob ein Wert in einer `UTO_INCREMENT`-Spalte gespeichert wurde. Hierzu führen Sie folgenden Code aus (der voraussetzt, dass Sie sich vom Erfolg der Anweisung überzeugt haben). Der Code ermittelt, ob die Anfrage ein `INSERT` mit einem `AUTO_INCREMENT`-Index war:

    if ((result = mysql_store_result(&mysql)) == 0 &&
        mysql_field_count(&mysql) == 0 &&
        mysql_insert_id(&mysql) != 0)
    {
        used_id = mysql_insert_id(&mysql);
    }

Weitere Informationen finden Sie unter Abschnitt 24.2.3.36, „`mysql_insert_id()`“.

Wurde ein neuer `AUTO_INCREMENT`-Wert generiert, so können Sie diesen auch erhalten, indem Sie die `SELECT LAST_INSERT_ID()`-Anweisung mit `mysql_query()` ausführen und den Wert aus der Ergebnismenge dieser Anweisung abfragen.

Für `LAST_INSERT_ID()` wird die zuletzt generierte ID für jede Verbindung im Server gespeichert. Sie wird von keinem anderen Client geändert, noch nicht einmal dann, wenn Sie eine andere `AUTO_INCREMENT`-Spalte mit einem nichtmagischen Wert aktualisieren (also einem Wert, der nicht `NULL` und nicht `0` ist).

Wenn Sie die für eine Tabelle generierte ID benutzen und in eine andere Tabelle einfügen möchten, erledigen Sie dies mit SQL-Anweisungen wie diesen:

    INSERT INTO foo (auto,text)
        VALUES(NULL,'text');              # generiert ID durch Einfügen von NULL
    INSERT INTO foo2 (id,text)
        VALUES(LAST_INSERT_ID(),'text');  # benutzt ID in einer zweiten Tabelle

Beachten Sie, dass `mysql_insert_id()` den Wert liefert, der in einer `AUTO_INCREMENT`-Spalte gespeichert war, egal ob dieser Wert automatisch durch Speichern von `NULL` oder `0` generiert oder als expliziter Wert angegeben wurde. `LAST_INSERT_ID()` liefert nur automatisch generierte `AUTO_INCREMENT`-Werte. Wenn Sie einen expliziten Wert, der nicht `NULL` oder `0` ist, speichern, so beeinflusst dieser nicht den Rückgabewert von `LAST_INSERT_ID()`.

#### 24.2.13.4. Probleme beim Linken mit der C-API

Beim Verlinken mit der C-API können folgende Fehler auf manchen Systemen auftreten:

    gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl

    Undefined        first referenced
     symbol          in file
    floor            /usr/local/lib/mysql/libmysqlclient.a(password.o)
    ld: fatal: Symbol referencing errors. No output written to client

Wenn dies auf Ihrem System geschieht, müssen Sie die Mathe-Bibliothek einbinden, indem Sie `-lm` am Ende der Compile/link-Zeile hinzufügen.

### 24.2.14. Clientprogramme bauen

Wenn Sie MySQL-Clients kompilieren, die Sie selbst geschrieben oder von einem Fremdhersteller bekommen haben, müssen diese im Link-Befehl mit den `-lmysqlclient -lz`-Optionen verknüpft werden. Eventuell müssen Sie auch die Option `-L` angeben, um dem Linker mitzuteilen, wo er die Bibliothek finden kann. Wenn die Bibliothek beispielsweise in `/usr/local/mysql/lib` installiert ist, müssen Sie im Link-Befehl `-L/usr/local/mysql/lib -lmysqlclient -lz` verwenden.

Für Clients, die MySQL-Header-Dateien benutzen, müssen Sie eventuell beim Kompilieren die Option `-I` (zum Beispiel `-I/usr/local/mysql/include`) einstellen, damit der Compiler die Header-Dateien finden kann.

Um das Kompilieren von MySQL-Programmen auf Unix zu erleichtern, haben wir das mysql_config-Skript für Sie erstellt. Siehe hierzu Abschnitt 24.9.2, „mysql_config — Kompilieroptionen zum Kompilieren von Clients erhalten“.

Mit dem Skript können Sie einen MySQL-Client wie folgt kompilieren:

    CFG=/usr/local/mysql/bin/mysql_config
    sh -c "gcc -o progname `$CFG --cflags` progname.c `$CFG --libs`"

`sh -c` ist erforderlich, damit die Shell die Ausgabe von mysql_config nicht als ein einziges Wort behandelt.

### 24.2.15. Wie man einen Thread-Client herstellt

Die Clientbibliothek ist beinahe Thread-sicher. Das größte Problem besteht darin, dass die Subroutinen in `net.c`, die Daten aus Sockets lesen, nicht gegen Interrupts gesichert sind. Dies wurde mit dem Hintergedanken so eingerichtet, dass Sie vielleicht einen eigenen Alarm installieren möchten, der einen langen Lesevorgang auf einem Server abbrechen kann. Wenn Sie Interrupt-Handler für den `SIGPIPE`-Interrupt installieren, sollte die Arbeit auf dem Socket Thread-sicher sein.

Um zu verhindern, dass das Programm abbricht, sobald eine Verbindung endet, blockiert MySQL `SIGPIPE` beim ersten Aufruf von `mysql_server_init()`, `mysql_init()` oder `mysql_connect()`. Wenn Sie einen eigenen `SIGPIPE`-Handler benutzen möchten, sollten Sie als Erstes `mysql_server_init()` aufrufen und dann Ihren Handler installieren.

In den älteren Binaries, die auf unserer Website angeboten werden (http://www.mysql.com/), werden die Clientbibliotheken normalerweise nicht mit der Thread-sicheren Option kompiliert (ausgenommen die Windows-Binaries, die standardmäßig Thread-sicher kompiliert werden). Neuere Binärdistributionen sollten sowohl eine normale als auch eine Thread-sichere Clientbibliothek besitzen.

Um einen Threaded Client zu erstellen, den Sie mit anderen Threads unterbrechen und auf dem Sie Timeouts für die Kommunikation mit dem MySQL Server einstellen können, verwenden Sie die Bibliotheken `-lmysys`, `-lmystrings` und `-ldbug` sowie den `net_serv.o`-Code, den auch der Server benutzt.

Wenn Sie keine Interrupts oder Timeouts benötigen, kompilieren Sie einfach eine Thread-sichere Clientbibliothek `(mysqlclient_r)` und benutzen diese. Siehe Abschnitt 24.2, „MySQL-C-API“. In diesem Fall müssen Sie sich über die `net_serv.o`-Objektdatei oder die anderen MySQL-Bibliotheken keine Gedanken machen.

Wenn Sie einen Threaded Client mit Timeouts und Interrupts benutzen möchten, sind die Routinen in der Datei `thr_alarm.c` sehr gut geeignet. Benutzen Sie Routinen aus der `mysys`-Bibliothek, so müssen Sie nur daran denken, `my_init()` immer als Erstes aufzurufen! Siehe Abschnitt 24.2.11, „C-Threaded-Funktionsbeschreibungen“.

Alle Funktionen außer `mysql_real_connect()` sind standardmäßig Thread-sicher. Die folgenden Hinweise beschreiben, wie man eine Thread-sichere Clientbibliothek kompiliert und in Thread-sicherer Weise benutzt. (Eigentlich gelten die folgenden Hinweise zu `mysql_real_connect()` auch für `mysql_connect()`, aber da `mysql_connect()` veraltet ist, sollten Sie ohnehin nur mit `mysql_real_connect()` arbeiten.)

Um `mysql_real_connect()` Thread-sicher zu machen, müssen Sie die Clientbibliothek mit folgendem Befehl neu kompilieren:

    shell> ./configure --enable-thread-safe-client

Dies erzeugt die Thread-sichere Clientbibliothek `libmysqlclient_r`. (Immer vorausgesetzt, dass Ihr Betriebssytem über eine Thread-sichere `gethostbyname_r()`-Funktion verfügt.) Diese Bibliothek ist pro Verbindung Thread-sicher. Zwei Threads können also dieselbe Verbindung nutzen, allerdings mit folgenden Schwachstellen:

- Zwei Threads können einem MySQL Server nicht gleichzeitig über dieselbe Verbindung eine Anfrage senden. Sie müssen vor allem gewährleisten, dass zwischen `mysql_query()` und `mysql_store_result()` kein anderer Thread dieselbe Verbindung benutzt.

- Viele Threads können auf unterschiedliche Ergebnismengen zugreifen, die mit `mysql_store_result()` abgerufen werden.

- Wenn Sie dagegen `mysql_use_result` benutzen, müssen Sie dafür sorgen, dass so lange kein anderer Thread dieselbe Verbindung benutzt, bis die Ergebnismenge wieder geschlossen wurde. Allerdings ist `mysql_store_result()` ohnehin die bessere Lösung für Threaded Clients, die sich dieselbe Verbindung teilen.

- Wenn Sie mehrere Threads auf derselben Verbindung einsetzen möchten, müssen Sie die `mysql_query()`- und `mysql_store_result()`-Aufrufkombinationen mit einer Mutex-Sperre umgeben. Sobald `mysql_store_result()` fertig ist, kann die Sperre aufgehoben werden und andere Threads können Anfragen an dieselbe Verbindung schicken.

- Wenn Sie mit POSIX-Threads programmieren, können Sie mit `pthread_mutex_lock()` und `pthread_mutex_unlock()` eine Mutex-Sperre errichten und wieder freigeben.

Folgendes ist wichtig, wenn Sie einen Thread andere MySQL-Funktionen aufrufen lassen als die, welche die Verbindung zur MySQL-Datenbank eingerichtet haben:

Wenn Sie `mysql_init()` oder `mysql_connect()` aufrufen, legt MySQL eine Thread-spezifische Variable für den Thread an, die (unter anderem) von der Debugbibliothek genutzt wird.

Wenn Sie eine MySQL-Funktion aufrufen, bevor der Thread `mysql_init()` oder `mysql_connect()` aufgerufen hat, wurden die Thread-spezifischen Variablen für den Thread noch nicht angelegt und Sie riskieren, dass es früher oder später zu einem Core Dump kommt.

Damit alles reibunbslos funktioniert, müssen Sie Folgendes tun:

1. Rufen Sie `my_init()` am Anfang Ihres Programms auf, wenn dieses vor `mysql_real_connect()` noch eine andere MySQL-Funktion aufruft.

2. Rufen Sie im Thread-Handler `mysql_thread_init()` auf, ehe Sie irgendeine MySQL-Funktion benutzen.

3. Im Thread müssen Sie `mysql_thread_end()` vor `pthread_exit()` aufrufen. Das gibt den Speicher frei, den MySQL für Thread-spezifische Variablen reserviert hat.

Eventuell werden Fehler aufgrund von undefinierten Symbolen gemeldet, wenn Sie Ihren Client mit `libmysqlclient_r` verlinken. In den meisten Fällen liegt dies daran, dass Sie vergessen haben, auf der Link/compile-Zeile die Thread-Bibliotheken einzubinden.

## 24.3. MySQLs PHP-API

PHP ist eine serverseitige, in HTML eingebettete Skriptsprache zur Erstellung von dynamischen Webseiten. Sie steht für die meisten Betriebssysteme und Webserver zur Verfügung und kann auf die meisten gebräuchlichen Datenbanken zugreifen, darunter auch MySQL. PHP kann als separates Programm ausgeführt oder als Modul in den Apache-Webserver kompiliert werden.

PHP stellt zwei verschiedene MySQL-API-Erweiterungen zur Verfügung:

- `mysql`: Diese Erweiterung ist für PHP 4 und 5 verfügbar und für MySQL-Versionen gedacht, die älter als MySQL 4.1 sind. Die Erweiterung unterstützt weder das verbesserte Authentifizierungsprotokoll von MySQL 5.1, noch vorbereitete Anweisungen oder Mehrfachanweisungen. Wenn Sie diese Erweiterung mit MySQL 5.1 benutzen möchten, müssen Sie den MySQL Server wahrscheinlich mit der Option --old-passwords konfigurieren (siehe Abschnitt A.2.3, „`Client does not support authentication protocol`“). Diese Erweiterung ist auf der PHP-Website unter http://php.net/mysql dokumentiert.

- `mysqli` (eine Abkürzung für „MySQL, Improved“) ist eine Erweiterung, die nur in PHP 5 verfügbar ist. Sie ist für die Benutzung mit MySQL 4.1.1 und höher gedacht. Diese Erweiterung unterstützt das Authentifizierungsprotokoll von MySQL 5.1 sowie die APIS für vorbereitete Anweisungen und Mehrfachanweisungen (Prepared Statements und Multiple Statements). Überdies hat diese Erweiterung eine moderne Schnittstelle für die objektorientierte Programmierung zu bieten. Die Dokumentation der Erweiterung `mysqli` finden Sie unter http://php.net/mysqli. Außerdem ist unter http://www.zend.com/php5/articles/php5-mysqli.php ein hilfreicher Fachartikel zu lesen.

Die PHP-Distribution und -Dokumentation stehen auf der PHP-Website zur Verfügung.

### 24.3.1. Allgemeine Probleme mit MySQL und PHP

- `Error: Maximum Execution Time Exceeded`: Dies ist ein PHP-Limit. Gehen Sie in die Datei `php.ini` und setzen Sie die maximale Ausführungszeit von 30 Sekunden auf einen höheren Wert, wie Sie ihn benötigen. Außerdem ist es keine schlechte Idee, den pro Skript verfügbaren Arbeitsspeicher von 8 auf 16 Mbyte zu verdoppeln.

- `Fatal error: Call to unsupported or undefined Funktion mysql_connect() in ...`: Dies bedeutet, dass Ihre PHP-Version nicht mit MySQL-Unterstützung kompiliert wurde. Sie können entweder ein dynamisches MySQL-Modul kompilieren und in PHP laden oder PHP mit integrierter MySQL-Unterstützung rekompilieren. Dieser Prozess wird im PHP-Handbuch genauer erläutert.

- `Error: Undefined reference to 'uncompress'`: Dies bedeutet, dass die Clientbibliothek mit Unterstützung für ein komprimiertes Client/Server-Protokoll kompiliert wurde. Dies beheben Sie, indem Sie die Option `-lz` als Letztes beim Verlinken mit `-lmysqlclient` hinzufügen.

- `Error: Client does not support authentication protocol`: Dieser Fehler tritt am häufigsten auf, wenn Sie versuchen, die ältere `mysql`-Erweiterung mit MySQL 4.1.1 oder höher zu verwenden. Mögliche Lösungen: Sie können auf MySQL 4.0 umstellen, auf PHP 5 und die neuere `mysqli` umschalten oder den MySQL Server mit der Option `--old-passwords` konfigurieren. (Siehe auch Abschnitt A.2.3, „`Client does not support authentication protocol`“.)

Wer noch mit älterem PHP4-Code arbeitet, kann eine Kompatibilitätsschicht für die alte und neue MySQL-Bibliothek verwenden, wie beispielsweise: http://www.coggeshall.org/oss/mysql2i.

## 24.4. MySQLs Perl-API

Das `DBI`-Modul von Perl stellt eine generische Schnittstelle für den Datenbankzugriff zur Verfügung. Sie können ein DBI-Skript schreiben, das ohne Änderungen mit vielen verschiedenen Datenbank-Engines funktioniert. Um DBI nutzen zu können, müssen Sie das `DBI`-Modul sowie für jeden Servertyp, auf den Sie zugreifen möchten, ein DataBase Driver (DBD)-Modul kompilieren. Das Treibermodul für MySQL ist `DBD::mysql`.

Perl DBI ist die empfohlene Schnittstelle für Perl. Sie ersetzt eine ältere Schnittstelle namens `mysqlperl`, die nun als obsolet gelten kann.

Installationsanleitungen für Perl DBI-Support finden Sie in Abschnitt 2.13, „Anmerkungen zur Perl-Installation“.

DBI-Informationen stehen auf der Kommandozeile, online oder gedruckt zur Verfügung:

- Wenn Sie die Module `DBI` und `DBD::mysql` installiert haben, können Sie Informationen über diese Module mit dem Befehl `perldoc` auf der Kommandozeile abfragen:

      shell> perldoc DBI
      shell> perldoc DBI::FAQ
      shell> perldoc DBD::mysql

  Sie können diese Informationen auch mit `pod2man`, `pod2html` und so weiter in andere Formate übersetzen.

- Online-Informationen über Perl DBI stehen auf der DBI-Website unter http://dbi.perl.org/ zur Verfügung. Diese Site hostet auch eine allgemeine Mailingliste zu DBI. MySQL AB hostet überdies eine spezielle `DBD::mysql`-Mailingliste; siehe Abschnitt 1.7.1, „Die MySQL-Mailinglisten“.

- Was das gedruckte Wort angeht, so ist das offizielle DBI-Buch Programming the Perl DBI (Alligator Descartes und Tim Bunce, O'Reilly & Associates, 2000). Informationen über dieses Buch finden Sie auf der DBI-Website http://dbi.perl.org/.

  Informationen, die speziell die Benutzung von DBI mit MySQL in den Mittelpunkt stellen, finden Sie unter MySQL and Perl for the Web (Paul DuBois, New Riders, 2001). Die Website zu diesem Buch ist http://www.kitebird.com/mysql-perl/.

## 24.5. MySQL-C++-APIs

`MySQL++` ist eine MySQL-API für C++. Warren Young hat dieses Projekt übernommen. Weitere Informationen finden Sie unter http://www.mysql.com/products/mysql++/.

### 24.5.1. Borland C++

Sie können die MySQL Windows-Quelldatei mit Borland C++ 5.02 kompilieren. (Zur Windows-Quelldatei gehören nur Projekte für Microsoft VC++; Projektdateien für Borland C++ müssen Sie sich selbst beschaffen.)

Ein bekanntes Problem mit Borland C++ ist, dass er eine andere Strukturanordnung als VC++ verwendet. Daher bekommen Sie Probleme, wenn Sie versuchen, mit Borland C++ die standardmäßigen `libmysql.dll`-Bibliotheken zu benutzen (die mit VC++ kompiliert wurden). Um dies zu vermeiden, rufen Sie `mysql_init()` nur mit `NULL` als Argument auf und verwenden keine vorab zugewiesene `MYSQL`-Struktur.

## 24.6. MySQL-Python-APIs

`MySQLdb` stellt für Python eine MySQL-Unterstützung zur Verfügung, die mit der Python-DB-API-Version 2.0 harmoniert. Diese finden Sie unter http://sourceforge.net/projects/mysql-python/.

## 24.7. MySQL-Tcl-APIs

`MySQLtcl` ist eine einfache API, um mit der Programmiersprache Tcl auf einen MySQL-Datenbankserver zugreifen zu können. Zu finden ist sie unter http://www.xdobry.de/mysqltcl/.

## 24.8. MySQL-Eiffel-Wrapper

Eiffel MySQL ist eine Schnittstelle zum MySQL-Datenbankserver für die von Michael Ravits geschriebene Programmiersprache Eiffel. Diese finden Sie unter http://efsa.sourceforge.net/archive/ravits/mysql.htm.

## 24.9. MySQL-Hilfsprogramme für die Programmentwicklung

Dieser Abschnitt beschreibt einige Utilities, die Ihnen bei der Entwicklung von MySQL-Programmen helfen können.

- `msql2mysql`

  Ein Shell-Skript, das `mSQL`-Programme in MySQL konvertiert. Es kann zwar nicht jeden Fall behandeln, ist aber für die Konvertierung ein guter Anfang.

- `mysql_config`

  Ein Shell-Skript, das die zur Kompilierung von MySQL-Programmen notwendigen Optionswerte erstellt.

### 24.9.1. msql2mysql — Umwandeln von mSQL-Programmen für die Benutzung mit MySQL

Anfangs wurde die MySQL-C-API ganz ähnlich wie die API für das Datenbanksystem mSQL entwickelt. Daher lassen sich mSQL-Programme oft relativ einfach für die Benutzung mit MySQL konvertieren, indem man einfach nur die Namen der C-API-Funktionen ändert.

Die Utility msql2mysql wandelt mSQL-C-API-Funktionsaufrufe in ihre MySQL-Entsprechungen um. Da msql2mysql die Eingabedatei an Ort und Stelle konvertiert, sollten Sie vorher eine Kopie des Originals anlegen. Sie können msql2mysql beispielsweise wie folgt verwenden:

    shell> cp client-prog.c client-prog.c.orig
    shell> msql2mysql client-prog.c
    client-prog.c converted

Danach untersuchen Sie `client-prog.c` und nehmen, so weit notwendig, abschließende Überarbeitungen vor.

msql2mysql verwendet zum Ersetzen der Funktionsnamen die Utility replace. Siehe Abschnitt 8.17, „replace — Hilfsprogramm für String-Ersetzungen“.

### 24.9.2. mysql_config — Kompilieroptionen zum Kompilieren von Clients erhalten

mysql_config gibt Ihnen nützliche Informationen zum Kompilieren des MySQL-Clients und zur Verbindung mit MySQL.

mysql_config unterstützt die folgenden Optionen:

- `--cflags`

  Compiler-Flags zum Auffinden von Include-Dateien und wichtige Compiler-Flags und Defines, die zum Kompilieren der `libmysqlclient`-Bibliothek verwendet werden.

- `--include`

  Compiler-Optionen zum Auffinden von MySQL-Include-Dateien. (Beachten Sie, dass normalerweise statt dieser Option die Option `--cflags` benutzt wird.)

- `--libmysqld-libs`, `---embedded`

  Bibliotheken und Optionen, die zum Verlinken mit dem MySQL Embedded Server erforderlich sind.

- `--libs`

  Bibliotheken und Optionen, die zum Verlinken mit der MySQL-Clientbibliothek erforderlich sind.

- `--libs_r`

  Bibliotheken und Optionen, die zum Verlinken mit der Thread-sicheren MySQL-Clientbibliothek erforderlich sind.

- `--port`

  Die Standard-TCP/IP-Portnummer, die beim Konfigurieren von MySQL definiert wird.

- `--socket`

  Die Standard-Unix-Socket-File, die beim Konfigurieren von MySQL definiert wird.

- `--version`

  Versionsnummer für die MySQL-Distribution.

Wenn Sie mysql_config ohne Optionen aufrufen, zeigt der Befehl eine Liste aller von ihm unterstützten Optionen samt ihrer Werte an:

    shell> mysql_config
    Usage: /usr/local/mysql/bin/mysql_config [options]
    Options:
      --cflags         [-I/usr/local/mysql/include/mysql -mcpu=pentiumpro]
      --include        [-I/usr/local/mysql/include/mysql]
      --libs           [-L/usr/local/mysql/lib/mysql -lmysqlclient -lz
                        -lcrypt -lnsl -lm -L/usr/lib -lssl -lcrypto]
      --libs_r         [-L/usr/local/mysql/lib/mysql -lmysqlclient_r
                        -lpthread -lz -lcrypt -lnsl -lm -lpthread]
      --socket         [/tmp/mysql.sock]
      --port           [3306]
      --version        [4.0.16]
      --libmysqld-libs [-L/usr/local/mysql/lib/mysql -lmysqld -lpthread -lz
                        -lcrypt -lnsl -lm -lpthread -lrt]

Sie können mysql_config in einer Kommandozeile benutzen, um den Wert, den dieser Befehl für eine bestimmte Option anzeigt, einzubinden. Um beispielsweise ein MySQL-Clientprogramm zu kompilieren, verwenden Sie mysql_config folgendermaßen:

    shell> CFG=/usr/local/mysql/bin/mysql_config
    shell> sh -c "gcc -o progname `$CFG --cflags` progname.c `$CFG --libs`"

Wenn Sie mysql_config auf diese Weise benutzen, achten Sie darauf, es in Backtick-Zeichen einzuschließen (‘```’). So weiß die Shell, dass sie dies ausführen und die Ausgabe in den umgebenden Befehl einsetzen muss.

Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.

Zurück |  | Weiter
Kapitel 23. Präzisionsberechnungen | Zum Anfang | Kapitel 25. Connectors