Kapitel 25. Connectors
Zurück |  | Weiter

## Kapitel 25. Connectors

Dieses Kapitel beschreibt MySQL Connectors, Treiber, die für Clientprogramme Verbindungsmöglichkeiten zu MySQL bereitstellen.

## 25.1. MySQL Connector/ODBC

MySQL Connector/ODBC ist der Name einer Familie von MySQL-ODBC-Treibern (auch MyODBC-Treiber genannt), die Zugriff auf eine MySQL-Datenbank mithilfe der Open Database Connectivity (ODBC)-API geben, die Industriestandard ist. Die vorliegende Referenz behandelt die API-Version Connector/ODBC 3.51, die ODBC 3.5x-konformen Zugriff auf eine MySQL-Datenbank gibt.

Das Manual für ältere MyODBC-Versionen als 3.51 finden Sie in der entsprechenden Binär- oder Quelldistribution.

Weitere Informationen über den ODBC-API-Standard und seine Verwendung finden Sie unter http://www.microsoft.com/data/.

Der Teil dieser Referenz, der sich mit Anwendungsentwicklung beschäftigt, setzt gute Vorkenntnisse in C, allgemeine DBMS-Kenntnisse und nicht zuletzt auch die Vertrautheit mit MySQL voraus. Weitere Informationen über die Funktionalität und Syntax von MySQL finden Sie unter http://dev.mysql.com/doc/.

MyODBC muss in der Regel nur auf Windows-Rechnern installiert werden. Für Unix und Mac OS X kann das native MySQL-Netzwerk oder eine Named Pipe zur Kommunikation mit der MySQL-Datenbank benutzt werden. Eventuell benötigen Sie jedoch MyODBC für Unix oder Mac OS X, wenn Sie eine Anwendung haben, die für die Datenbankkommunikation eine ODBC-Schnittstelle benötigt. Solche Anwendungen sind beispielsweise ColdFusion, Microsoft Office und Filemaker Pro.

Wenn Sie den MyODBC-Connector auf einem Unix-Host benutzen, müssen Sie auch einen ODBC-Manager installieren.

Fragen, die dieses Dokument nicht beantwortet, richten Sie bitte per E-Mail an `<myodbc@lists.mysql.com>`.

### 25.1.1. Einführung in MyODBC

ODBC (Open Database Connectivity) gibt Clientprogrammen Zugriffsmöglichkeiten auf eine breite Palette von Datenbanken oder Datenquellen. ODBC ist eine standardisierte API, die Verbindungen zu SQL-Datenbankservern ermöglicht. Sie wurde nach den Vorgaben der SQL Access Group entwickelt und definiert Funktionsaufrufe, Fehlercodes und Datentypen, die für die Entwicklung datenbankunabhängiger Anwendungen eingesetzt werden können. ODBC wird normalerweise dort genutzt, wo Datenbankunabhängigkeit oder paralleler Zugriff auf verschiedene Datenquellen erforderlich ist.

Mehr über ODBC können Sie unter http://www.microsoft.com/data/ nachlesen.

#### 25.1.1.1. MyODBC-Versionen

Zurzeit sind zwei Versionen von MyODBC erhältlich:

- MyODBC 5.0, gegenwärtig noch in der Beta-Phase, wurde geschaffen, um die Funktionalität des MyODBC 3.51-Treibers zu erweitern und sämtliche Funktionen des MySQL Servers 5.0 zu unterstützen, einschließlich gespeicherter Prozeduren und Views. Anwendungen für MyODBC 3.51 werden auch mit MyODBC 5.0 funktionieren, zusätzlich jedoch auch die neuen Funktionen nutzen können. Die Features und Funktionalität des MyODBC 5.0-Treibers sind zurzeit noch nicht Gegenstand des vorliegenden Guides.

- MyODBC 3.51 ist das aktuelle Release des 32-Bit-ODBC-Treibers, auch MySQL ODBC 3.51-Treiber genannt. Diese Version wurde gegenüber dem älteren MyODBC 2.50-Treiber verbessert. Sie unterstützt den ODBC 3.5x-Spezifikationslevel 1 (die gesamte Core-API + Features von Level 2), damit weiterhin auch die gesamte Funktionalität für den ODBC-Zugriff auf MySQL geboten werden kann.

- MyODBC 2.50 ist die frühere Version des 32-Bit-ODBC-Treibers von der MySQL AB und beruht auf dem ODBC 2.50-Spezifikationslevel 0 (mit den Features von Level 1 und 2). Über den MyODBC 2.50-Treiber informiert diese Referenz nur zu Vergleichszwecken.

Hinweis: Ab diesem Abschnitt liegt das Hauptaugenmerk dieser Referenz auf dem MyODBC 3.51-Treiber. Weitere Informationen über den MyODBC-Treiber 2.50 finden Sie in der Dokumentation zu den Installationspaketen dieser Version. Wenn ein konkretes Thema (ein Fehler oder ein bekanntes Problem) nur die Version 2.50 betrifft, wird es unter Umständen zur Orientierung hier ebenfalls behandelt.

#### 25.1.1.2. Allgemeine Informationen über ODBC und MyODBC

Open Database Connectivity (ODBC) ist eine allgemein anerkannte Programmierschnittstelle (API) für den Datenbankzugriff. Sie beruht auf den Call-Level Interface(CLI)-Spezifikationen von X/Open und ISO/IEC für Datenbank-APIs und benutzt als Sprache für den Datenbankzugriff die Structured Query Language (SQL).

Eine Übersicht über die von MyODBC unterstützten ODBC-Funktionen finden Sie unter Abschnitt 25.1.5.1, „MyODBC: API-Referenz“. Allgemeine Informationen über ODBC gibt es unter http://www.microsoft.com/data/.

##### 25.1.1.2.1. MyODBC-Architektur

Die MyODBC-Architektur basiert auf den im folgenden Diagramm gezeigten fünf Komponenten:

- Anwendung:

  Die Anwendung (Application) nutzt die ODBC-API, um auf die Daten auf dem MySQL Server zuzugreifen. Die ODBC-API ihrerseits kommuniziert mit dem Treiber-Manager (Driver Manager). Die Anwendung kommuniziert mit dem Treiber-Manager über normale ODBC-Aufrufe und kümmert sich nicht darum, wie und wo die Daten gespeichert sind oder wie das System für den Datenzugriff konfiguriert ist. Alles, was sie wissen muss, ist der Data Source Name (DSN).

  Einige Aufgaben müssen von allen Anwendungen erledigt werden, egal auf welche Weise sie ODBC nutzen:

  - Sie müssen den MySQL Server auswählen und sich mit ihm verbinden.

  - Sie müssen SQL-Anweisungen zur Ausführung übermitteln.

  - Sie müssen die Ergebnisse (sofern vorhanden) abholen.

  - Sie müssen Fehler verarbeiten.

  - Sie müssen die Transaktion, zu der die SQL-Anweisung gehört, committen oder zurückrollen.

  - Sie müssen die Verbindung zum MySQL Server trennen.

  Da die meiste Arbeit im Zusammenhang mit dem Datenzugriff mit SQL verrichtet wird, besteht die Hauptaufgabe von Anwendungen, die ODBC nutzen, in der Übermittlung von SQL-Anweisungen und dem Abruf der dadurch erzeugten Ergebnisse.

- Treiber-Manager:

  Der Treiber-Manager ist eine Bibliothek zur Verwaltung der Kommunikation zwischen Anwendung und Treiber(n). Er kümmert sich um folgende Aufgaben:

  - Er löst Data Source Names (DSN) auf. Der DSN ist ein Konfigurations-String, der einen Datenbanktreiber, einen Datenbank-Host und optional auch Authentifizierungsdaten enthält und der ODBC-Anwendung eine Datenbankverbindung über eine standardisierte Referenz ermöglicht.

    Da der DSN die Informationen für die Datenbankverbindung enthält, kann sich jede ODBC-fähige Anwendung über dieselbe DSN-Referenz mit der Datenquelle verbinden. Dadurch ist es nicht mehr nötig, jede Anwendung, die Zugriff auf eine konkrete Datenbank benötigt, separat zu konfigurieren. Stattdessen instruieren Sie die Anwendung, einen vorkonfigurierten DSN zu verwenden.

  - Er lädt und entlädt den Treiber, der für den Zugriff auf eine bestimmte Datenbank notwendig ist, wie im DSN definiert. Wenn Sie zum Beispiel einen DSN für die Verbindung mit einer MySQL-Datenbank konfiguriert haben, lädt der Treiber-Manager den MyODBC-Treiber, damit die ODBC-API mit dem MySQL-Host kommunizieren kann.

  - Er verarbeitet ODBC-Funktionsaufrufe oder übergibt sie zur Verarbeitung an den Treiber.

- MyODBC-Treiber:

  Der MyODBC-Treiber ist eine Bibliothek, die Funktionen implementiert, welche von der ODBC-API unterstützt werden. Er verarbeitet ODBC-Funktionsaufrufe, übermittelt SQL-Requests an den MySQL Server und liefert die Ergebnisse an die Anwendung zurück. Wenn nötig, modifiziert der Treiber den von der Anwendung übermittelten Request so, dass er der MySQL-Syntax entspricht.

- DSN-Konfiguration:

  Die ODBC-Konfigurationsdatei speichert die Treiber- und Datenbankinformationen, die für die Serververbindung erforderlich sind. Der Treiber-Manager nutzt sie, um festzustellen, welcher Treiber laut der Definition im DSN geladen werden muss. Der Treiber liest daraus die Verbindungsparameter anhand des angegebenen DSN. Weitere Informationen finden Sie unter Abschnitt 25.1.3, „MyODBC: Konfiguration“.

- MySQL Server:

  Die MySQL-Datenbank, in der die Informationen gespeichert sind. Die Datenbank wird für Abfragen als Datenquelle und für Einfügungen und Änderungen als Ziel für die Daten genutzt.

##### 25.1.1.2.2. ODBC-Treiber-Manager

Ein ODBC-Treiber-Manager ist eine Bibliothek zur Verwaltung der Kommunikation zwischen einer ODBC-fähigen Anwendung und Treibern. Seine Hauptfunktionen sind:

- Data Source Names (DSN) auflösen

- Treiber laden und entladen

- ODBC-Funktionsaufrufe verarbeiten oder zur Verarbeitung an den Treiber weiterleiten

Bei Windows und Mac OS X sind ODBC-Treiber-Manager im Betriebssystem enthalten. Die meisten Implementierungen von ODBC-Treiber-Managern umfassen auch eine Administrationsanwendung, um die Konfiguration von DSN und Treibern zu vereinfachen. Beispiele und Informationen zu diesen Managern, einschließlich der ODBC-Treiber-Manager von Unix, sind im Folgenden aufgelistet:

- Microsoft Windows ODBC-Treiber-Manager (`odbc32.dll`), http://www.microsoft.com/data/.

- Mac OS X enthält den `ODBC Administrator`, eine GUI-Anwendung, die einen vereinfachten Konfigurationsmechanismus für den iODBC-Treiber-Manager von Unix zur Verfügung stellt. Sie können DSN- und Treiber-Informationen entweder über den ODBC-Administrator oder durch die iODBC-Konfigurationsdateien in Erfahrung bringen. Das bedeutet auch, dass Sie die ODBC Administrator-Konfigurationen mit dem Befehl `iodbctest` testen können. http://www.apple.com.

- `unixODBC`-Treiber-Manager für Unix (`libodbc.so`). Siehe weitere Informationen unter http://www.unixodbc.org. Ab der Version `unixODBC` 2.1.2 ist der MyODBC-Treiber 3.51 im Installationspaket des `unixODBC`-Treiber-Managers enthalten.

- Über den `iODBC`-ODBC-Treiber-Manager für Unix (`libiodbc.so`) finden Sie weitere Informationen unter http://www.iodbc.org.

### 25.1.2. Installation von MyODBC

Die MyODBC-Treiber können Sie mit zwei verschiedenen Methoden installieren, nämlich entweder als Binär- oder als Quellinstallation. Die Binärinstallation ist die einfachste. Eine Quellinstallation dürfte nur auf Plattformen notwendig sein, für die kein Binärinstallationspaket zur Verfügung steht oder wenn Sie den Installationsprozess oder die MyODBC-Treiber vor der Installation modifizieren möchten.

#### 25.1.2.1. Woher man MyODBC bekommt

Die MySQL AB vertreibt alle ihre Produkte unter der General Public License (GPL). Die neueste Version der MyODBC-Binär- und Quelldateien erhalten Sie auf der Website von MySQL AB unter http://dev.mysql.com/downloads/.

Weitere Informationen über MyODBC finden Sie unter http://www.mysql.com/products/myodbc/.

Über die Lizenzen können Sie sich unter http://www.mysql.com/company/legal/licensing/ informieren.

#### 25.1.2.2. Unterstützte Plattformen

MyODBC kann auf allen von MySQL unterstützten Plattformen verwendet werden, als da sind:

- Windows 95, 98, Me, NT, 2000, XP und 2003

- Alle Unix-ähnlichen Betriebssysteme, darunter AIX, Amiga, BSDI, DEC, FreeBSD, HP-UX 10/11, Linux, NetBSD, OpenBSD, OS/2, SGI Irix, Solaris, SunOS, SCO OpenServer, SCO UnixWare, Tru64 Unix

- Mac OS X und Mac OS X Server

Wenn für eine bestimmte Plattform keine Binärdistribution verfügbar ist, schlagen Sie bitte Abschnitt 25.1.2.4, „MyODBC von einer Quelldistribution installieren“, nach, um den Treiber aus dem Originalquellcode zu erstellen. Die Binärdateien, die Sie aus diesem Code erstellen, könnten Sie dann MySQL zugänglich machen, indem Sie eine E-Mail an `<myodbc@lists.mysql.com>` schicken. So können auch andere diese Binärdateien nutzen.

#### 25.1.2.3. MyODBC von einer Binärdistribution installieren

Am einfachsten lässt sich MyODBC von einer Binärdistribution installieren. Wenn Sie mehr Kontrolle über den Treiber oder das Installationsverzeichnis bekommen oder einzelne Elemente des Treibers an Ihre Bedürfnisse anpassen möchten, müssen Sie ihn aus den Quelldateien erstellen. Siehe hierzu Abschnitt 25.1.2.4, „MyODBC von einer Quelldistribution installieren“.

##### 25.1.2.3.1. Installation von MyODBC aus einer Binärdistribution unter Windows

Bevor Sie die MyODBC-Treiber auf Windows installieren, sollten Sie sicherstellen, dass Ihre Microsoft Data Access Components (MDAC) auf dem neuesten Stand sind. Die aktuellste Version erhalten Sie auf der Website Microsoft Data Access and Storage.

Für die Windows-Installation stehen drei Distributionstypen zur Verfügung. Der Inhalt ist immer derselbe; nur die Installationsmethode ist unterschiedlich.

- Der gezippte Installer besteht aus einem Zip-Archiv mit einer eigenständigen Installationsanwendung. Um dieses Paket zu installieren, packen Sie den Installer aus und führen die Installationsanwendung aus. Unter Abschnitt 25.1.2.3.1.1, „Windows MyODBC-Treiber mit einem Installer installieren“, erfahren Sie, wie die Installation fertig gestellt wird.

- MSI-Installer ist eine Installationsdatei zur Verwendung mit dem Installer, der in Windows 2000, Windows XP und Windows Server 2003 enthalten ist. Unter Abschnitt 25.1.2.3.1.1, „Windows MyODBC-Treiber mit einem Installer installieren“, erfahren Sie, wie die Installation fertig gestellt wird.

- Das gezippte DLL-Paket enthält die DLL-Dateien, die manuell installiert werden müssen. Unter Abschnitt 25.1.2.3.1.2, „Windows MyODBC-Treiber mit dem DLL-Zip-Archiv installieren“, erfahren Sie, wie die Installation fertig gestellt wird.

###### 25.1.2.3.1.1. Windows MyODBC-Treiber mit einem Installer installieren

Die Installer-Programme bieten ein sehr einfaches Mittel zur Installation der MyODBC-Treiber. Wenn Sie den gezippten Installer heruntergeladen haben, müssen Sie die Installer-Anwendung noch auspacken. Der grundlegende Installationsprozess ist für beide Installer derselbe.

Um die Installation abzuschließen, gehen Sie folgendermaßen vor:

1. Setzen Sie einen Doppelklick auf den extrahierten Installer oder die heruntergeladene MSI-Datei.

2. Dadurch wird der MySQL Connector/ODBC 3.51 - Setup Wizard gestartet. Klicken Sie auf Next, um den Installationsprozess zu starten.

3. Nun wählen Sie den Installationstyp. Die typische Installation liefert die Standarddateien, die für eine ODBC-Verbindung mit einer MySQL-Datenbank benötigt werden. Die Complete-Option installiert sämtliche verfügbaren Dateien einschließlich Debugging und Hilfsprogrammen. Wir empfehlen, eine dieser beiden Optionen zu nutzen. Danach klicken Sie auf Next und machen mit Schritt 5 weiter.

   Sie können auch eine benutzerdefinierte (Custom) Installation verlangen, bei der Sie die zu installierenden Komponenten selbst auswählen können. Wenn Sie diese Methode ausgewählt haben, klicken Sie auf Next und gehen zu Schritt 4.

4. Wenn Sie sich für eine benutzerdefinierte Installation entschieden haben, wählen Sie in den Popup-Fenstern aus, welche Komponenten Sie installieren möchten, und klicken dann auf Next, um die notwendigen Dateien zu installieren.

5. Wenn die Dateien auf Ihren Computer kopiert worden sind, ist die Installation abgeschlossen. Klicken Sie auf Finish, um den Installer zu schließen.

Nun ist die Installation fertig und Sie können beginnen, Ihre ODBC-Verbindungen gemäß Abschnitt 25.1.3, „MyODBC: Konfiguration“, zu konfigurieren.

###### 25.1.2.3.1.2. Windows MyODBC-Treiber mit dem DLL-Zip-Archiv installieren

Wenn Sie das DLL-Paket als Zip-Archiv heruntergeladen haben, müssen Sie die einzelnen Dateien, die für MyODBC erforderlich sind, manuell installieren. Nach dem Auspacken der Installationsdateien können Sie dies entweder selbst tun, indem Sie jede notwendige Anweisung einzeln ausführen, oder die mitgelieferte Batch-Datei für eine Installation in den Standardverzeichnissen nutzen.

Installation mithilfe der Batch-Datei:

1. Extrahieren Sie das MyODBC Zipped DLL-Paket.

2. Öffnen Sie ein Befehlseingabefenster.

3. Gehen Sie in das Verzeichnis, das beim Extrahieren des MyODBC Zipped DLL-Pakets angelegt wurde.

4. Führen Sie `Install.bat` aus:

       C:\> Install.bat

   Dieser Befehl kopiert die notwendigen Dateien in das Standardverzeichnis und registriert dann den MyODBC-Treiber beim Windows ODBC-Manager.

Wenn Sie die Dateien in ein anderes Verzeichnis kopieren möchten, etwa um unterschiedliche Versionen des MyODBC-Treibers auf demselben Computer auszuführen oder zu testen, dann müssen Sie die Dateien manuell kopieren. Allerdings kann man nur davon abraten, sie in ein anderes als das Standardverzeichnis zu installieren. Um die Dateien von Hand in das Standardinstallationsverzeichnis zu kopieren, verfahren Sie folgendermaßen:

1. Extrahieren Sie das MyODBC Zipped DLL-Paket.

2. Öffnen Sie ein Befehlseingabefenster.

3. Gehen Sie in das Verzeichnis, das beim Extrahieren des MyODBC Zipped DLL-Pakets angelegt wurde.

4. Kopieren Sie die Bibliotheksdateien in ein passendes Verzeichnis. Standardmäßig werden sie in das Systemverzeichnis von Windows kopiert, nämlich `\Windows\System32`:

       C:\> copy lib\myodbc3S.dll \Windows\System32
       C:\> copy lib\myodbc3S.lib \Windows\System32
       C:\> copy lib\myodbc3.dll \Windows\System32
       C:\> copy lib\myodbc3.lib \Windows\System32

5. Kopieren Sie die MyODBC-Tools. Diese müssen in ein Verzeichnis gesetzt werden, das im System-`PATH` liegt. Standardmäßig werden sie in das Systemverzeichnis von Windows installiert, nämlich `\Windows\System32`:

       C:\> copy bin\myodbc3i.exe \Windows\System32
       C:\> copy bin\myodbc3m.exe \Windows\System32
       C:\> copy bin\myodbc3c.exe \Windows\System32

6. Optional können Sie auch die Hilfedateien kopieren. Damit diese im Hilfe-System zugänglich sind, müssen sie im Windows-Systemverzeichnis installiert werden:

       C:\> copy doc\*.hlp \Windows\System32

7. Zum Schluss registrieren Sie den MyODBC-Treiber beim ODBC-Manager:

       C:\> myodbc3i -a -d -t"MySQL ODBC 3.51 Driver;\
         DRIVER=myodbc3.dll;SETUP=myodbc3S.dll"

   Wenn Sie die Dateien nicht im Standardverzeichnis installiert haben, müssen Sie bei diesem Befehl die Verweise auf die DLL-Dateien und den Ort des Befehls entsprechend ändern.

###### 25.1.2.3.1.3. Umgang mit Installationsfehlern

Auf Windows wird eventuell folgender Fehler gemeldet, wenn Sie versuchen, den älteren MyODBC 2.50-Treiber zu installieren:

    An error occurred while copying C:\WINDOWS\SYSTEM\MFC30.DLL.
    Restart Windows and try installing again (before running any
    applications which use ODBC)

Dieser Fehler tritt auf, wenn eine andere Anwendung gerade das ODBC-System benutzt. Windows erlaubt Ihnen dann vielleicht nicht, die Installation abzuschließen. In den meisten Fällen können Sie jedoch mit einem Klick auf `Ignorieren` fortfahren, den Rest der MyODBC-Dateien zu kopieren, und das Ergebnis der Installation sollte funktionieren. Wenn nicht, so fahren Sie Ihren Computer im „abgesicherten Modus“ wieder hoch. Diesen Modus steuern Sie an, indem Sie beim Booten, unmittelbar bevor Windows gestartet wird, auf F8 drücken. Installieren Sie sodann die MyODBC-Treiber und starten Sie den Computer im Normalmodus neu.

##### 25.1.2.3.2. Installation von MyODBC aus einer Binärdistribution unter Unix

Es gibt zwei Methoden, um MyODBC auf Unix von einer Binärdistribution zu installieren. Für die meisten Unix-Umgebungen wird die Tarball-Distribution benötigt. Für Linux-Systeme steht außerdem eine RPM-Distribution zur Verfügung.

###### 25.1.2.3.2.1. Installation von MyODBC aus einer beinären Tarball-Distribution

Um den Treiber von einer Tarball-Distribution zu installieren (die Datei `.tar.gz`), laden Sie die neueste Treiberversion für Ihr Betriebssystem herunter und halten sich an die folgenden Schritte (gezeigt wird das Vorgehen mit einer Linux-Version des Tarballs):

    shell> su root
    shell> gunzip MyODBC-3.51.11-i686-pc-linux.tar.gz
    shell> tar xvf MyODBC-3.51.11-i686-pc-linux.tar
    shell> cd MyODBC-3.51.11-i686-pc-linux

Lesen Sie die Installationsanweisungen in der Datei `INSTALL-BINARY` und führen Sie folgende Befehle aus.

    shell> cp libmyodbc* /usr/local/lib
    shell> cp odbc.ini /usr/local/etc
    shell> export ODBCINI=/usr/local/etc/odbc.ini

Dann fahren Sie mit Abschnitt 25.1.3.4, „Konfiguration einer MyODBC-DSN unter Unix“, fort, um den DSN für MyODBC zu konfigurieren. Weitere Informationen finden Sie in der Datei `INSTALL-BINARY` aus Ihrer Distribution.

###### 25.1.2.3.2.2. Installation von MyODBC aus einer RPM-Distribution

Um MyODBC von einer RPM-Distribution auf Linux zu installieren oder zu aktualisieren, laden Sie einfach die RPM-Distribution der neuesten MyODBC-Version herunter und halten sich an die nachfolgenden Anleitungen. Zuerst müssen Sie mit su root der `root`-User werden und dann können Sie die RPM-Datei installieren.

Wenn es sich um eine Erstinstallation handelt:

    shell> su root
     shell> rpm -ivh MyODBC-3.51.12.i386.rpm

Wenn der Treiber bereits existiert und nur aktualisiert werden soll:

    shell> su root
    shell> rpm -Uvh MyODBC-3.51.12.i386.rpm

Falls ein Fehler in den Abhängigkeiten der MySQL-Clientbibliothek `libmysqlclient` gemeldet wird, übergehen Sie ihn einfach, indem Sie die Option `--nodeps` einstellen, und sorgen dafür, dass die gemeinsame MySQL-Clientbibliothek im Pfad oder mit `LD_LIBRARY_PATH` eingestellt ist.

So werden die Treiberbibliotheken und zugehörigen Dokumente in `/usr/local/lib` und `/usr/share/doc/MyODBC` installiert. Machen Sie nun weiter mit Abschnitt 25.1.3.4, „Konfiguration einer MyODBC-DSN unter Unix“.

Um den Treiber zu deinstallieren, müssen Sie als `root` einen rpm-Befehl ausführen:

    shell> su root
    shell> rpm -e MyODBC

##### 25.1.2.3.3. MyODBC auf Mac OS X installieren

Mac OS X basiert auf dem Betriebssystem FreeBSD. Normalerweise können Sie den MySQL-Netzwerkanschluss benutzen, um sich mit MySQL Servern auf anderen Hosts zu verbinden. Die Installation des MyODBC-Treibers versetzt Sie in die Lage, sich mit MySQL-Datenbanken auf jeder beliebigen Plattform über die ODBC-Schnittstelle zu verbinden. Den MyODBC-Treiber müssen Sie nur dann installieren, wenn Ihre Anwendung eine ODBC-Schnittstelle benötigt. Zu den Anwendungen, die ODBC (und somit auch den MyODBC-Treiber) erfordern oder nutzen können, gehören ColdFusion, Filemaker Pro, 4th Dimension und viele andere mehr.

Mac OS X enthält einen eigenen ODBC-Manager, der auf dem `iODBC`-Manager basiert. Mac OS X hat ein Administrationstool, das die Administration von ODBC-Treibern und die Konfiguration erleichtert, wobei die zugrunde liegenden `iODBC`-Konfigurationsdateien aktualisiert werden.

###### 25.1.2.3.3.1. MyODBC-Treiber installieren

MyODBC kann auf einem Mac OS X oder Mac OS X Server mithilfe der Binärdistribution installiert werden. Dieses Paket steht als komprimierte Disk Image-Datei (`.dmg`) zur Verfügung. Um MyODBC mit dieser Methode zu installieren, verfahren Sie wie folgt:

1. Laden Sie die Datei auf Ihren Computer herunter und führen Sie einen Doppelklick auf die Image-Datei aus.

2. Dort finden Sie ein Installer-Paket (mit der Erweiterung `.pkg`). Mit einem Doppelklick auf diese Datei starten Sie den Mac OS X-Installer.

3. Wenn Sie die Grußbotschaft sehen, klicken Sie auf Continue, um den Installationsprozess zu starten.

4. Bitte nehmen Sie sich ein wenig Zeit, um die wichtigen Informationen (Important Information) zu lesen, denn sie enthalten eine Anleitung für den weiteren Installationsprozess. Wenn Sie eine Verbindung zu einer MySQL-Datenbank testen möchten, müssen Sie den Standort Ihres MySQL Servers kennen und einen Benutzernamen und ein Passwort haben, um einen zum Testen der Installation geeigneten DSN zu erhalten. Ein solcher Test ist jedoch nicht erforderlich, um die Installation abzuschließen. Wenn Sie die Hinweise gelesen und die notwendigen Informationen gesammelt haben, klicken Sie auf Continue.

5. MyODBC-Treiber unterliegen der GNU General Public License. Bitte lesen Sie die Lizenz, wenn Sie sie noch nicht kennen, ehe Sie mit der Installation fortfahren. Mit einem Klick auf Continue akzeptieren Sie die Lizenz (hier werden Sie noch einmal zur Bestätigung aufgefordert) und setzen die Installation fort.

6. Wählen Sie ein Installationsverzeichnis für die MyODBC-Treiber und die ODBC Administrator-Anwendung. Sie müssen die Dateien auf einem Laufwerk mit einem Betriebssystem installieren, sodass Sie unter Umständen nicht viele Auswahlmöglichkeiten haben. Wählen Sie das Laufwerk, das Sie benutzen möchten, und klicken Sie auf Continue.

7. Der Installer wählt automatisch die Dateien aus, die auf Ihrem Computer installiert werden müssen. Um fortzufahren, klicken Sie auf Install. Der Installer kopiert nun die erforderlichen Dateien auf Ihren Computer. Eine Fortschrittsanzeige informiert Sie über den Installationsfortschritt.

8. Nach Abschluss der Installation sehen Sie ein Fenster wie das unten abgebildete. Klicken Sie auf Close, um den Installer zu beenden.

#### 25.1.2.4. MyODBC von einer Quelldistribution installieren

Wenn Sie MyODBC von einer Quelldistribution installieren, haben Sie mehr Einfluss auf den Inhalt und das Installationsverzeichnis der MyODBC-Komponenten. Außerdem können Sie dann MyODBC auch auf Plattformen installieren, für die keine vorkompilierte Binärversion verfügbar ist.

MyODBC-Quelldateien erhalten Sie entweder als Download oder über das Revisionskontrollsystem, das die MyODBC-Entwickler benutzen.

##### 25.1.2.4.1. Installation von MyODBC aus einer Quelldistribution unter Windows

Auf Windows müsste eine Quellinstallation von MyODBC nur dann nötig sein, wenn Sie die Quelle oder die Installation ändern möchten. Wenn Sie unsicher sind, ob Sie von Quelldateien installieren sollten, verwenden Sie besser die Binärinstallation, die in Abschnitt 25.1.2.3.1, „Installation von MyODBC aus einer Binärdistribution unter Windows“, beschrieben ist.

Für eine Quellinstallation von MyODBC auf Windows sind verschiedene Tools und Pakete erforderlich:

- MDAC, Microsoft Data Access SDK von http://www.microsoft.com/data/.

- Ein geeigneter C-Compiler, wie etwa Microsoft Visual C++ oder der C-Compiler von Microsoft Visual Studio.

- Ein kompatibles `make`-Tool. In den Beispielen dieses Abschnitts wird `nmake` von Microsoft eingesetzt.

- MySQL-Clientbibliotheken und Include-Dateien von MySQL 4.0.0 oder höher (vorzugsweise MySQL 4.0.16 oder höher). Diese sind notwendig, weil MyODBC neue Aufrufe und Strukturen verwendet, die erst ab dieser Version der Bibliothek vorhanden sind. Die MySQL-Clientbibliotheken und Include-Dateien erhalten Sie von http://dev.mysql.com/downloads/.

###### 25.1.2.4.1.1. Bauen von MyODBC 3.51

MyODBC-Quelldistributionen enthalten `Makefiles`, für die nmake oder die `make`-Utility notwendig ist. Die Distribution enthält `Makefile`, um die Release-Version, und `Makefile_debug`, um Debugging-Versionen der Treiberbibliotheken und DLLs zu bauen.

Den Treiber bauen Sie wie folgt:

1. Sie laden die Quelldateien herunter und extrahieren sie in einen Ordner. Dann gehen Sie in dieses Verzeichnis. Der folgende Befehl geht davon aus, dass der Ordner `myodbc3-src` heißt:

       C:\> cd myodbc3-src

2. Sie editieren `Makefile`, um den Pfad der MySQL-Clientbibliotheken und -Header-Dateien anzugeben. Dann erstellen und installieren Sie mit folgenden Befehlen die Release-Version:

       C:\> nmake -f Makefile
       C:\> nmake -f Makefile install

   nmake -f Makefile erstellt die Release-Version des Treibers und speichert die Binärdateien in einem Unterverzeichnis namens `Release`.

   nmake -f Makefile install installiert (kopiert) die Treiber-DLLs und Bibliotheken (`myodbc3.dll`, `myodbc3.lib`) in Ihr Systemverzeichnis.

3. Die Debugversion wird mit `Makefile_Debug` anstelle von `Makefile` erstellt:

       C:\> nmake -f Makefile_debug
       C:\> nmake -f Makefile_debug install

4. Um den Treiber sauber neu zu installieren, geben Sie Folgendes ein:

       C:\> nmake -f Makefile clean
       C:\> nmake -f Makefile install

Hinweis

- Achten Sie darauf, in den Makefiles den richtigen Pfad zu den MySQL-Clientbibliotheken und Header-Dateien anzugeben. (Hierzu müssen Sie die Variablen `MYSQL_LIB_PATH` und `MYSQL_INCLUDE_PATH` einstellen.) Der Standardpfad zur Header-Datei ist voraussichtlich `C:\mysql\include` und der Standardpfad zur Bibliothek lautet `C:\mysql\lib\opt` für Release-DLLs und `C:\mysql\lib\debug` für Debugging-Versionen.

- Mehr über die Verwendung von nmake erfahren Sie unter http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vcce4/html/evgrfRunningNMAKE.asp.

- Wenn Sie den Subversion-Baum zum Kompilieren verwenden, bekommen alle Windows-spezifischen `Makefiles` den Namen `Win_Makefile*`.

###### 25.1.2.4.1.2. Testen

Wenn die Treiberbibliotheken in das Systemverzeichnis kopiert/installiert worden sind, können Sie anhand der Beispiele aus dem Unterverzeichnis `samples` testen, ob die Bibliotheken korrekt erstellt wurden:

    C:\> cd samples
    C:\> nmake -f Makefile all

###### 25.1.2.4.1.3. Bauen von MyODBC 2.50

Die Quelldistribution MyODBC 2.50 enthält auch VC-Workspace-Dateien. Sie können den Treiber mit diesen Dateien (`.dsp` und `.dsw`) direkt bauen, indem Sie sie von Microsoft Visual Studio 6.0 oder höher laden.

##### 25.1.2.4.2. Installation von MyODBC aus einer Quelldistribution unter Unix

Folgende Tools werden benötigt, um MySQL auf Unix aus der Quelldistribution zu erstellen:

- Ein funktionierender ANSI C++-Compiler. gcc 2.95.2 oder höher, egcs 1.0.2 oder höher oder egcs 2.91.66, SGI C++ und SunPro C++ sind Beispiele für funktionierende Compiler.

- Ein gutes make-Programm. Das make von GNU ist immer empfehlenswert und manchmal sogar obligatorisch.

- MySQL-Clientbibliotheken und Include-Dateien von MySQL 4.0.0 oder höher (vorzugweise MySQL 4.0.16 oder höher). Diese sind notwendig, weil MyODBC neue Aufrufe und Strukturen benutzt, die erst ab dieser Version der Bibliothek zur Verfügung stehen. Sie erhalten die MySQL-Clientbibliotheken und Include-Dateien unter http://dev.mysql.com/downloads/.

  Wenn Sie einen eigenen MySQL Server und/oder Clientbibliotheken aus den Quelldateien gebaut haben, müssen Sie bei der Erstellung der Bibliotheken `configure` mit der Option `--enable-thread-safe-client` verwendet haben.

  Außerdem müssen Sie sich vergewissern, dass die Bibliothek `libmysqlclient` als Shared Library gebaut und installiert wurde.

- Ein kompatibler ODBC-Manager muss installiert sein. Von MyODBC ist bekannt, dass es mit den Managern `iODBC` und `unixODBC` funktioniert. Siehe auch Abschnitt 25.1.1.2.2, „ODBC-Treiber-Manager“.

- Wenn Sie einen Zeichensatz verwenden, der nicht in die MySQL-Clientbibliothek kompiliert ist, müssen Sie die MySQL-Zeichendefinitionen aus dem Verzeichnis `charsets` in `SHAREDIR` installieren (nach Voreinstellung ist dies `/usr/local/mysql/share/mysql/charsets`). Wenn Sie den MySQL Server auf demselben Computer installiert haben, müssten die Zeichendefinitionen vorhanden sein. Mehr über Unterstützung von Zeichensätzen erfahren Sie unter Kapitel 10, Zeichensatz-Unterstützung.

Wenn Sie alle erforderlichen Dateien beisammen haben, extrahieren Sie die Quelldateien in ein getrenntes Verzeichnis. Danach führen Sie configure aus und erstellen mit make die Bibliothek.

###### 25.1.2.4.2.1. Typische configure-Optionen

Das configure-Skript gibt Ihnen viel Einfluss auf die Konfiguration Ihres MyODBC-Builds. Diesen Einfluss üben Sie aus, indem Sie auf der Kommandozeile Optionen für configure benutzen. Außerdem können Sie configure mit gewissen Umgebungsvariablen beeinflussen. Eine Liste der Optionen und Umgebungsvariablen für configure liefert Ihnen folgender Befehl:

    shell> ./configure --help

Die gebräuchlichsten Optionen für configure werden im Folgenden beschrieben:

1. Um MyODBC zu kompilieren, müssen Sie den Pfad zu den Include- und Bibliotheksdateien des MySQL-Clients mit der Option `--with-mysql-path=`DIR`` angeben, wobei `DIR` das Verzeichnis ist, in dem MySQL installiert wurde.

   Die Optionen zum Kompilieren von MySQL ermitteln Sie, indem Sie ``DIR`/bin/mysql_config` ausführen.

2. Geben Sie den Standardpfad für die Header- und Bibliotheksdateien für Ihren ODBC-Treiber-Manager an (`iODBC` oder `unixODBC`).

   - Wenn Sie `iODBC` benutzen, aber nicht im Standardverzeichnis (`/usr/local`) installiert haben, müssen Sie eventuell die Option `--with-iodbc=`DIR`` angeben, wobei `DIR` das Verzeichnis ist, in dem `iODBC` installiert wurde.

     Liegen die `iODBC`-Header nicht unter ``DIR`/include`, können Sie ihren Speicherort mit der Option `--with-iodbc-includes=`INCDIR`` angeben.

     Dies gilt auch für Bibliotheken. Wenn sie nicht unter ``DIR`/lib` zu finden sind, können Sie die Option `--with-iodbc-libs=`LIBDIR`` verwenden.

   - Wenn Sie `unixODBC` nutzen, verwenden Sie die Option `--with-unixODBC=`DIR`` (Groß- und Kleinschreibung beachten!), damit configure standardmäßig nach `unixODBC` statt nach `iODBC` sucht. `DIR` ist das Verzeichnis, wo `unixODBC` installiert ist.

     Wenn die `unixODBC`-Header und Bibliotheken nicht in ``DIR`/include` und ``DIR`/lib` liegen, müssen Sie die Optionen `--with-unixODBC-includes=`INCDIR`` und `--with-unixODBC-libs=`LIBDIR`` einstellen.

3. Vielleicht möchten Sie ein anderes Installationspräfix als `/usr/local` vorgeben. Wenn Sie zum Beispiel die MyODBC-Treiber in `/usr/local/odbc/lib` installieren möchten, setzen Sie die Option `--prefix=/usr/local/odbc`.

Zum Schluss sieht der Konfigurationsbefehl in etwa wie folgt aus:

    shell> ./configure --prefix=/usr/local \
             --with-iodbc=/usr/local \
             --with-mysql-path=/usr/local/mysql

###### 25.1.2.4.2.2. Zusätzliche Konfigurationsoptionen

Es gibt noch mehr Optionen, die Sie einstellen müssen oder können, wenn Sie den MyODBC-Treiber vor dem Build konfigurieren.

- Um den Treiber mit den Thread-sicheren Clientbibliotheken von MySQL, `libmysqlclient_r.so` oder `libmysqlclient_r.a`, zu verlinken, geben Sie folgende configure-Option an:

      --enable-thread-safe

  Deaktiviert (die Standardeinstellung) wird dies wie folgt:

      --disable-thread-safe

  Diese Option ermöglicht die Erstellung der Thread-sicheren Treiberbibliothek `libmyodbc3_r.so` durch das Verlinken mit der Thread-sicheren MySQL-Clientbibliothek `libmysqlclient_r.so` (die Erweiterungen hängen vom Betriebssystem ab).

  Wenn das Kompilieren mit der Thread-sicheren Option scheitert, dann möglicherweise deshalb, weil auf dem betreffenden System die richtigen Thread-Bibliotheken nicht gefunden werden konnten. Stellen Sie den Wert von `LIBS` also auf die für Ihr System passende Thread-Bibliothek ein.

      LIBS="-lpthread" ./configure ..

- Die gemeinsam genutzte und die statische Version von MyODBC werden mit folgenden Optionen aktiviert und deaktiviert:

      --enable-shared[=yes/no]
      --disable-shared
      --enable-static[=yes/no]
      --disable-static

- Nach Voreinstellung werden alle Binärdistributionen ohne Debugging gebaut (mit `--without-debug` konfiguriert).

  Um Debugging-Informationen zu erhalten, erstellen Sie den Treiber aus der Quellversion und stellen die Option `--with-debug` ein, wenn Sie configure ausführen.

- Diese Option steht nur für Quellbäume aus dem Subversion-Repository zur Verfügung, nicht für Quelldistributionen, die als Package geliefert werden.

  Nach Voreinstellung wird der Treiber mit der Option `--without-docs` gebaut. Wenn Sie die Dokumentation einrichten möchten, führen Sie configure folgendermaßen aus:

      --with-docs

###### 25.1.2.4.2.3. Bauen und Kompilieren

Um die Treiberbibliotheken zu bauen, müssen Sie nur make laufen lassen.

    shell> make

Wenn Fehler auftreten, berichtigen Sie sie und fahren im Build-Prozess fort. Ist der Build nicht möglich, senden Sie eine ausführliche E-Mail an `<myodbc@lists.mysql.com>`, um sich Hilfe zu holen.

###### 25.1.2.4.2.4. Bauen von gemeinsam genutzten (shared) Bibliotheken

Auf den meisten Plattformen werden `.so` (shared) Client-Bibliotheken standardmäßig nicht gebaut oder unterstützt. Grund dafür sind die schlechten Erfahrungen, die wir beim Erstellen von Shared Libraries gemacht haben.

In solchen Fällen müssen Sie die MySQL-Distribution herunterladen und mit folgenden Optionen konfigurieren:

    --without-server --enable-shared

Um den Treiber mit Shared Libraries zu erstellen, müssen Sie die Option `--enable-shared` für configure angeben. Standardmäßig ist diese Option für configure nicht aktiviert.

Wenn Sie den Treiber mit `--disable-shared` konfiguriert haben, können Sie aus den statischen Bibliotheken die `.so`-Datei mit folgenden Befehlen erstellen:

    shell> cd MyODBC-3.51.01
    shell> make
    shell> cd driver
    shell> CC=/usr/bin/gcc \
              $CC -bundle -flat_namespace -undefined error \
              -o .libs/libmyodbc3-3.51.01.so \
              catalog.o connect.o cursor.o dll.o error.o execute.o \
              handle.o info.o misc.o myodbc3.o options.o prepare.o \
              results.o transact.o utility.o \
              -L/usr/local/mysql/lib/mysql/ \
              -L/usr/local/iodbc/lib/ \
              -lz -lc -lmysqlclient -liodbcinst

Aus `-liodbcinst` müssen Sie `-lodbcinst` machen, wenn Sie `unixODBC` anstelle von `iODBC` nutzen. Die Bibliothekspfade müssen Sie dann auch entsprechend konfigurieren.

So wird die Datei `libmyodbc3-3.51.01.so` erstellt und in das Verzeichnis `.libs` gelegt. Diese Datei kopieren Sie in das Installationsverzeichnis der MyODBC-Bibliotheken (`/usr/local/lib`) oder in das `lib`-Verzeichnis unter dem Installationsverzeichnis, das Sie mit `--prefix` vorgegeben haben.

    shell> cd .libs
    shell> cp libmyodbc3-3.51.01.so /usr/local/lib
    shell> cd /usr/local/lib
    shell> ln -s libmyodbc3-3.51.01.so libmyodbc3.so

Die Thread-sichere Treiberbibliothek bauen Sie mit:

    shell> CC=/usr/bin/gcc \
              $CC -bundle -flat_namespace -undefined error
              -o .libs/libmyodbc3_r-3.51.01.so
              catalog.o connect.o cursor.o dll.o error.o execute.o
              handle.o info.o misc.o myodbc3.o options.o prepare.o
              results.o transact.o utility.o
              -L/usr/local/mysql/lib/mysql/
              -L/usr/local/iodbc/lib/
              -lz -lc -lmysqlclient_r -liodbcinst

###### 25.1.2.4.2.5. Installation der Treiberbibliotheken

Mit folgendem Befehl installieren Sie die Treiberbibliotheken:

    shell> make install

Damit wird eines der folgenden Bibliotheken-Sets installiert:

Für MyODBC 3.51:

- `libmyodbc3.so`

- `libmyodbc3-3.51.01.so`, wobei 3.51.01 die Treiberversion ist

- `libmyodbc3.a`

Für Thread-sicheres MyODBC 3.51:

- `libmyodbc3_r.so`

- `libmyodbc3-3_r.51.01.so`

- `libmyodbc3_r.a`

Für MyODBC 2.5.0:

- `libmyodbc.so`

- `libmyodbc-2.50.39.so`, wobei 2.50.39 die Treiberversion ist

- `libmyodbc.a`

Mehr über den Build-Prozess erfahren Sie in der Datei `INSTALL`, die mit der Quelldistribution mitgeliefert wird. Achtung: Wenn Sie den make-Befehl von Sun verwenden, können Fehler entstehen. Das gmake von GNU dagegen müsste auf allen Plattformen funktionieren.

###### 25.1.2.4.2.6. Testen von MyODBC unter Unix

Um die einfachen Beispiele in der von Ihnen gebauten Distribution mit den Bibliotheken auszuführen, geben Sie folgenden Befehl ein:

    shell> make test

Ehe Sie Tests laufen lassen, legen Sie den DSN 'myodbc3' in `odbc.ini` an und stellen die Umgebungsvariable `ODBCINI` auf die korrekte `odbc.ini`-Datei ein. Dann läuft der MySQL Server. Eine `odbc.ini`-Beispieldatei wird mit der Treiberdistribution mitgeliefert.

Sie können das Skript `samples/run-samples` auch so umschreiben, dass es die gewünschten DSN-, UID- und PASSWORD-Werte als Kommandozeilenargumente für jedes Beispiel übergibt.

###### 25.1.2.4.2.7. Bauen von MyODBC aus dem Quellcode unter Mac OS X

Um den Treiber auf Mac OS X (Darwin) zu erstellen, verwenden Sie folgendes configure-Beispiel:

    shell> ./configure --prefix=/usr/local
              --with-unixODBC=/usr/local
              --with-mysql-path=/usr/local/mysql
              --disable-shared
              --enable-gui=no
              --host=powerpc-apple

Dieser Befehl setzt voraus, dass `unixODBC` und MySQL in den Standardverzeichnissen installiert wurden. Ist dies nicht der Fall, müssen Sie die Konfiguration entsprechend ändern.

Auf Mac OS X werden mit der Option `--enable-shared` die `.dylib`-Dateien standardmäßig erstellt. Die `.so`-Dateien können Sie folgendermaßen bauen:

    shell> make
    shell> cd driver
    shell> CC=/usr/bin/gcc \
              $CC -bundle -flat_namespace -undefined error
              -o .libs/libmyodbc3-3.51.01.so *.o
              -L/usr/local/mysql/lib/
              -L/usr/local/iodbc/lib
              -liodbcinst -lmysqlclient -lz -lc

Die Thread-sichere Treiberbibliothek bauen Sie mit:

    shell> CC=/usr/bin/gcc \
              $CC -bundle -flat_namespace -undefined error
              -o .libs/libmyodbc3-3.51.01.so *.o
              -L/usr/local/mysql/lib/
              -L/usr/local/iodbc/lib
              -liodbcinst -lmysqlclienti_r -lz -lc -lpthread

Aus `-liodbcinst` müssen Sie `-lodbcinst` machen, wenn Sie `unixODBC` anstelle von `iODBC` nutzen. Die Bibliothekspfade müssen Sie dann auch entsprechend konfigurieren.

In der Apple-Version von GCC sind cc und gcc in Wirklichkeit symbolische Links zu gcc3.

Kopieren Sie diese Bibliothek in das Verzeichnis `$prefix/lib` und richten Sie einen symbolischen Link auf `libmyodbc3.so` ein.

Mit folgendem Befehl überprüfen Sie die Ausgabeeigenschaften für die gemeinsam genutzten Bibliotheken:

    shell> otool -LD .libs/libmyodbc3-3.51.01.so

###### 25.1.2.4.2.8. Bauen von MyODBC aus dem Quellcode unter HP-UX

Zur Erstellung des Treibers auf HP-UX 10.x or 11.x nutzen Sie folgendes configure-Beispiel:

Wenn cc verwendet wird:

    shell> CC="cc" \
              CFLAGS="+z" \
              LDFLAGS="-Wl,+b:-Wl,+s" \
              ./configure --prefix=/usr/local
              --with-unixodbc=/usr/local
              --with-mysql-path=/usr/local/mysql/lib/mysql
              --enable-shared
              --enable-thread-safe

Wenn gcc verwendet wird:

    shell> CC="gcc" \
              LDFLAGS="-Wl,+b:-Wl,+s" \
              ./configure --prefix=/usr/local
              --with-unixodbc=/usr/local
              --with-mysql-path=/usr/local/mysql
              --enable-shared
              --enable-thread-safe

Haben Sie den Treiber gebaut, so überprüfen Sie seine Attribute mit chatr .libs/libmyodbc3.sl, um festzustellen, ob der Pfad der MySQL-Clientbibliothek mit der Umgebungsvariablen `SHLIB_PATH` hätte eingestellt werden müssen. Bei statischen Versionen können Sie alle Optionen, die gemeinsam genutzte Bibliotheken betreffen, ignorieren und configure mit der `--disable-shared`-Option laufen lassen.

###### 25.1.2.4.2.9. MyODBC unter AIX aus dem Quellcode bauen

Um den Treiber auf AIX zu bauen, gehen Sie nach folgendem configure-Beispiel vor:

    shell> ./configure --prefix=/usr/local
              --with-unixodbc=/usr/local
              --with-mysql-path=/usr/local/mysql
              --disable-shared
              --enable-thread-safe

Hinweis: Weitere Informationen über das Bauen und Einrichten statischer und gemeinsam genutzter Bibliotheken auf unterschiedlichen Plattformen finden Sie unter Using static and shared libraries across platforms'.

##### 25.1.2.4.3. Installation von MyODBC aus dem Entwicklungsquellbaum

Achtung: Bitte lesen Sie den folgenden Abschnitt nur dann, wenn Sie daran interessiert sind, uns zu helfen oder Code zu testen. Wenn Sie MySQL Connector/ODBC lediglich auf Ihrem System ans Laufen bringen möchten, benutzen Sie bitte eine Standard-Release-Distribution.

Um auf den Quellbaum von MyODBC zugreifen zu können, müssen Sie Subversion installiert haben. Subversion ist kostenlos unter http://subversion.tigris.org/ erhältlich.

Folgende Tools sind erforderlich, um MyODBC von den Quellbäumen erstellen zu können:

- autoconf 2.52 (oder neuer)

- automake 1.4 (oder neuer)

- libtool 1.4 (oder neuer)

- m4

Den aktuellsten Quellbaum in der Entwicklung finden Sie unter unseren öffentlichen Subversion-Bäumen unter http://dev.mysql.com/tech-resources/sources.html.

Um die Connector/ODBC-Quelldateien auszuchecken, gehen Sie in das Verzeichnis, in welches Sie den zu speichernden MyODBC-Baum kopieren möchten, und geben folgenden Befehl ein:

    shell> svn co http://svn.mysql.com/svnpublic/connector-odbc3

Danach dürfte eine Kopie des gesamten MyODBC-Quellbaums im Verzeichnis `connector-odbc3` vorliegen. Auf Unix oder Linux erstellen Sie den Build aus diesen Quelldateien wie folgt:

    shell> cd connector-odbc3
    shell> aclocal
    shell> autoheader
    shell> autoconf
    shell> automake;
    shell> ./configure  # Hier geben Sie Ihre Optionen an
    shell> make

Weitere Informationen über den Build finden Sie in der Datei `INSTALL`, die in demselben Verzeichnis liegt. Über configure-Optionen können Sie unter Abschnitt 25.1.2.4.2.1, „Typische configure-Optionen“, Genaueres erfahren.

Nach dem Build führen Sie make install aus, um den MyODBC 3.51-Treiber auf Ihrem System zu installieren.

Wenn Sie bis make vorgedrungen sind, aber die Distribution sich nicht kompilieren lässt, schicken Sie bitte einen Bericht an `<myodbc@lists.mysql.com>`.

Auf Windows können Sie zur Erstellung des Treibers die Windows-Makefiles `WIN-Makefile` und `WIN-Makefile_debug` benutzen. Weiteres erfahren Sie unter Abschnitt 25.1.2.4.1, „Installation von MyODBC aus einer Quelldistribution unter Windows“.

Nach dem ersten Auschecken, mit dem Sie den Quellbaum heruntergeladen haben, sollten Sie regelmäßig svn update laufen lassen, um Ihre Quelldateien mit den neuesten Versionen zu aktualisieren.

### 25.1.3. MyODBC: Konfiguration

Bevor Sie eine Verbindung zu einer MySQL-Datenbank über den MyODBC-Treiber einrichten können, müssen Sie einen ODBC-Data Source Name (DSN) konfigurieren. Der DSN verbindet die diversen Konfigurationsparameter, die zur Kommunikation mit einer Datenbank erforderlich sind, mit einem bestimmten Namen. Um mit der Datenbank zu kommunizieren, verwenden Sie in einer Anwendung den DSN, anstatt die einzelnen Parameter in der Anwendung selbst zu konfigurieren. DSN-Informationen können benutzer- oder systemspezifisch sein, oder sie können in einer gesonderten Datei angegeben werden. Die Namen der ODBC-Datenquellen werden je nach Plattform und ODBC-Treiber unterschiedlich konfiguriert.

#### 25.1.3.1. Namen für Datenquellen (DSN)

Mit einem Data Source Name sind die Konfigurationsparameter für die Kommunikation mit einer bestimmten Datenbank verbunden. Normalerweise besteht ein DSN aus folgenden Parametern:

- Name
- Hostname
- Datenbankname
- Login-Name
- Passwort

Zusätzlich können verschiedene ODBC-Treiber, darunter auch MyODBC, weitere treiberspezifische Optionen und Parameter haben.

Es gibt drei DSN-Typen:

- Ein System-DSN ist eine globale DSN-Definition, die jedem Benutzer und jeder Anwendung auf einem bestimmten System zur Verfügung steht. Ein System-DSN kann normalerweise nur von einem Systemadministrator konfiguriert werden, oder aber von einem Benutzer, der die speziellen Berechtigungen zur Erstellung von System-DSNs hat.

- Ein User-DSN ist für einen einzelnen Benutzer spezifisch und dient der Speicherung von Datenbankverbindungsinformationen, die dieser Benutzer regelmäßig verwendet.

- Ein File-DSN definiert die DSN-Konfiguration in einer einfachen Datei. File-DSNs können von Benutzern und Computern gemeinsam genutzt werden und sind daher praktischer, wenn DSN-Informationen als Teil einer Anwendung auf mehreren Computern installiert oder verteilt werden sollen.

DSN-Informationen werden je nach Plattform und Umgebung an unterschiedlichen Speicherorten abgelegt.

#### 25.1.3.2. Konfiguration einer MyODBC-DSN unter Windows

Mit dem `ODBC-Datenquellen-Administrator` von Windows können Sie DSNs anlegen, die Treiberinstallation überprüfen und ODBC-Systeme wie etwa Tracing (Ablaufverfolgung, dient dem Debugging) und Verbindungspooling einrichten.

Verschiedene Ausgaben und Versionen von Windows speichern den `ODBC-Datenquellen-Administrator` an verschiedenen Orten, je nach der verwendeten Windows-Version.

Den `ODBC-Datenquellen-Administrator` in Windows Server 2003 öffnen:

1. Wählen Sie im Startmenü `Verwaltung` und klicken Sie auf `Datenquellen (ODBC)`.

Den `ODBC-Datenquellen-Administrator` in Windows 2000 Server oder Windows 2000 Professional öffnen:

1. Wählen Sie im Startmenü `Einstellungen` und klicken Sie auf `Systemsteuerung`.

2. In der `Systemsteuerung` klicken Sie auf `Verwaltung`.

3. In der `Verwaltung` klicken Sie auf `Datenquellen (ODBC)`.

Den `ODBC-Datenquellen-Administrator` in Windows XP öffnen:

1. Klicken Sie im Startmenü auf `Systemsteuerung`.

2. In der `Systemsteuerung` klicken Sie, wenn die Kategorienansicht eingestellt ist, auf `Leistung und Wartung` und dann auf `Verwaltung`. Wenn Sie die Klassische Ansicht für die Systemsteuerung eingestellt haben, klicken Sie hier direkt auf `Verwaltung`.

3. In der `Verwaltung` klicken Sie auf `Datenquellen (ODBC)`.

Unabhängig von der Windows-Version müssten Sie nun das Fenster des `ODBC-Datenquellen-Administrators` vor sich sehen:

In Windows XP können Sie den Ordner `Verwaltung` Ihrem Startmenü hinzufügen, um den ODBC-Datenquellen-Administrator später leichter finden zu können:

1. Klicken Sie mit rechts auf die Schaltfläche Start.

2. Wählen Sie `Eigenschaften`.

3. Klicken Sie auf Anpassen....

4. Wählen Sie die Registerkarte Erweitert.

5. Markieren Sie unter `Startmenüelemente` im Abschnitt `Systemverwaltung` den Punkt `Im Menü "Alle Programme" anzeigen`.

In Windows Server 2003 und Windows XP können Sie den `ODBC-Datenquellen-Administrator` auch dauerhaft Ihrem Startmenü hinzufügen. Hierzu suchen Sie wie oben beschrieben das Symbol `Datenquellen (ODBC)`, klicken mit rechts darauf und wählen dann An Startmenü anheften.

##### 25.1.3.2.1. Einen MyODBC-DSN auf Windows einrichten

Zum Hinzufügen und Konfigurieren einer neuen MyODBC-Datenquelle auf Windows benutzen Sie den `ODBC-Datenquellen-Administrator`:

1. Öffnen Sie den `ODBC-Datenquellen-Administrator`.

2. Um einen System-DSN hinzuzufügen (der allen Benutzern zugänglich ist), wählen Sie die Registerkarte `System DSN`. Einen Benutzer-DSN, der ausschließlich für den aktuellen Benutzer zur Verfügung steht, erstellen Sie mit einem Klick auf Hinzufügen....

3. Sie müssen den ODBC-Treiber für diesen DSN auswählen.

   Wählen Sie `MySQL ODBC 3.51 Driver` und klicken Sie dann auf `Finish`.

4. Nun müssen Sie noch die spezifischen Felder für den DSN im Dialog `Add Data Source Name` anlegen.

   Im Feld `Data Source Name` geben Sie den Namen der Datenquelle ein, auf die Sie zugreifen möchten. Das kann jeder gültige Name Ihrer Wahl sein.

5. In das Feld `Description` geben Sie einen Text ein, der dabei hilft, die Verbindung zu identifizieren.

6. In das Feld `Server` geben Sie den Namen des MySQL Serverhosts ein, auf den Sie zugreifen möchten. Nach Voreinstellung ist dies `localhost`.

7. In das Feld `User` geben Sie den Benutzernamen für diese Verbindung ein.

8. In das Feld `Password` geben Sie das Passwort für diese Verbindung ein.

9. Im Popup-Fenster `Database` müsste automatisch eine Liste der Datenbanken erscheinen, auf die der Benutzer ein Zugriffsrecht hat.

10. Mit einem Klick auf OK wird der DSN gespeichert.

Eine vollständige DSN-Konfiguration kann folgendermaßen aussehen:

##### 25.1.3.2.2. MyODBC-DSN-Konfiguration auf Windows überprüfen

Um die Verbindung mit den von Ihnen eingegebenen Parametern zu überprüfen, klicken Sie auf Test. Lässt sich die Verbindung problemlos einrichten, erscheint ein Dialog mit der Meldung `Success; connection was made!` (abhängig von den Spracheinstellungen auch auf Deutsch).

Wenn die Verbindung nicht zustande kam, können Sie Informationen über den Test und die Gründe seines Scheiterns mit einem Klick auf Diagnostics einholen. Es werden dann zusätzliche Fehlermeldungen angezeigt.

##### 25.1.3.2.3. MyODBC-DSN-Konfigurationsoptionen

Sie können eine Reihe von Optionen für einen konkreten DSN einstellen, indem Sie im DSN-Konfigurationsdialog entweder eine der Registerkarten Connect Options oder Advanced anklicken.

Den Dialog Connect Options sehen Sie unten.

Folgende drei Optionen können konfiguriert werden:

- `Port` ist die Nummer des TCP/IP-Ports, der zur Kommunikation mit MySQL genutzt wird. Normalerweise wird nach Voreinstellung der Port 3306 verwendet. Wenn für Ihren Server ein anderer TCP/IP-Port konfiguriert ist, müssen Sie dessen Portnummer hier angeben.

- `Socket` stellt den Namen oder Ort eines bestimmten Sockets oder einer Windows-Pipe ein, die für die Kommunikation mit MySQL benutzt wird.

- `Initial Statement` definiert eine SQL-Anweisung, die beim Aufbau einer Verbindung zu MySQL ausgeführt wird. Das können Sie nutzen, um MySQL-Optionen für Ihre Verbindung anzugeben, etwa den Standardzeichensatz oder die Datenbank, die für diese Verbindung verwendet werden soll.

Auf der Registerkarte Advanced können Sie MyODBC-Verbindungsparameter einstellen. Informationen über die Bedeutung dieser Optionen finden Sie unter Abschnitt 25.1.3.5, „MyODBC: Verbindungsparameter“.

##### 25.1.3.2.4. Fehler und ihre Behebung

Dieser Abschnitt beantwortet Fragen im Zusammenhang mit MyODBC-Verbindungen.

- Beim Konfigurieren eines MyODBC-DSN tritt der Fehler `Could Not Load Translator or Setup Library` auf

  Weitere Informationen finden Sie im MS Knowledge Base Article(Q260558) . Bitte stellen Sie außerdem sicher, dass Sie die neueste gültige `ctl3d32.dll` in Ihrem Systemverzeichnis haben.

- Auf Windows wird für eine optimale Performance die `myodbc3.dll` kompiliert. Wenn Sie MyODBC 3.51 debuggen möchten (etwa um Tracing zu ermöglichen), sollten Sie stattdessen `myodbc3d.dll` verwenden. Um diese Datei zu installieren, kopieren Sie `myodbc3d.dll` über die installierte `myodbc3.dll`-Datei. Achten Sie darauf, die Treiber-DLL auf die Release-Version zurückzustellen, wenn Sie mit dem Debuggen fertig sind, da die Debugging-Version Leistungsprobleme verursachen kann. Beachten Sie, dass die `myodbc3d.dll`-Datei in den MyODBC-Versionen 3.51.07 bis 3.51.11 nicht inbegriffen ist. Wenn Sie eine dieser Versionen benutzen, müssen Sie die DLL aus einer Vorversion herüberkopieren (zum Beispiel aus 3.51.06).

  Für MyODBC 2.50 werden stattdessen `myodbc.dll` und `myodbcd.dll` verwendet.

#### 25.1.3.3. Konfiguration einer MyODBC-DSN unter Mac OS X

Um einen DSN unter Mac OS X zu konfigurieren, verwenden Sie den ODBC Administrator. Arbeiten Sie mit Mac OS X 10.2 oder älter, schauen Sie in Abschnitt 25.1.3.4, „Konfiguration einer MyODBC-DSN unter Unix“. Bitte wählen Sie aus, ob Sie einen User DSN oder einen System DSN anlegen möchten. Wenn Sie einen System DSN wollen, müssen Sie sich unter Umständen authentifizieren. Hierzu klicken Sie auf das Vorhängeschlosssymbol und geben einen Benutzernamen und ein Passwort mit Administratorrechten an.

1. Öffnen Sie den ODBC Administrator im `Utilities`-Ordner im Verzeichnis `Applications`.

2. Klicken Sie unter User DSN oder System DSN auf Add.

3. Wählen Sie den MyODBC-Treiber und klicken Sie auf OK.

4. Nun sehen Sie das Dialogfeld `Data Source Name`. Geben Sie hier den `Data Source Name` und eine optionale Beschreibung in das Feld `Description` für den DSN ein.

5. Mit einem Klick auf Add fügen Sie dem Panel ein neues Schlüsselwort/Wert-Paar hinzu. Sie sollten mindestens vier solcher Paare konfigurieren, nämlich für die Verbindungsparameter `server`, `username`, `password` und `database`. Siehe Abschnitt 25.1.3.5, „MyODBC: Verbindungsparameter“.

6. Mit einem Klick auf OK fügen Sie den DSN der Liste der konfigurierten Datenquellennamen hinzu.

Eine vollständige DSN-Konfiguration sieht in etwa folgendermaßen aus:

Sie können auch noch weitere ODBC-Optionen für Ihren DSN einrichten, indem Sie weitere Schlüsselwort/Wert-Paare anlegen und die entsprechenden Werte einstellen. Siehe hierzu Abschnitt 25.1.3.5, „MyODBC: Verbindungsparameter“.

#### 25.1.3.4. Konfiguration einer MyODBC-DSN unter Unix

Unter `Unix` konfigurieren Sie DSN-Einträge direkt in der Datei `odbc.ini`. Hier sehen Sie eine typische `odbc.ini`-Datei, die `myodbc` und `myodbc3` als DSN-Namen für MyODBC 2.50 und MyODBC 3.51 einrichtet:

    ;
    ;  odbc.ini configuration for MyODBC and MyODBC 3.51 drivers
    ;

    [ODBC Data Sources]
    myodbc      = MyODBC 2.50 Driver DSN
    myodbc3     = MyODBC 3.51 Driver DSN

    [myodbc]
    Driver       = /usr/local/lib/libmyodbc.so
    Description  = MyODBC 2.50 Driver DSN
    SERVER       = localhost
    PORT         =
    USER         = root
    Password     =
    Database     = test
    OPTION       = 3
    SOCKET       =

    [myodbc3]
    Driver       = /usr/local/lib/libmyodbc3.so
    Description  = MyODBC 3.51 Driver DSN
    SERVER       = localhost
    PORT         =
    USER         = root
    Password     =
    Database     = test
    OPTION       = 3
    SOCKET       =

    [Default]
    Driver       = /usr/local/lib/libmyodbc3.so
    Description  = MyODBC 3.51 Driver DSN
    SERVER       = localhost
    PORT         =
    USER         = root
    Password     =
    Database     = test
    OPTION       = 3
    SOCKET       =

In Abschnitt 25.1.3.5, „MyODBC: Verbindungsparameter“, sind die möglichen Verbindungsparameter aufgelistet.

Hinweis: Wenn Sie `unixODBC` benutzen, können Sie den DSN mit folgenden Tools einrichten:

- ODBCConfig GUI-Tool (HOWTO: ODBCConfig)

- odbcinst

Gelegentlich tritt bei `unixODBC` folgender Fehler auf:

    Data source name not found and no default driver specified

Wenn dies geschieht, müssen Sie sich vergewissern, dass die Umgebungsvariablen `ODBCINI` und `ODBCSYSINI` auf die richtige `odbc.ini`-Datei verweisen. Wenn beispielsweise Ihre `odbc.ini`-Datei unter `/usr/local/etc` liegt, müssen die Umgebungsvariablen folgendermaßen gesetzt werden:

    export ODBCINI=/usr/local/etc/odbc.ini
    export ODBCSYSINI=/usr/local/etc

#### 25.1.3.5. MyODBC: Verbindungsparameter

Sie können die Parameter aus den folgenden Tabellen für MyODBC verwenden, wenn Sie einen DSN konfigurieren. Windows-Benutzer können diese Parameter bei der DSN-Konfiguration in den Feldern Optionen und Erweitert angeben. Welche Optionen für welche Felder und Kontrollkästchen da sind, ist der Tabelle zu entnehmen. Auf Unix und Mac OS X verwenden Sie den Parameternamen und -wert als Schlüsselwort/Wert-Paar. Alternativ können Sie diese Parameter in dem `InConnectionString`-Argument im Aufruf von `SQLDriverConnect()` einstellen.

Parameter | Standardwert | Bemerkungen
`user` | ODBC (auf Windows) | Der Benutzername für die MySQL-Verbindung.
`server` | `localhost` | Der Hostname des MySQL Servers.
`database` |  | Die Standarddatenbank.
`option` | 0 | Optionen für die Arbeitsweise von MyODBC. Siehe unten.
`port` | 3306 | Der TCP/IP-Port, der verwendet wird, wenn `server` nicht `localhost` ist.
`stmt` |  | Eine Anweisung, die bei einer MySQL-Verbindung ausgeführt wird.
`password` |  | Das Passwort für den `user`-Account auf dem `server`.
`socket` |  | Die Unix-Socketdatei oder die Named Pipe von Windows, die für die Verbindung verwendet wird, wenn `server` der `localhost` ist.

Das Argument `option` teilt MyODBC mit, dass der Client nicht absolut ODBC-fähig ist. Auf Windows wählt man Optionen normalerweise aus, indem man die Kontrollkästchen im Verbindungsbildschirm markiert, aber ebenso gut kann man sie auch mit dem `option`-Argument angeben. Die folgenden Optionen werden in derselben Reihenfolge wie auf dem MyODBC-Verbindungsbildschirm aufgeführt:

Wert | Windows-Kontrollkästchen | Beschreibung
1 | Don't Optimized Column Width | Der Client kann nicht damit umgehen, dass MyODBC die echte Breite einer Spalte zurückgibt.
2 | Return Matching Rows | Der Client kann nicht damit umgehen, dass MySQL den wirklichen Wert der betroffenen Zeilen zurückgibt. Wenn dieses Flag gesetzt ist, liefert MySQL stattdessen die „gefundenen Zeilen“. Damit dies funktioniert, benötigen Sie MySQL 3.21.14 oder höher.
4 | Trace Driver Calls To myodbc.log | Erstellt ein Debuglog in `C:\myodbc.log` auf Windows bzw. in `/tmp/myodbc.log` auf Unix-Varianten.
8 | Allow Big Results | Es wird keine Größenbegrenzung für Ergebnisse und Parameter eingestellt.
16 | Don't Prompt Upon Connect | Nicht zu Fragen auffordern, selbst wenn der Treiber dies tun würde.
32 | Enable Dynamic Cursor | Aktiviert oder deaktiviert Unterstützung für dynamische Cursors. (Unzulässig in MyODBC 2.50.)
64 | Ignore # in Table Name | Ignoriert Datenbanknamen in `db_name.tbl_name.col_name`.
128 | User Manager Cursors | Erzwingt Benutzung von ODBC-Manager-Cursors (experimentell).
256 | Don't Use Set Locale | Deaktiviert die Nutzung erweiterter Fetch-Operationen (experimentell).
512 | Pad Char To Full Length | `CHAR`-Spalten werden auf die volle Spaltenlänge aufgefüllt.
1024 | Return Table Names for SQLDescribeCol | `SQLDescribeCol()` gibt voll qualifizierte Spaltennamen zurück.
2048 | Use Compressed Protocol | Verwendet das komprimierte Client/Server-Protokoll.
4096 | Ignore Space After Function Names | Lässt den Server Leerraum zwischen Funktionsname und ‘`(`’ ignorieren (nötig für PowerBuilder). Macht alle Funktionsnamen zu Schlüsselwörtern.
8192 | Force Use of Named Pipes | Verbindung über Named Pipes mit einem mysqld-Server, der auf NT läuft.
16384 | Change BIGINT Columns to Int | Wandelt `BIGINT`-Spalten in `INT`-Spalten um (manche Anwendungen können mit `BIGINT` nicht umgehen).
32768 | No Catalog (exp) | Gibt 'user' als `Table_qualifier` und `Table_owner` von `SQLTables` zurück (experimentell).
65536 | Read Options From `my.cnf` | Liest Parameter aus den Gruppen `[client]` und `[odbc]` in `my.cnf`.
131072 | Safe | Fügt einige zusätzliche Sicherheitsprüfungen hinzu (eigentlich unnötig, aber ...).
262144 | Disable transaction | Deaktiviert Transaktionen.
524288 | Save queries to `myodbc.sql` | Ermöglicht Anweisungs-Logging in der Datei `c:\myodbc.sql`(`/tmp/myodbc.sql`) (nur im Debug-Modus aktiviert)
1048576 | Don't Cache Result (forward only cursors) | Ergebnisse werden nicht lokal im Treiber zwischengespeichert, sondern vom Server gelesen (`mysql_use_result()`). Das geht nur bei Forward-only-Cursors. Diese Option ist wichtig für den Umgang mit großen Tabellen, wenn der Treiber nicht die ganze Ergebnismenge speichern soll.
2097152 | Force Use Of Forward Only Cursors | Erzwingt `Forward-only`-Cursors. Wenn Anwendungen den Standard-Cursor-Typ static/dynamic einstellen, aber der Treiber Ergebnismengen nicht im Cache speichern soll, gewährleistet diese Option das gewünschte Forward-only-Cursor-Verhalten.

Um mehrere Optionen auszuwählen, addieren Sie ihre Werte. Wenn Sie beispielsweise `option` auf 12 (4+8) setzen, bedeutet das Debugging ohne Paketlimits.

Die folgende Tabelle zeigt einige empfohlene `option`-Werte für unterschiedliche Konfigurationen:

Konfiguration | Optionswert
Microsoft Access, Visual Basic | 3
Treiber-Tracing (Debug-Modus) | 4
Microsoft Access (mit verbesserten DELETE-Anfragen) | 35
Große Tabellen mit zu vielen Zeilen | 2049
Sybase PowerBuilder | 135168
Query-Logging (Debug-Modus) | 524288
Treiber-Tracing und Query-Logging (Debug-Modus) | 524292
Große Tabellen ohne Ergebnis-Caching | 3145731

#### 25.1.3.6. Verbinden ohne vordefinierte DSN

Eine Verbindung zum MySQL Server können Sie mit SQLDriverConnect unter Angabe des `DRIVER`-Namens herstellen. Die folgenden Verbindungs-Strings gelten für MyODBC mit DSN-Less-Verbindungen:

Für MyODBC 2.50:

    ConnectionString = "DRIVER={MySQL};\
                       SERVER=localhost;\
                       DATABASE=test;\
                       USER=venu;\
                       PASSWORD=venu;\
                       OPTION=3;"

Für MyODBC 3.51:

    ConnectionString = "DRIVER={MySQL ODBC 3.51 Driver};\
                       SERVER=localhost;\
                       DATABASE=test;\
                       USER=venu;\
                       PASSWORD=venu;\
                       OPTION=3;"

Wenn Ihre Programmiersprache Backslashes mit nachfolgendem Whitespace in ein Leerzeichen umwandelt, sollte der Verbindungs-String besser als ein einziger langer String oder als mehrere verkettete Strings ohne Leerraum dazwischen angegeben werden:

    ConnectionString = "DRIVER={MySQL ODBC 3.51 Driver};"
                       "SERVER=localhost;"
                       "DATABASE=test;"
                       "USER=venu;"
                       "PASSWORD=venu;"
                       "OPTION=3;"

Unter Abschnitt 25.1.3.5, „MyODBC: Verbindungsparameter“, finden Sie die möglichen Verbindungsparameter.

#### 25.1.3.7. ODBC: Verbindungspooling

Verbindungspooling versetzt den ODBC-Treiber in die Lage, vorhandene Verbindungen zu einer gegebenen Datenbank aus einem Pool von Verbindungen wiederzuverwenden, anstatt sie bei jedem Zugriff auf die betreffende Datenbank wieder neu aufzubauen. Durch Verbindungspooling können Sie also die gesamte Leistung Ihrer Anwendung verbessern, da es weniger lange dauert, eine Verbindung zu einer im Pool befindlichen Datenbank zu öffnen.

Mehr über Verbindungspooling erfahren Sie unter http://support.microsoft.com/default.aspx?scid=kb;EN-US;q169470.

#### 25.1.3.8. Erzeugen einer ODBC-Trace-Datei

Wenn Sie Schwierigkeiten oder Probleme mit MyODBC haben, erstellen Sie als Erstes eine Logdatei aus dem `ODBC Manager` und MyODBC. Dieses als Tracing bezeichnete Vorgehen wird durch den ODBC Manager ermöglicht. Tracing wird auf Windows, Mac OS X und Unix in unterschiedlicher Weise eingeschaltet.

##### 25.1.3.8.1. Anschalten von ODBC-Tracing unter Windows

Trace-Option auf Windows aktivieren:

1. Über die Registerkarte `Tracing` des Dialogfelde ODBC Data Source Administrator können Sie einstellen, wie ODBC-Funktionsaufrufe nachverfolgt werden.

2. Wenn Sie auf der Registerkarte `Tracing` das Tracing eingeschaltet haben, protokolliert der `Treiber-Manager` alle ODBC-Funktionsaufrufe für alle in der Folgezeit ausgeführten Anwendungen.

3. ODBC-Funktionsaufrufe für Anwendungen, die vor Einschaltung des Tracings ausgeführt wurden, werden nicht protokolliert. Die ODBC-Funktionsaufrufe werden in einer von Ihnen vorgegebenen Logdatei festgehalten.

4. Das Tracing hört erst auf, nachdem Sie auf `Stop tracing now` geklickt haben. Vergessen Sie nicht: Während das Tracing läuft, wächst die Logdatei immer weiter an. Überdies beeinträchtigt das Tracing die Leistung aller Ihrer ODBC-Anwendungen.

##### 25.1.3.8.2. Anschalten von ODBC-Tracing unter Mac OS X

Um die Trace-Option unter Mac OS X 10.3 oder höher zu aktivieren, nutzen Sie die Registerkarte `Tracing` im ODBC Administrator .

1. Öffnen Sie den ODBC Administrator.

2. Wählen Sie die Registerkarte `Tracing`.

3. Markieren Sie das Kontrollkästchen `Enable Tracing`.

4. Geben Sie an, wo das Tracing-Log gespeichert werden soll. Wenn Sie die Daten an eine vorhandene Logdatei anfügen möchten, klicken Sie auf die Schaltfläche Choose....

##### 25.1.3.8.3. Anschalten von ODBC-Tracing unter Unix

Um die Trace-Option unter Mac OS X 10.2 (oder früher) oder unter Unix einzuschalten, müssen Sie die `trace`-Option zur ODBC-Konfiguration hinzufügen:

1. Unter Unix müssen Sie die `Trace`-Option explizit in die Datei `ODBC.INI` einfügen.

   Das Tracing setzen Sie auf `ON` oder `OFF`, indem Sie die Parameter `TraceFile` und `Trace` in `odbc.ini` wie folgt verwenden:

       TraceFile  = /tmp/odbc.trace
       Trace      = 1

   `TraceFile` gibt den Namen und vollständigen Pfad der Trace-Datei an und `Trace` wird auf `ON` oder `OFF` gesetzt. Sie können auch `1` oder `YES` für `ON` und `0` oder `NO` für `OFF` einsetzen. Wenn Sie ODBCConfig von `unixODBC` benutzen, müssen Sie die Tracing-Anleitung für `unixODBC`-Aufrufe unter HOWTO-ODBCConfig befolgen.

##### 25.1.3.8.4. MyODBC-Log einschalten

Ein MyODBC-Log wird folgendermaßen erstellt:

1. Unter Windows müssen Sie hierzu das Optionsflag `Trace MyODBC` im Bildschirm für die MyODBC-Verbindungs- und Konfigurationseinstellungen aktivieren. Das Log wird in die Datei `C:\myodbc.log` geschrieben. Wird die Trace-Option nicht berücksichtigt, wenn Sie zum obigen Bildschirm zurückkehren, so bedeutet dies, dass Sie nicht den `myodbcd.dll`-Treiber benutzen, siehe auch Abschnitt 25.1.3.2.4, „Fehler und ihre Behebung“.

   Wenn Sie Mac OS X, Unix oder eine Verbindung ohne DSN verwenden, müssen Sie im Verbindungs-String `OPTION=4` angeben oder in den DSN das entsprechende Schlüsselwort/Wert-Paar aufnehmen.

2. Starten Sie Ihre Anwendung und versuchen Sie, einen Absturz herbeizuführen. Dann schauen Sie in der MyODBC-Trace-Datei nach, was schief gegangen ist.

Wenn Sie Hilfe benötigen, um herauszufinden, wo das Problem liegt, schauen Sie in Abschnitt 25.1.7.1, „MyODBC: Community-Support“.

### 25.1.4. MyODBC-Beispiele

Wenn Sie einen DSN für den Zugriff auf eine Datenbank konfiguriert haben, hängt es von der jeweils verwendeten Anwendung oder Programmiersprache ab, wie diese Verbindung geöffnet und benutzt wird. Da ODBC eine standardisierte Schnittstelle ist, kann jede Anwendung oder Sprache, die ODBC unterstützt, den DSN nutzen und sich mit der konfigurierten Datenbank verbinden.

#### 25.1.4.1. Grundlegende Schritte für die Verwendung von MyODBC für Applikationen

Anwendungen, die MyODBC benutzen, müssen Folgendes tun, um sich mit einem MySQL Server zu verbinden:

- Den MyODBC-DSN konfigurieren

- Verbindung zum MySQL Server aufbauen

- Initialisierungsoperationen

- SQL-Anweisungen ausführen

- Ergebnisse abrufen

- Transaktionen ausführen

- Serververbindung trennen

Diese Schritte werden von den Anwendungen mit einigen Variationen ausgeführt. Das folgende Diagramm zeigt den grundsätzlichen Ablauf:

#### 25.1.4.2. Schritt-für-Schritt-Anleitung für das Verbinden zu einer MySQL-Datenbank mittels MyODBC

Eine typische Situation, in der MyODBC installiert würde, tritt ein, wenn man von einem Windows-Rechner aus auf eine Datenbank zugreifen möchte, die auf einem Linux- oder Unix-Host läuft.

Um ein Beispiel zu geben, wie man den Zugriff zwischen den beiden Computern einrichten könnte, zeigen wir im Folgenden die wichtigsten Schritte. Wir gehen davon aus, dass Sie sich vom System BETA aus mit dem Benutzernamen `myuser` und dem Passwort `mypassword` mit dem System ALPHA verbinden.

Auf dem System ALPHA (dem MySQL Server) sind folgende Schritte erforderlich:

1. Sie starten den MySQL Server.

2. Sie richten mit `GRANT` ein Konto mit dem Benutzernamen `myuser` ein, das sich vom System BETA aus mit dem Passwort `myuser` mit der Datenbank `test` verbinden darf:

       GRANT ALL ON test.* to 'myuser'@'BETA' IDENTIFIED BY 'mypassword';

   Genaueres über die Berechtigungen von MySQL lesen Sie unter Abschnitt 5.9, „MySQL-Benutzerkontenverwaltung“.

Auf dem System BETA (dem MyODBC-Client) gehen Sie folgendermaßen vor:

1. Sie konfigurieren einen MyODBC-DSN mit den passenden Parametern für Server, Datenbank und Authentifizierungsdaten, wie Sie sie gerade auf dem System ALPHA eingerichtet haben.

   Parameter | Wert | Bemerkungen
   DSN | remote_test | Der Name der Verbindung
   SERVER | ALPHA | Die Adresse des Remote-Servers
   DATABASE | test | Der Name der Standarddatenbank
   USER | myuser | Der Benutzername, der für den Zugriff auf diese Datenbank konfiguriert wurde
   PASSWORD | mypassword | Das Passwort für `myuser`

2. Sie verbinden sich mit einer ODBC-fähigen Anwendung, wie etwa Microsoft Office, unter Verwendung des soeben angelegten DSN mit dem MySQL Server. Scheitert die Verbindung, so untersuchen Sie den Verbindungsprozess mit Tracing. Weitere Informationen finden Sie unter Abschnitt 25.1.3.8, „Erzeugen einer ODBC-Trace-Datei“.

#### 25.1.4.3. MyODBC und ODBC-Werkzeuge von Drittanbietern

Wenn Sie Ihren MyODBC DSN konfiguriert haben, können Sie mit jeder Anwendung, die die ODBC-Schnittstelle unterstützt, auf die MySQL-Datenbank zugreifen, auch mit Programmiersprachen und Anwendungen von Drittanbietern. Dieser Abschnitt verrät Ihnen, wie man MyODBC mit verschiedenen ODBC-kompatiblen Tools und Anwendungen einsetzt, darunter Microsoft Word, Microsoft Excel und Adobe/Macromedia ColdFusion.

##### 25.1.4.3.1. Applikationen, die mit MyODBC getestet wurden

MyODBC wurde mit folgenden Anwendungen getestet:

Hersteller | Anwendung | Hinweise
Adobe | ColdFusion | Früher Macromedia ColdFusion
Borland | C++ Builder |
| Builder 4 |
| Delphi |
Business Objects | Crystal Reports |
Claris | Filemaker Pro |
Corel | Paradox |
Computer Associates | Visual Objects | Auch CAVO genannt
| AllFusion ERwin Data Modeler |
Gupta | Team Developer | Früher bekannt als Centura Team Developer; Gupta SQL/Windows
Gensym | G2-ODBC Bridge |
Inline | iHTML |
Lotus | Notes | Versionen 4.5 und 4.6
Microsoft | Access |
| Excel |
| Visio Enterprise |
| Visual C++ |
| Visual Basic |
| ODBC.NET | Mit C#, Visual Basic, C++
| FoxPro |
| Visual Interdev |
OpenOffice.org | OpenOffice.org |
Perl | DBD::ODBC |
Pervasive Software | DataJunction |
Sambar Technologies | Sambar Server |
SPSS | SPSS |
SoftVelocity | Clarion |
SQLExpress | SQLExpress for Xbase++ |
Sun | StarOffice |
SunSystems | Vision |
Sybase | PowerBuilder |
| PowerDesigner |
theKompany.com | Data Architect |

Wenn Sie von anderen Anwendungen wissen, dass sie mit MyODBC funktionieren, melden Sie sie bitte per E-Mail an `<myodbc@lists.mysql.com>`.

##### 25.1.4.3.2. Verwendung von MyODBC mit Microsoft Word und Excel

Sie können Microsoft Word und Microsoft Excel nutzen, um auf Daten einer MySQL-Datenbank mithilfe von MyODBC zuzugreifen. In Microsoft Word ist diese Fähigkeit besonders nützlich, wenn Daten für einen Serienbrief importiert oder Tabellen und Daten in Reports eingebunden werden sollen. In Microsoft Excel können Sie Anfragen auf Ihrem MySQL Server verarbeiten und die Daten direkt in ein Excel-Arbeitsblatt importieren, wo sie dann in Form von Zeilen und Spalten dargestellt werden.

In beiden Anwendungen werden die Daten mit Microsoft Query abgefragt und importiert. Diese Anwendung kann eine Anfrage über eine ODBC-Quelle ausführen. Sie erstellen mit Microsoft Query die SQL-Anweisung, die ausgeführt werden soll, und wählen dabei die Tabellen, Felder, Auswahlkriterien und Sortierreihenfolge. Um beispielsweise Tabellendaten aus einer Tabelle der Testdatenbank World in ein Excel-Arbeitsblatt einzufügen und dazu die DSN-Beispiele aus Abschnitt 25.1.3, „MyODBC: Konfiguration“, zu verwenden, gehen Sie folgendermaßen vor:

1. Sie legen ein neues Arbeitsblatt an.

2. Sie wählen aus dem Menü `Daten` den Befehl `Externe Daten importieren` und dann `Neue Abfrage erstellen`.

3. Microsoft Query fährt jetzt hoch. Als Erstes müssen Sie nun die Datenquelle auswählen, indem Sie einen vorhandenen Data Source Name aussuchen.

4. Im `Query-Assistenten` müssen Sie die zu importierenden Spalten auswählen. Die Liste der Tabellen, die dem Benutzer über den konfigurierten DSN zur Verfügung stehen, wird links angezeigt, und die Spalten, die der Anfrage hinzugefügt werden, rechts. Die Spalten, die Sie wählen, entsprechen denen, die im ersten Abschnitt einer `SELECT`-Anfrage erscheinen. Klicken Sie auf Next, um fortzufahren.

5. Die Spalten der Anfrage können Sie mit dem `Filter Data` -Dialog filtern (wie mit einer `WHERE`-Klausel) . Klicken Sie nun wieder auf Next.

6. Wählen Sie eine (optionale) Sortierreihenfolge für die Daten. Dies entspricht einer `ORDER BY`-Klausel in einer SQL-Anfrage. Bis zu drei Felder können Sie auswählen, um die Rückgabedaten der Anfrage zu sortieren. Nun klicken Sie wieder auf Next.

7. Nun wählen Sie das Zielobjekt für Ihre Anfrage, beispielsweise Microsoft Excel. Hier können Sie aussuchen, in welches Arbeitsblatt und welche Zelle die Daten eingefügt werden sollen. Sie können dann die Anfrage und Ergebnisse in Microsoft Query anzeigen lassen, wo Sie die SQL-Anfrage weiter bearbeiten und die Rückgabedaten weiter filtern und sortieren können; oder Sie erstellen aus der Anfrage einen OLAP Cube, der dann direkt in Microsoft Excel verwendet werden kann. Klicken Sie nun auf Finish.

Mit demselben Verfahren können Sie Daten auch in ein Word-Dokument importieren, wo sie in Form einer Tabelle eingefügt werden. Dies kann für Serienbriefe genutzt werden (wo die Felddaten aus einer Word-Tabelle gelesen werden) oder auch zum Einbinden von Daten und Berichten in einen anderen Bericht oder ein Dokument.

##### 25.1.4.3.3. Verwendung von MyODBC und Microsoft Access

Unter Verwendung von MyODBC können Sie MySQL-Datenbanken auch mit Microsoft Access benutzen. Die MySQL-Datenbank kann als Importquelle, als Exportquelle oder als verknüpfte Tabelle verwendet werden, die direkt in einer Access-Anwendung eingesetzt wird. So wird Access zu einem Frontend einer MySQL-Datenbank.

###### 25.1.4.3.3.1. Export von Access-Daten nach MySQL

Um eine Tabelle mit Daten aus einer Access-Datenbank in MySQL zu importieren, verfahren Sie wie folgt:

1. Wenn Sie eine Access-Datenbank oder ein Access-Projekt öffnen, erscheint ein Datenbankfenster. Hier können Sie mit Shortcuts neue Datenbankobjekte erzeugen oder vorhandene öffnen.

2. Klicken Sie auf den Namen der zu exportierenden `table` oder `query` und wählen Sie dann im Menü `Datei (File)` den Befehl `Exportieren (Export)`.

3. Im Dialogfeld `Export Object Type `Objektname` To` wählen Sie im Feld `Speichern unter (Save as)` den Punkt `ODBC Databases ()`:

4. Im Dialogfeld `Exportieren (Export)` geben Sie einen Namen für die Datei ein (oder akzeptieren den Namensvorschlag) und wählen dann `OK`.

5. Im Dialogfeld zur Auswahl der Datenquelle werden die definierten Datenquellen für alle auf Ihrem Computer installierten ODBC-Treiber aufgelistet. Klicken Sie hier auf die Registerkarte Dateidatenquelle oder Maschinendatenquelle und setzen Sie dann einen Doppelklick auf die MyODBC- oder MyODBC-3.51-Datenquelle, in die Sie Daten exportieren möchten. Wie eine neue Datenquelle für MyODBC definiert wird, erfahren Sie unter Abschnitt 25.1.3.2, „Konfiguration einer MyODBC-DSN unter Windows“.

Microsoft Access verbindet sich über diese Datenquelle mit dem MySQL Server und exportiert dann neue Tabellen und/oder Daten.

###### 25.1.4.3.3.2. Importieren von MySQL-Daten in Access

Um einen Link oder eine oder mehrere Tabellen von MySQL in Access zu importieren, gehen Sie folgendermaßen vor:

1. Sie öffnen eine Datenbank oder gehen in das Datenbankfenster und öffnen sie dort.

2. Um Tabellen zu importieren, zeigen Sie im `Datei`-Menü auf `Externe Daten abrufen` und klicken dann auf `Importieren`. Um Tabellen zu verknüpfen, zeigen Sie im Dateimenü auf `Externe Daten abrufen` und klicken dann auf `Tabellen verknüpfen`.

3. Im Dialogfeld `Import` (oder `Verknüpfen`) wählen Sie im Feld Dateityp den Eintrag `ODBC Databases ()`. Das Dialogfeld Datenquelle wählen führt die definierten Datenquellen auf.

4. Wenn für die gewünschte ODBC-Datenquelle eine Anmeldung erforderlich ist, geben Sie Ihren Benutzernamen und Ihr Passwort ein (sowie eventuell erforderliche Zusatzinformationen) und klicken dann auf `OK`.

5. Microsoft Access verbindet sich mit dem MySQL Server über die `ODBC-Datenquelle` und zeigt die Liste der Tabellen an, die Sie `importieren` oder `verknüpfen` können.

6. Klicken Sie nun alle Tabellen an, die Sie `importieren` oder `verknüpfen` möchten, und klicken Sie dann auf `OK`. Wenn Sie eine Tabelle verknüpfen, die keinen Index besitzt, über den Datensätze eindeutig identifiziert werden können, zeigt Microsoft Access eine Liste der Felder dieser verknüpften Tabelle an. Klicken Sie auf ein Feld oder eine Feldkombination, die Datensätze eindeutig identifiziert, und dann auf `OK`.

###### 25.1.4.3.3.3. Verknüpfen von MySQL-Daten zu Access-Tabellen

Mit folgendem Verfahren können Sie Verknüpfungen anzeigen oder aktualisieren, wenn sich die Struktur oder der Speicherort einer verknüpften Tabelle geändert hat. Der Verknüpfungsassistent führt die Pfade aller Tabellen auf, die gerade verknüpft sind.

Verknüpfungen anzeigen oder aktualisieren:

1. Öffnen Sie die Datenbank, die die Verknüpfungen zu den Tabellen enthält.

2. Zeigen Sie im Menü `Extras` auf `Add-ins` (`Datenbank-Utilities` in Access 2000 oder höher) und klicken Sie dann auf `Verknüpfungsassistent`.

3. Markieren Sie die Kontrollkästchen der Tabellen, deren Links Sie aktualisieren möchten.

4. Mit einem Klick auf OK werden die Verknüpfungen aktualisiert.

Microsoft Access bestätigt eine erfolgreiche Aktualisierung oder zeigt, wenn die Tabelle nicht gefunden wurde, das Dialogfeld `Neuen Speicherort wählen für` <table name> an, in welchem Sie den neuen Speicherort der Tabelle eingeben können. Wenn mehrere der ausgewählten Tabellen an den neuen Speicherort verschoben wurden, durchsucht der Verknüpfungsassistent diesen Ort nach allen diesen Tabellen und aktualisiert die Verknüpfungen in einem einzigen Durchgang.

Pfad für mehrere verknüpfte Tabellen ändern:

1. Öffnen Sie die Datenbank, die die Verknüpfungen zu den Tabellen enthält.

2. Zeigen Sie im Menü `Extras` auf `Add-ins` (`Datenbank-Utilities` in Access 2000 oder höher) und klicken Sie dann auf `Verknüpfungsassistent`.

3. Markieren Sie das Kontrollkästchen `Bei neuem Speicherort immer nachfragen`.

4. Markieren Sie die Kontrollkästchen der Tabellen, deren Verknüpfungen Sie ändern möchten, und klicken Sie auf `OK`.

5. Geben Sie im Dialogfeld `Neuen Speicherort wählen für `tabellenname`` den neuen Speicherort ein und klicken Sie auf `Öffnen` und dann auf `OK`.

#### 25.1.4.4. MyODBC: Programmierbeispiele

Wenn ein geeigneter ODBC-Manager und der MyODBC-Treiber installiert sind, müsste jede Programmiersprache und Umgebung, die ODBC unterstützt, über MyODBC mit einer MySQL-Datenbank Verbindung aufnehmen können.

Dazu gehören auch (aber natürlich nicht nur) die Microsoft-Sprachen (Visual Basic, C# und Schnittstellen wie ODBC.NET) und Perl (über das DBI-Modul und den DBD::ODBC-Treiber).

##### 25.1.4.4.1. Verwendung von MyODBC mit Visual Basic und ADO, DAO sowie RDO

Dieser Abschnitt zeigt einfache Beispiele für die Verwendung des MySQL ODBC 3.51-Treibers mit ADO, DAO und RDO.

###### 25.1.4.4.1.1. ADO: `rs.addNew`, `rs.delete` und `rs.update`

Das folgende ADO(ActiveX Data Objects)-Beispiel legt eine Tabelle an (`my_ado`) und demonstriert die Verwendung von `rs.addNew`, `rs.delete` und `rs.update`.

    Private Sub myodbc_ado_Click()

    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim fld As ADODB.Field
    Dim sql As String

    'connect to MySQL server using MySQL ODBC 3.51 Driver
    Set conn = New ADODB.Connection
    conn.ConnectionString = "DRIVER={MySQL ODBC 3.51 Driver};"_
    & "SERVER=localhost;"_
    & " DATABASE=test;"_
    & "UID=venu;PWD=venu; OPTION=3"

    conn.Open

    'create table
    conn.Execute "DROP TABLE IF EXISTS my_ado"
    conn.Execute "CREATE TABLE my_ado(id int not null primary key, name varchar(20)," _
    & "txt text, dt date, tm time, ts timestamp)"

    'direct insert
    conn.Execute "INSERT INTO my_ado(id,name,txt) values(1,100,'venu')"
    conn.Execute "INSERT INTO my_ado(id,name,txt) values(2,200,'MySQL')"
    conn.Execute "INSERT INTO my_ado(id,name,txt) values(3,300,'Delete')"

    Set rs = New ADODB.Recordset
    rs.CursorLocation = adUseServer

    'fetch the initial table ..
    rs.Open "SELECT * FROM my_ado", conn
    Debug.Print rs.RecordCount
    rs.MoveFirst
    Debug.Print String(50, "-") & "Initial my_ado Result Set " & String(50, "-")
    For Each fld In rs.Fields
    Debug.Print fld.Name,
    Next
    Debug.Print

    Do Until rs.EOF
    For Each fld In rs.Fields
    Debug.Print fld.Value,
    Next
    rs.MoveNext
    Debug.Print
    Loop
    rs.Close

    'rs insert
    rs.Open "select * from my_ado", conn, adOpenDynamic, adLockOptimistic
    rs.AddNew
    rs!Name = "Monty"
    rs!txt = "Insert row"
    rs.Update
    rs.Close

    'rs update
    rs.Open "SELECT * FROM my_ado"
    rs!Name = "update"
    rs!txt = "updated-row"
    rs.Update
    rs.Close

    'rs update second time..
    rs.Open "SELECT * FROM my_ado"
    rs!Name = "update"
    rs!txt = "updated-second-time"
    rs.Update
    rs.Close

    'rs delete
    rs.Open "SELECT * FROM my_ado"
    rs.MoveNext
    rs.MoveNext
    rs.Delete
    rs.Close

    'fetch the updated table ..
    rs.Open "SELECT * FROM my_ado", conn
    Debug.Print rs.RecordCount
    rs.MoveFirst
    Debug.Print String(50, "-") & "Updated my_ado Result Set " & String(50, "-")
    For Each fld In rs.Fields
    Debug.Print fld.Name,
    Next
    Debug.Print

    Do Until rs.EOF
    For Each fld In rs.Fields
    Debug.Print fld.Value,
    Next
    rs.MoveNext
    Debug.Print
    Loop
    rs.Close
    conn.Close
    End Sub

###### 25.1.4.4.1.2. DAO: `rs.addNew`, `rs.update` und Scrolling

Das folgende DAO(Data Access Objects)-Beispiel legt die Tabelle `my_dao` an und demonstriert die Verwendung von `rs.addNew`, `rs.update` und Ergebnismengen-Scrolling.

    Private Sub myodbc_dao_Click()

    Dim ws As Workspace
    Dim conn As Connection
    Dim queryDef As queryDef
    Dim str As String

    'connect to MySQL using MySQL ODBC 3.51 Driver
    Set ws = DBEngine.CreateWorkspace("", "venu", "venu", dbUseODBC)
    str = "odbc;DRIVER={MySQL ODBC 3.51 Driver};"_
    & "SERVER=localhost;"_
    & " DATABASE=test;"_
    & "UID=venu;PWD=venu; OPTION=3"
    Set conn = ws.OpenConnection("test", dbDriverNoPrompt, False, str)

    'Create table my_dao
    Set queryDef = conn.CreateQueryDef("", "drop table if exists my_dao")
    queryDef.Execute

    Set queryDef = conn.CreateQueryDef("", "create table my_dao(Id INT AUTO_INCREMENT PRIMARY KEY, " _
    & "Ts TIMESTAMP(14) NOT NULL, Name varchar(20), Id2 INT)")
    queryDef.Execute

    'Insert new records using rs.addNew
    Set rs = conn.OpenRecordset("my_dao")
    Dim i As Integer

    For i = 10 To 15
    rs.AddNew
    rs!Name = "insert record" & i
    rs!Id2 = i
    rs.Update
    Next i
    rs.Close

    'rs update..
    Set rs = conn.OpenRecordset("my_dao")
    rs.Edit
    rs!Name = "updated-string"
    rs.Update
    rs.Close

    'fetch the table back...
    Set rs = conn.OpenRecordset("my_dao", dbOpenDynamic)
    str = "Results:"
    rs.MoveFirst
    While Not rs.EOF
    str = " " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
    Debug.Print "DATA:" & str
    rs.MoveNext
    Wend

    'rs Scrolling
    rs.MoveFirst
    str = " FIRST ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
    Debug.Print str

    rs.MoveLast
    str = " LAST ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
    Debug.Print str

    rs.MovePrevious
    str = " LAST-1 ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
    Debug.Print str

    'free all resources
    rs.Close
    queryDef.Close
    conn.Close
    ws.Close

    End Sub

###### 25.1.4.4.1.3. RDO: `rs.addNew` und `rs.update`

Das folgende RDO(Remote Data Objects)-Beispiel legt die Tabelle `my_rdo` an und demonstriert die Verwendung von `rs.addNew` und `rs.update`.

    Dim rs As rdoResultset
    Dim cn As New rdoConnection
    Dim cl As rdoColumn
    Dim SQL As String

    'cn.Connect = "DSN=test;"
    cn.Connect = "DRIVER={MySQL ODBC 3.51 Driver};"_
    & "SERVER=localhost;"_
    & " DATABASE=test;"_
    & "UID=venu;PWD=venu; OPTION=3"

    cn.CursorDriver = rdUseOdbc
    cn.EstablishConnection rdDriverPrompt

    'drop table my_rdo
    SQL = "drop table if exists my_rdo"
    cn.Execute SQL, rdExecDirect

    'create table my_rdo
    SQL = "create table my_rdo(id int, name varchar(20))"
    cn.Execute SQL, rdExecDirect

    'insert - direct
    SQL = "insert into my_rdo values (100,'venu')"
    cn.Execute SQL, rdExecDirect

    SQL = "insert into my_rdo values (200,'MySQL')"
    cn.Execute SQL, rdExecDirect

    'rs insert
    SQL = "select * from my_rdo"
    Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
    rs.AddNew
    rs!id = 300
    rs!Name = "Insert1"
    rs.Update
    rs.Close

    'rs insert
    SQL = "select * from my_rdo"
    Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
    rs.AddNew
    rs!id = 400
    rs!Name = "Insert 2"
    rs.Update
    rs.Close

    'rs update
    SQL = "select * from my_rdo"
    Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
    rs.Edit
    rs!id = 999
    rs!Name = "updated"
    rs.Update
    rs.Close

    'fetch back...
    SQL = "select * from my_rdo"
    Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
    Do Until rs.EOF
    For Each cl In rs.rdoColumns
    Debug.Print cl.Value,
    Next
    rs.MoveNext
    Debug.Print
    Loop
    Debug.Print "Row count="; rs.RowCount

    'close
    rs.Close
    cn.Close

    End Sub

##### 25.1.4.4.2. Verwendung von MyODBC mit .NET

Dieser Abschnitt zeigt einfache Beispiele für die Verwendung von MyODBC-Treibern mit ODBC.NET.

###### 25.1.4.4.2.1. Verwendung von MyODBC mit ODBC.NET und C# (C sharp)

Das folgende Beispiel legt die Tabelle `my_odbc_net` an und demonstriert ihre Verwendung in C#.

    /**
     * @sample    : mycon.cs
     * @purpose   : Demo sample for ODBC.NET using MyODBC
     * @author    : Venu, <myodbc@lists.mysql.com>
     *
     * (C) Copyright MySQL AB, 1995-2006
     *
     **/

    /* Build-Befehl
     *
     *  csc /t:exe
     *      /out:mycon.exe mycon.cs
     *      /r:Microsoft.Data.Odbc.dll
     */

    using Console = System.Console;
    using Microsoft.Data.Odbc;

    namespace myodbc3
    {
      class mycon
      {
        static void Main(string[] args)
        {
          try
            {
              //Verbindungs-String für MyODBC 2.50
              /*string MyConString = "DRIVER={MySQL};" +
                "SERVER=localhost;" +
                "DATABASE=test;" +
                "UID=venu;" +
                "PASSWORD=venu;" +
                "OPTION=3";
              */
              //Verbindungs-String für MyODBC 3.51
              string MyConString = "DRIVER={MySQL ODBC 3.51 Driver};" +
                "SERVER=localhost;" +
                "DATABASE=test;" +
                "UID=venu;" +
                "PASSWORD=venu;" +
                "OPTION=3";

              //Verbindung zu MySQL mittels MyODBC
              OdbcConnection MyConnection = new OdbcConnection(MyConString);
              MyConnection.Open();

              Console.WriteLine("\n !!! success, connected successfully !!!\n");

              //Verbindungs-Informationen anzeigen
              Console.WriteLine("Connection Information:");
              Console.WriteLine("\tConnection String:" +
                                MyConnection.ConnectionString);
              Console.WriteLine("\tConnection Timeout:" +
                                MyConnection.ConnectionTimeout);
              Console.WriteLine("\tDatabase:" +
                                MyConnection.Database);
              Console.WriteLine("\tDataSource:" +
                                MyConnection.DataSource);
              Console.WriteLine("\tDriver:" +
                                MyConnection.Driver);
              Console.WriteLine("\tServerVersion:" +
                                MyConnection.ServerVersion);

              //Beispieltabelle anlegen
              OdbcCommand MyCommand =
                new OdbcCommand("DROP TABLE IF EXISTS my_odbc_net",
                                MyConnection);
              MyCommand.ExecuteNonQuery();
              MyCommand.CommandText =
                "CREATE TABLE my_odbc_net(id int, name varchar(20), idb bigint)";
              MyCommand.ExecuteNonQuery();

              //Insert
              MyCommand.CommandText =
                "INSERT INTO my_odbc_net VALUES(10,'venu', 300)";
              Console.WriteLine("INSERT, Total rows affected:" +
                                MyCommand.ExecuteNonQuery());;

              //Insert
              MyCommand.CommandText =
                "INSERT INTO my_odbc_net VALUES(20,'mysql',400)";
              Console.WriteLine("INSERT, Total rows affected:" +
                                MyCommand.ExecuteNonQuery());

              //Insert
              MyCommand.CommandText =
                "INSERT INTO my_odbc_net VALUES(20,'mysql',500)";
              Console.WriteLine("INSERT, Total rows affected:" +
                                MyCommand.ExecuteNonQuery());

              //Update
              MyCommand.CommandText =
                "UPDATE my_odbc_net SET id=999 WHERE id=20";
              Console.WriteLine("Update, Total rows affected:" +
                                MyCommand.ExecuteNonQuery());

              //COUNT(*)
              MyCommand.CommandText =
                "SELECT COUNT(*) as TRows FROM my_odbc_net";
              Console.WriteLine("Total Rows:" +
                                MyCommand.ExecuteScalar());

              //Fetch
              MyCommand.CommandText = "SELECT * FROM my_odbc_net";
              OdbcDataReader MyDataReader;
              MyDataReader =  MyCommand.ExecuteReader();
              while (MyDataReader.Read())
                {
                  if(string.Compare(MyConnection.Driver,"myodbc3.dll") == 0) {
                    //Nur von MyODBC 3.51 unterstützt
                    Console.WriteLine("Data:" + MyDataReader.GetInt32(0) + " " +
                                      MyDataReader.GetString(1) + " " +
                                      MyDataReader.GetInt64(2));
                  }
                  else {
                    //BIGINTs werden von MyODBC nicht unterstützt
                    Console.WriteLine("Data:" + MyDataReader.GetInt32(0) + " " +
                                      MyDataReader.GetString(1) + " " +
                                      MyDataReader.GetInt32(2));
                  }
                }

              //Alle Ressourcen schließen
              MyDataReader.Close();
              MyConnection.Close();
            }
          catch (OdbcException MyOdbcException) //Catch any ODBC exception ..
            {
              for (int i=0; i < MyOdbcException.Errors.Count; i++)
                {
                  Console.Write("ERROR #" + i + "\n" +
                                "Message: " +
                                MyOdbcException.Errors[i].Message + "\n" +
                                "Native: " +
                                MyOdbcException.Errors[i].NativeError.ToString() + "\n" +
                                "Source: " +
                                MyOdbcException.Errors[i].Source + "\n" +
                                "SQL: " +
                                MyOdbcException.Errors[i].SQLState + "\n");
                }
            }
        }
      }
    }

###### 25.1.4.4.2.2. Verwendung von MyODBC mit ODBC.NET und Visual Basic

Das folgende Beispiel legt die Tabelle `my_vb_net` an und demonstriert ihre Verwendung in VB.

    ' @sample    : myvb.vb
    ' @purpose   : Demo sample for ODBC.NET using MyODBC
    ' @author    : Venu, <myodbc@lists.mysql.com>
    '
    ' (C) Copyright MySQL AB, 1995-2006
    '
    '

    '
    ' build command
    '
    ' vbc /target:exe
    '     /out:myvb.exe
    '     /r:Microsoft.Data.Odbc.dll
    '     /r:System.dll
    '     /r:System.Data.dll
    '

    Imports Microsoft.Data.Odbc
    Imports System

    Module myvb
      Sub Main()
        Try

          'MyODBC 3.51 connection string
          Dim MyConString As String = "DRIVER={MySQL ODBC 3.51 Driver};" & _
          "SERVER=localhost;" & _
          "DATABASE=test;" & _
          "UID=venu;" & _
          "PASSWORD=venu;" & _
          "OPTION=3;"

          'Connection
          Dim MyConnection As New OdbcConnection(MyConString)
          MyConnection.Open()

          Console.WriteLine("Connection State::" & MyConnection.State.ToString)

          'Drop
          Console.WriteLine("Dropping table")
          Dim MyCommand As New OdbcCommand()
          MyCommand.Connection = MyConnection
          MyCommand.CommandText = "DROP TABLE IF EXISTS my_vb_net"
          MyCommand.ExecuteNonQuery()

          'Create
          Console.WriteLine("Creating....")
          MyCommand.CommandText = "CREATE TABLE my_vb_net(id int, name varchar(30))"
          MyCommand.ExecuteNonQuery()

          'Insert
          MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(10,'venu')"
          Console.WriteLine("INSERT, Total rows affected:" & _
          MyCommand.ExecuteNonQuery())

          'Insert
          MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(20,'mysql')"
          Console.WriteLine("INSERT, Total rows affected:" & _
          MyCommand.ExecuteNonQuery())

          'Insert
          MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(20,'mysql')"
          Console.WriteLine("INSERT, Total rows affected:" & _
          MyCommand.ExecuteNonQuery())

          'Insert
          MyCommand.CommandText = "INSERT INTO my_vb_net(id) VALUES(30)"
          Console.WriteLine("INSERT, Total rows affected:" & _
                            MyCommand.ExecuteNonQuery())

          'Update
          MyCommand.CommandText = "UPDATE my_vb_net SET id=999 WHERE id=20"
          Console.WriteLine("Update, Total rows affected:" & _
          MyCommand.ExecuteNonQuery())

          'COUNT(*)
          MyCommand.CommandText = "SELECT COUNT(*) as TRows FROM my_vb_net"
          Console.WriteLine("Total Rows:" & MyCommand.ExecuteScalar())

          'Select
          Console.WriteLine("Select * FROM my_vb_net")
          MyCommand.CommandText = "SELECT * FROM my_vb_net"
          Dim MyDataReader As OdbcDataReader
          MyDataReader = MyCommand.ExecuteReader
          While MyDataReader.Read
            If MyDataReader("name") Is DBNull.Value Then
              Console.WriteLine("id = " & _
              CStr(MyDataReader("id")) & "  name = " & _
              "NULL")
            Else
              Console.WriteLine("id = " & _
              CStr(MyDataReader("id")) & "  name = " & _
              CStr(MyDataReader("name")))
            End If
          End While

          'Catch ODBC Exception
        Catch MyOdbcException As OdbcException
          Dim i As Integer
          Console.WriteLine(MyOdbcException.ToString)

          'Catch program exception
        Catch MyException As Exception
          Console.WriteLine(MyException.ToString)
        End Try
      End Sub

### 25.1.5. MyODBC-Referenz

Der vorliegende Abschnitt enthält Referenzmaterial für die MyODBC-API, zeigt die unterstützten Funktionen und Methoden, die MySQL-Spaltentypen und die entsprechenden nativen Typen in MyODBC sowie die von MyODBC zurückgegebenen Fehlercodes.

#### 25.1.5.1. MyODBC: API-Referenz

Dieser Abschnitt fasst ODBC-Routinen nach Funktionalität zusammen.

Die vollständige Referenz zur ODBC-API finden Sie in der ODBC Programmer's Reference unter http://msdn.microsoft.com/library/en-us/odbc/htm/odbcabout_this_manual.asp.

Eine Anwendung kann die Funktion `SQLGetInfo` aufrufen, um Konformitätsinformationen über MyODBC einzuholen. Ob der Treiber eine bestimmte Funktion unterstützt, kann eine Anwendung mit `SQLGetFunctions` in Erfahrung bringen.

Hinweis: Zur Abwärtskompatibilität unterstützt der MyODBC 3.51-Treiber auch die veralteten Funktionen.

Die folgenden Tabellen zeigen die MyODBC-API-Funktionsaufrufe nach Aufgabenbereich:

Verbindung mit einer Datenquelle:

| MyODBC |  |
Funktionsname | 2.50 | 3.51 | Standard | Zweck
`SQLAllocHandle` | Nein | Ja | ISO 92 | Beschafft einen Handle für Umgebung, Verbindung, Anweisung oder Deskriptor.
`SQLConnect` | Ja | Ja | ISO 92 | Verbindet sich mit einem konkreten Treiber über Data Source Name, Benutzername und Passwort.
`SQLDriverConnect` | Ja | Ja | ODBC | Verbindet sich mit einem konkreten Treiber über einen Verbindungs-String oder verlangt, dass der Treiber-Manager und Treiber Verbindungsdialogfelder für den Benutzer anzeigen.
`SQLAllocEnv` | Ja | Ja | Veraltet | Beschafft einen vom Treiber zugewiesenen Umgebungs-Handle.
`SQLAllocConnect` | Ja | Ja | Veraltet | Beschafft einen Verbindungs-Handle

Informationen über einen Treiber und Datenquellen beschaffen:

| MyODBC |  |
Funktionsname | 2.50 | 3.51 | Standard | Zweck
`SQLDataSources` | Nein | Nein | ISO 92 | Liefert eine Liste der verfügbaren Datenquellen, mit denen der Treiber-Manager umgehen kann.
`SQLDrivers` | Nein | Nein | ODBC | Liefert eine Liste der installierten Treiber und ihrer Attribute, mit denen der Treiber-Manager umgehen kann.
`SQLGetInfo` | Ja | Ja | ISO 92 | Liefert Informationen über einen spezifischen Treiber und eine Datenquelle.
`SQLGetFunctions` | Ja | Ja | ISO 92 | Zeigt die unterstützten Treiberfunktionen an.
`SQLGetTypeInfo` | Ja | Ja | ISO 92 | Gibt Informationen über die unterstützten Datentypen.

Treiberattribute einstellen und abfragen:

| MyODBC |  |
Funktionsname | 2.50 | 3.51 | Standard | Zweck
`SQLSetConnectAttr` | Nein | Ja | ISO 92 | Setzt ein Verbindungsattribut.
`SQLGetConnectAttr` | Nein | Ja | ISO 92 | Gibt den Wert eines Verbindungsattributs zurück.
`SQLSetConnectOption` | Ja | Ja | Veraltet | Setzt eine Verbindungsoption.
`SQLGetConnectOption` | Ja | Ja | Veraltet | Gibt den Wert einer Verbindungsoption zurück.
`SQLSetEnvAttr` | Nein | Ja | ISO 92 | Setzt ein Umgebungsattribut.
`SQLGetEnvAttr` | Nein | Ja | ISO 92 | Gibt den Wert eines Umgebungsattributs zurück.
`SQLSetStmtAttr` | Nein | Ja | ISO 92 | Setzt ein Anweisungsattribut.
`SQLGetStmtAttr` | Nein | Ja | ISO 92 | Gibt den Wert eines Anweisungsattributs zurück.
`SQLSetStmtOption` | Ja | Ja | Veraltet | Setzt eine Anweisungsoption.
`SQLGetStmtOption` | Ja | Ja | Veraltet | Gibt den Wert einer Anweisungsoption zurück.

Vorbereitung von SQL-Requests:

| MyODBC |  |
Funktionsname | 2.50 | 3.51 | Standard | Zweck
`SQLAllocStmt` | Ja | Ja | Veraltet | Weist einen Anweisungs-Handle zu.
`SQLPrepare` | Ja | Ja | ISO 92 | Bereitet eine SQL-Anweisung zur späteren Ausführung vor.
`SQLBindParameter` | Ja | Ja | ODBC | Weist Speicher für einen Parameter in einer SQL-Anweisung zu.
`SQLGetCursorName` | Ja | Ja | ISO 92 | Gibt den mit einem Anweisungs-Handle verbundenen Cursor-Namen zurück.
`SQLSetCursorName` | Ja | Ja | ISO 92 | Gibt einen Cursor-Namen an.
`SQLSetScrollOptions` | Ja | Ja | ODBC | Setzt Optionen zur Steuerung des Cursor-Verhaltens.

Übermittlung von Requests:

| MyODBC |  |
Funktionsname | 2.50 | 3.51 | Standard | Zweck
`SQLExecute` | Ja | Ja | ISO 92 | Führt eine vorbereitete Anweisung aus.
`SQLExecDirect` | Ja | Ja | ISO 92 | Führt eine Anweisung aus.
`SQLNativeSql` | Ja | Ja | ODBC | Gibt den Text einer vom Treiber übersetzten SQL-Anweisung zurück.
`SQLDescribeParam` | Ja | Ja | ODBC | Gibt die Beschreibung eines bestimmten Parameters in einer Anweisung zurück.
`SQLNumParams` | Ja | Ja | ISO 92 | Gibt die Anzahl der Parameter in einer Anweisung zurück.
`SQLParamData` | Ja | Ja | ISO 92 | Wird in Verbindung mit `SQLPutData` verwendet, um Parameterdaten zur Ausführungszeit zu liefern. (Nützlich für lange Datenwerte.)
`SQLPutData` | Ja | Ja | ISO 92 | Sendet einen Datenwert eines Parameters ganz oder teilweise. (Nützlich für lange Datenwerte.)

Ergebnisse und Ergebnisinformationen abrufen:

| MyODBC |  |
Funktionsname | 2.50 | 3.51 | Standard | Zweck
`SQLRowCount` | Ja | Ja | ISO 92 | Meldet, wie viele Zeilen von einem Insert, Update oder Delete betroffen wurden.
`SQLNumResultCols` | Ja | Ja | ISO 92 | Meldet die Anzahl der Zeilen in der Ergebnismenge.
`SQLDescribeCol` | Ja | Ja | ISO 92 | Beschreibt eine Spalte der Ergebnismenge.
`SQLColAttribute` | Nein | Ja | ISO 92 | Beschreibt Attribute einer Spalte der Ergebniszeile.
`SQLColAttributes` | Ja | Ja | Veraltet | Beschreibt Attribute einer Spalte der Ergebniszeile.
`SQLFetch` | Ja | Ja | ISO 92 | Gibt mehrere Ergebniszeilen zurück.
`SQLFetchScroll` | Nein | Ja | ISO 92 | Gibt scrollbare Ergebniszeilen zurück.
`SQLExtendedFetch` | Ja | Ja | Veraltet | Gibt scrollbare Ergebniszeilen zurück.
`SQLSetPos` | Ja | Ja | ODBC | Setzt einen Cursor in einen abgeholten Datenblock, sodass eine Anwendung Daten in der Zeilenmenge erneuern oder Daten in der Ergebnismenge aktualisieren oder löschen kann.
`SQLBulkOperations` | Nein | Ja | ODBC | Führt Einfügungen oder Bookmarking als Massenoperationen aus, darunter Updates, Deletes und Datenabruf anhand von Bookmarks.

Fehler- oder Diagnosedaten abrufen:

| MyODBC |  |
Funktionsname | 2.50 | 3.51 | Standard | Zweck
`SQLError` | Ja | Ja | Veraltet | Gibt zusätzliche Fehler- oder Statusinformationen zurück.
`SQLGetDiagField` | Ja | Ja | ISO 92 | Gibt zusätzliche diagnostische Informationen zurück (ein einzelnes Feld der diagnostischen Datenstruktur).
`SQLGetDiagRec` | Ja | Ja | ISO 92 | Gibt zusätzliche diagnostische Informationen zurück (mehrere Felder der diagnostischen Datenstruktur).

Informationen über die Systemtabellen (Katalogfunktionen) der Datenquelle abrufen:

| MyODBC |  |
Funktionsname | 2.50 | 3.51 | Standard | Zweck
`SQLColumnPrivileges` | Ja | Ja | ODBC | Liefert eine Liste von Spalten und zugehörigen Berechtigungen für eine oder mehr Tabellen.
`SQLColumns` | Ja | Ja | X/Open | Liefert eine Liste der Spaltennamen in den angegebenen Tabellen.
`SQLForeignKeys` | Ja | Ja | ODBC | Liefert für eine angegebene Tabelle eine Liste der Spalten, die den Fremdschlüssel bilden (sofern vorhanden).
`SQLPrimaryKeys` | Ja | Ja | ODBC | Liefert die Liste der Spalten, die den Primärschlüssel einer Tabelle bilden.
`SQLSpecialColumns` | Ja | Ja | X/Open | Liefert Informationen über die optimale Spaltenmenge zur eindeutigen Identifikation einer Zeile in einer angegebenen Tabelle oder die Spalten, die automatisch aktualisiert werden, wenn eine Transaktion einen Wert in der Zeile ändert.
`SQLStatistics` | Ja | Ja | ISO 92 | Liefert Statistikdaten über eine einzelne Tabelle und die Liste der mit ihr verbundenen Indizes.
`SQLTablePrivileges` | Ja | Ja | ODBC | Liefert eine Liste der Tabellen und zugehörigen Berechtigungen.
`SQLTables` | Ja | Ja | X/Open | Liefert eine Liste der Tabellennamen, die in einer bestimmten Datenstruktur gespeichert sind.

Transaktionen ausführen:

| MyODBC |  |
Funktionsname | 2.50 | 3.51 | Standard | Zweck
`SQLTransact` | Ja | Ja | Veraltet | Schreibt eine Transaktion fest (Commit) oder rollt sie zurück (Rollback).
`SQLEndTran` | Nein | Ja | ISO 92 | Schreibt eine Transaktion fest (Commit) oder rollt sie zurück (Rollback).

Anweisungen abschließen:

| MyODBC |  |
Funktionsname | 2.50 | 3.51 | Standard | Zweck
`SQLFreeStmt` | Ja | Ja | ISO 92 | Beendet die Anweisungsverarbeitung, verwirft noch anhängige Ergebnisse und gibt optional die Ressourcen frei, die mit dem Anweisungs-Handle verbunden waren.
`SQLCloseCursor` | Ja | Ja | ISO 92 | Schließt einen auf einem Anweisungs-Handle geöffneten Cursor.
`SQLCancel` | Ja | Ja | ISO 92 | Bricht eine SQL-Anweisung ab.

Verbindungen schließen:

| MyODBC |  |
Funktionsname | 2.50 | 3.51 | Standard | Zweck
`SQLDisconnect` | Ja | Ja | ISO 92 | Schließt die Verbindung.
`SQLFreeHandle` | Nein | Ja | ISO 92 | Gibt einen Umgebungs-, Verbindungs-, Anweisungs- oder Deskriptor-Handle frei.
`SQLFreeConnect` | Ja | Ja | Veraltet | Gibt einen Verbindungs-Handle frei.
`SQLFreeEnv` | Ja | Ja | Veraltet | Gibt einen Umgebungs-Handle frei

#### 25.1.5.2. MyODBC: Datentypen

Die folgende Tabelle zeigt, wie der Treiber die Datentypen des Servers den Standarddatentypen von SQL und C zuordnet:

Nativer Wert | SQL-Typ | C-Typ
`bit` | `SQL_BIT` | `SQL_C_BIT`
`tinyint` | `SQL_TINYINT` | `SQL_C_STINYINT`
`tinyint unsigned` | `SQL_TINYINT` | `SQL_C_UTINYINT`
`bigint` | `SQL_BIGINT` | `SQL_C_SBIGINT`
`bigint unsigned` | `SQL_BIGINT` | `SQL_C_UBIGINT`
`long varbinary` | `SQL_LONGVARBINARY` | `SQL_C_BINARY`
`blob` | `SQL_LONGVARBINARY` | `SQL_C_BINARY`
`longblob` | `SQL_LONGVARBINARY` | `SQL_C_BINARY`
`tinyblob` | `SQL_LONGVARBINARY` | `SQL_C_BINARY`
`mediumblob` | `SQL_LONGVARBINARY` | `SQL_C_BINARY`
`long varchar` | `SQL_LONGVARCHAR` | `SQL_C_CHAR`
`text` | `SQL_LONGVARCHAR` | `SQL_C_CHAR`
`mediumtext` | `SQL_LONGVARCHAR` | `SQL_C_CHAR`
`char` | `SQL_CHAR` | `SQL_C_CHAR`
`numeric` | `SQL_NUMERIC` | `SQL_C_CHAR`
`decimal` | `SQL_DECIMAL` | `SQL_C_CHAR`
`integer` | `SQL_INTEGER` | `SQL_C_SLONG`
`integer unsigned` | `SQL_INTEGER` | `SQL_C_ULONG`
`int` | `SQL_INTEGER` | `SQL_C_SLONG`
`int unsigned` | `SQL_INTEGER` | `SQL_C_ULONG`
`mediumint` | `SQL_INTEGER` | `SQL_C_SLONG`
`mediumint unsigned` | `SQL_INTEGER` | `SQL_C_ULONG`
`smallint` | `SQL_SMALLINT` | `SQL_C_SSHORT`
`smallint unsigned` | `SQL_SMALLINT` | `SQL_C_USHORT`
`real` | `SQL_FLOAT` | `SQL_C_DOUBLE`
`double` | `SQL_FLOAT` | `SQL_C_DOUBLE`
`float` | `SQL_REAL` | `SQL_C_FLOAT`
`double precision` | `SQL_DOUBLE` | `SQL_C_DOUBLE`
`date` | `SQL_DATE` | `SQL_C_DATE`
`time` | `SQL_TIME` | `SQL_C_TIME`
`year` | `SQL_SMALLINT` | `SQL_C_SHORT`
`datetime` | `SQL_TIMESTAMP` | `SQL_C_TIMESTAMP`
`timestamp` | `SQL_TIMESTAMP` | `SQL_C_TIMESTAMP`
`text` | `SQL_VARCHAR` | `SQL_C_CHAR`
`varchar` | `SQL_VARCHAR` | `SQL_C_CHAR`
`enum` | `SQL_VARCHAR` | `SQL_C_CHAR`
`set` | `SQL_VARCHAR` | `SQL_C_CHAR`
`bit` | `SQL_CHAR` | `SQL_C_CHAR`
`bool` | `SQL_CHAR` | `SQL_C_CHAR`

#### 25.1.5.3. MyODBC: Fehlercodes

Die folgenden Tabellen führen die Fehlercodes auf, die der Treiber neben den Serverfehlern noch zurückliefert.

Nativer Code | SQLSTATE 2 | SQLSTATE 3 | Fehlermeldung
500 | 01000 | 01000 | General warning
501 | 01004 | 01004 | String data, right truncated
502 | 01S02 | 01S02 | Option value changed
503 | 01S03 | 01S03 | No rows updated/deleted
504 | 01S04 | 01S04 | More than one row updated/deleted
505 | 01S06 | 01S06 | Attempt to fetch before the result set returned the first row set
506 | 07001 | 07002 | `SQLBindParameter` not used for all parameters
507 | 07005 | 07005 | Prepared statement not a cursor-specification
508 | 07009 | 07009 | Invalid descriptor index
509 | 08002 | 08002 | Connection name in use
510 | 08003 | 08003 | Connection does not exist
511 | 24000 | 24000 | Invalid cursor state
512 | 25000 | 25000 | Invalid transaction state
513 | 25S01 | 25S01 | Transaction state unknown
514 | 34000 | 34000 | Invalid cursor name
515 | S1000 | HY000 | General driver defined error
516 | S1001 | HY001 | Memory allocation error
517 | S1002 | HY002 | Invalid column number
518 | S1003 | HY003 | Invalid application buffer type
519 | S1004 | HY004 | Invalid SQL data type
520 | S1009 | HY009 | Invalid use of null pointer
521 | S1010 | HY010 | Function sequence error
522 | S1011 | HY011 | Attribute can not be set now
523 | S1012 | HY012 | Invalid transaction operation code
524 | S1013 | HY013 | Memory management error
525 | S1015 | HY015 | No cursor name available
526 | S1024 | HY024 | Invalid attribute value
527 | S1090 | HY090 | Invalid string or buffer length
528 | S1091 | HY091 | Invalid descriptor field identifier
529 | S1092 | HY092 | Invalid attribute/option identifier
530 | S1093 | HY093 | Invalid parameter number
531 | S1095 | HY095 | Function type out of range
532 | S1106 | HY106 | Fetch type out of range
533 | S1117 | HY117 | Row value out of range
534 | S1109 | HY109 | Invalid cursor position
535 | S1C00 | HYC00 | Optional feature not implemented
0 | 21S01 | 21S01 | Column count does not match value count
0 | 23000 | 23000 | Integrity constraint violation
0 | 42000 | 42000 | Syntax error or access violation
0 | 42S02 | 42S02 | Base table or view not found
0 | 42S12 | 42S12 | Index not found
0 | 42S21 | 42S21 | Column already exists
0 | 42S22 | 42S22 | Column not found
0 | 08S01 | 08S01 | Communication link failure

### 25.1.6. Hinweise und Tipps zu MyODBC

Nun folgen einige allgemeine Hinweise und Tipps für die Verwendung von MyODBC in unterschiedlichen Umgebungen, Anwendungen und Tools. Die Hinweise basieren auf den Erfahrungen von MyODBC-Entwicklern und -Nutzern.

#### 25.1.6.1. MyODBC: Allgemeine Funktionalität

In diesem Abschnitt geht es um häufig benutzte Abfragen und Funktionalitätsbereiche in MySQL und ihre Verwendung mit MyODBC.

##### 25.1.6.1.1. Abruf von Auto-Increment-Werten

Den Wert einer Spalte, die nach einer `INSERT`-Anweisung `AUTO_INCREMENT` verwendet, kann man auf mehrere Weisen beschaffen. Um ihn unmittelbar nach dem `INSERT` abzurufen, verwendet man eine `SELECT`-Anfrage mit der `LAST_INSERT_ID()`-Funktion.

Mit MyODBC würden Sie hier zwei Anweisungen absetzen: die `INSERT`-Anweisung und die `SELECT`-Anfrage, die Ihnen den Auto-Increment-Wert liefert.

    INSERT INTO tbl (auto,text) VALUES(NULL,'text');
    SELECT LAST_INSERT_ID();

Wenn Sie den Wert nicht für Ihre Anwendung, aber für ein anderes `INSERT` benötigen, können Sie das Ganze auch mit folgenden beiden Anweisungen erledigen:

    INSERT INTO tbl (auto,text) VALUES(NULL,'text');
    INSERT INTO tbl2 (id,text) VALUES(LAST_INSERT_ID(),'text');

Manche ODBC-Anwendungen (darunter Delphi und Access) haben Schwierigkeiten, mit den oben gezeigten Methoden den Auto-Increment-Wert abzurufen. Hier bietet sich als Alternative folgende Anweisung an:

    SELECT * FROM tbl WHERE auto IS NULL;

Siehe Abschnitt 24.2.13.3, „Wie erhalte ich die eindeutige Kennung für die letzte eingefügte Zeile?“.

##### 25.1.6.1.2. Unterstützung für dynamische Cursor

MyODBC 3.51 bietet zwar `dynamic cursor`-Unterstützung, aber nach Voreinstellung sind dynamische Cursors nicht aktiviert. In Windows schalten Sie diese Funktion ein, indem Sie das Kontrollkästchen `Dynamische Cursor aktivieren` im ODBC-Datenquellen-Administrator markieren.

Auf anderen Plattformen schalten Sie dynamische Cursors ein, indem Sie zu dem Wert von `OPTION` den Wert `32` addieren, wenn Sie den DSN anlegen.

##### 25.1.6.1.3. MyODBC: Performanz

Der MyODBC-Treiber wurde auf eine sehr schnelle Leistung hin optimiert. Wenn Sie Probleme mit der Leistung von MyODBC haben oder viele Plattenzugriffe für einfache Anfragen auftreten, sollten Sie mehrere Dinge überprüfen:

- Stellen Sie sicher, dass `ODBC Tracing` nicht eingeschaltet ist. Wenn das Tracing aktiv ist, zeichnet der ODBC-Manager massenhaft Daten in der Tracing-Datei auf. Unter Windows können Sie dies prüfen und das Tracing gegebenenfalls deaktivieren, indem Sie die Ablaufverfolgung im ODBC-Datenquellen-Administrator ausschalten. In Mac OS X überprüfen Sie das Tracing-Feld des ODBC Administrators. Siehe auch Abschnitt 25.1.3.8, „Erzeugen einer ODBC-Trace-Datei“.

- Vergewissern Sie sich, dass Sie die Standardversion und nicht die Debugging-Version des Treibers benutzen. In der Debugging-Version werden zusätzliche Überprüfungen und Berichte ausgeführt.

- Deaktivieren Sie die Trace- und Query-Logs des MyODBC-Treibers. Da diese für jeden DSN aktiviert sind, müssen Sie darauf achten, nur den DSN zu bearbeiten, den Sie in Ihrer Anwendung benutzen. Unter Windows deaktivieren Sie die MyODBC- und Query-Logs, indem Sie die DSN-Konfiguration modifizieren. Unter Mac OS X und Unix müssen Sie dafür sorgen, dass der Treiber-Trace (Optionswert 4) und das Anfragen-Logging (Optionswert 524288) ausgeschaltet sind.

##### 25.1.6.1.4. Einstellen der ODBC-Zeitüberschreitung unter Windows

Wie Sie in Microsoft Windows ein Anfragen-Timeout einstellen, wenn Anfragen über eine ODBC-Verbindung ausgeführt werden, erfahren Sie in folgendem Artikel der Microsoft Knowledge Base: http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B153756.

#### 25.1.6.2. MyODBC: Applikationsspezifische Tipps

Die meisten Programme sollten mit MyODBC gut harmonieren, doch für die folgenden gibt es bestimmte Hinweise und Tipps zur Verbesserung der Arbeit mit MyODBC und dem betreffenden Programm.

Bei allen Anwendungen sollten Sie immer darauf achten, die jeweils neuesten Versionen von MyODBC-Treibern, ODBC-Manager und den von der Anwendung benutzten Bibliotheken und Schnittstellen einzusetzen. Wenn Sie beispielsweise unter Windows die neueste Version der Microsoft Data Access Components (MDAC) verwenden, wird die Kompatibilität mit ODBC im Allgemeinen und mit dem MyODBC-Treiber im Besonderen besser.

##### 25.1.6.2.1. MyODBC mit Microsoft-Anwendungen einsetzen

Die meisten Microsoft-Anwendungen wurden mit MyODBC getestet, einschließlich Microsoft Office, Microsoft Access und den verschiedenen von ASP und Microsoft Visual Studio unterstützten Programmiersprachen.

Wenn Sie mit MyODBC Probleme haben, aber Ihr Programm auch mit OLEDB funktioniert, sollten Sie den OLEDB-Treiber ausprobieren.

###### 25.1.6.2.1.1. Microsoft Access

Die Integration von Microsoft Access und MySQL können Sie mit MyODBC wie folgt verbessern:

- Für alle Access-Versionen sollten Sie die MyODBC-Option `Übereinstimmende Zeilen zurückgeben` einschalten. Für Access 2.0 sollten Sie zusätzlich die Option `Simulate ODBC 1.0` aktivieren.

- Alle Tabellen, die für Aktualisierungen zur Verfügung stehen sollen, müssen eine `TIMESTAMP`-Spalte haben. Um die größtmögliche Portierbarkeit zu erzielen, sollten Sie keine Länge in der Spaltendeklaration angeben (dies wird von MySQL-Versionen vor 4.1 nicht unterstützt).

- Jede MySQL-Tabelle, die mit Access benutzt werden soll, benötigt einen Primärschlüssel. Ist dieser nicht vorhanden, können neu eingefügte oder aktualisierte Zeilen als `#DELETED#` erscheinen.

- Verwenden Sie nur `DOUBLE`-Float-Felder. Access kann keine Float-Werte mit einfacher Genauigkeit vergleichen. Infolgedessen können neu eingefügte oder aktualisierte Zeilen als `#DELETED#` erscheinen, oder Sie können Zeilen nicht finden oder aktualisieren.

- Wenn Sie MyODBC zum Verknüpfen einer Tabelle verwenden, die eine `BIGINT`-Spalte hat, werden die Ergebnisse als `#DELETED#` angezeigt. Der Workaround hierfür ist:

  - Sie richten eine oder mehrere Dummy-Spalten mit dem Datentyp `TIMESTAMP` ein.

  - Sie wählen die Option `Change BIGINT columns to INT` im Verbindungsdialog vom ODBC DSN Administrator.

  - Sie löschen die Tabellenverknüpfung aus Access und legen sie neu an.

  Eventuell werden alte Einträge immer noch als `#DELETED#` angezeigt, während neu eingefügte/aktualisierte Einträge richtig angezeigt werden.

- Wenn Sie nach dem Hinzufügen einer `TIMESTAMP`-Spalte immer noch den Fehler `Another user has changed your data` bekommen, können Sie sich mit folgendem Trick behelfen:

  Verwenden Sie keine `table`-Datenblattansicht, sondern legen Sie ein Formular mit den gewünschten Feldern an und benutzen dann die `form`-Datenblattansicht. Die Eigenschaft `DefaultValue` der `TIMESTAMP`-Spalte setzen Sie auf `NOW()`. Am besten verbergen Sie die `TIMESTAMP`-Spalte, um die Benutzer nicht zu verwirren.

- In manchen Fällen generiert Access SQL-Anweisungen, die MySQL nicht versteht. Dann wählen Sie `"Query|SQLSpecific|Pass-Through"` aus dem Access-Menü.

- Auf Windows NT meldet Access `BLOB`-Spalten als `OLE OBJECTS`. Wenn Sie stattdessen `MEMO`-Spalten wünschen, wandeln Sie mit einem `ALTER TABLE` die `BLOB`-Spalten in `TEXT`-Spalten um.

- Access kommt nicht immer mit der `DATE`-Spalte von MySQL zurecht. Wenn Sie deswegen Probleme haben, ändern Sie die Spalten in `DATETIME`-Spalten um.

- Access versucht, `BYTE`-Spalten als `TINYINT` statt als `TINYINT UNSIGNED` zu exportieren. Das führt zu Problemen, wenn die Spalte größere Werte als 127 enthält.

- Wenn Sie in Access äußerst große (long) Tabellen gespeichert haben, kann es lange dauern, sie zu öffnen. Oder es geht Ihnen der virtuelle Speicher aus, sodass Sie einen `ODBC Query Failed`-Fehler bekommen und die Tabelle sich gar nicht mehr öffnen lässt. Dies können Sie mit folgenden Optionen beheben:

  - Return Matching Rows (2)

  - Allow BIG Results (8)

  In der Summe ergibt das 10 (`OPTION=10`).

Einige externe Fachbeiträge und Tipps zu Access, ODBC und MyODBC sind recht nützlich:

- How to Trap ODBC Login Error Messages in Access

- ODBC-Anwendungen für Access optimieren

  - Optimizing for Client/Server Performance

  - Tips for Converting Applications to Using ODBCDirect

  - Tips for Optimizing Queries on Attached SQL Tables

- Eine Liste von Tools für die Verwendung mit Access und ODBC-Datenquellen gibt es unter converters.

###### 25.1.6.2.1.2. Microsoft Excel und Spaltentypen

Wenn Sie Probleme mit dem Importieren von Daten in Microsoft Excel haben, insbesondere bei numerischen Werten sowie Datums- und Uhrzeitwerten, so liegt das wahrscheinlich an einem Excel-Bug: Der Datentyp für Einfügungen in Arbeitsblatt-Zellen wird anhand des Spaltentyps der Quelldaten bestimmt. Das führt dazu, dass Excel den Inhalt nicht richtig identifiziert, was sich sowohl auf das Anzeigeformat als auch auf Berechnungen auswirkt.

Dies beheben Sie, indem Sie in Ihren Anfragen die `CONCAT()`-Funktion einsetzen. So zwingen Sie Excel, den Wert als String zu behandeln: Excel parst dann den String und erkennt die darin enthaltenen Daten richtig.

Dennoch können manche Daten dann immer noch falsch formatiert werden, auch wenn die Quelldaten unverändert bleiben. Die Excel-Option `Zellen formatieren` ändert das Format der angezeigten Informationen.

###### 25.1.6.2.1.3. Microsoft Visual Basic

Um eine Tabelle aktualisieren zu können, müssen Sie zuerst einen Primärschlüssel für die Tabelle definieren.

Visual Basic mit ADO kann mit großen Integern nicht umgehen. Das führt dazu, dass manche Anfragen, wie etwa `SHOW PROCESSLIST`, nicht richtig funktionieren. Dies beheben Sie mit `OPTION=16384` im ODBC-Verbindungs-String oder indem Sie im MyODBC-Verbindungsbildschirm die Option `Change BIGINT columns to INT` aktivieren. Zugleich sollten Sie dann auch die Option `Return matching rows` einschalten.

###### 25.1.6.2.1.4. Microsoft Visual InterDev

Wenn Ihre Ergebnismenge einen `BIGINT` enthält, kann der Fehler `[Microsoft][ODBC Driver Manager] Driver does not support this parameter` auftreten. Versuchen Sie in diesem Fall, die Option `Change BIGINT columns to INT` im MyODBC-Verbindungsbildschirm einzuschalten.

###### 25.1.6.2.1.5. Visual Objects

Wählen Sie bitte die Option `Don't optimize column widths`.

###### 25.1.6.2.1.6. Microsoft ADO

Wenn Sie die ADO-API und MyODBC verwenden, müssen Sie auf einige Standardeigenschaften achten, die vom MySQL Server nicht unterstützt werden. Wenn Sie beispielsweise `CursorLocation Property` als `adUseServer` verwenden, bekommen Sie für die `RecordCount Property` das Ergebnis –1 heraus. Um den richtigen Wert zu erhalten, müssen Sie diese Eigenschaft auf `adUseClient` setzen, wie es im nachfolgenden VB-Code getan wird:

    Dim myconn As New ADODB.Connection
    Dim myrs As New Recordset
    Dim mySQL As String
    Dim myrows As Long

    myconn.Open "DSN=MyODBCsample"
    mySQL = "SELECT * from user"
    myrs.Source = mySQL
    Set myrs.ActiveConnection = myconn
    myrs.CursorLocation = adUseClient
    myrs.Open
    myrows = myrs.RecordCount

    myrs.Close
    myconn.Close

Ein anderer Workaround besteht darin, eine `SELECT COUNT(*)`-Anweisung für ähnliche Abfragen zu verwenden, um die richtige Zeilenzahl zu erhalten.

Um die Anzahl der von einer bestimmten SQL-Anweisung in ADO betroffenen Zeilen zu ermitteln, setzen Sie die Eigenschaft `RecordsAffected` in der ADO-Execute-Methode. Mehr über Execute-Methoden erfahren Sie unter http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdmthcnnexecute.asp.

Weitere Informationen gibt es unter ActiveX Data Objects (ADO) Frequently Asked Questions.

###### 25.1.6.2.1.7. MyODBC mit Active Server Pages (ASP) verwenden

Sie sollten die Option `Return matching rows` im DSN aktivieren.

Weitere Informationen über den Zugriff auf MySQL mit ASP und MyODBC finden Sie in folgenden Fachbeiträgen:

- Using MyODBC To Access Your MySQL Database Via ASP

- ASP and MySQL at DWAM.NT

Eine Liste häufig gestellter Fragen (FAQ) zu ASP finden Sie unter http://support.microsoft.com/default.aspx?scid=/Support/ActiveServer/faq/data/adofaq.asp.

###### 25.1.6.2.1.8. MyODBC mit Visual Basic (ADO, DAO and RDO) und ASP verwenden

Folgende Beiträge bieten Hilfe zu Visual Basic und ASP:

- MySQL BLOB columns and Visual Basic 6 von Mike Hillyer (`<mike@openwin.org>`).

- How to map Visual basic data type to MySQL types von Mike Hillyer (`<mike@openwin.org>`).

##### 25.1.6.2.2. MyODBC mit Borland-Anwendungen verwenden

Für alle Borland-Anwendungen, in denen die Borland Database Engine (BDE) benutzt wird, gelten folgende Hinweise zur Verbesserung der Kompatibilität:

- Aktualisieren Sie auf BDE 3.2 oder neuer.

- Aktivieren Sie die Option `Don't optimize column widths` im DSN.

- Aktivieren Sie die Option `Return matching rows` im DSN.

###### 25.1.6.2.2.1. MyODBC mit Borland Builder 4 verwenden

Wenn Sie eine Anfrage starten, können Sie die Eigenschaft `Active` oder die Methode `Open` einsetzen. Das Starten mit `Active` verläuft so, dass automatisch eine `SELECT * FROM ...`-Anfrage abgesetzt wird. Das kann nach hinten losgehen, wenn Ihre Tabellen zu groß sind.

###### 25.1.6.2.2.2. MyODBC mit Delphi verwenden

Der nachfolgende Delphi-Code kann sehr nützlich sein, um sowohl einen ODBC- als auch einen BDE-Eintrag für MyODBC zu erstellen. Für den BDE-Eintrag ist ein BDE Alias Editor erforderlich, den Sie kostenlos bei einer Delphi Super Page in Ihrer Nähe bekommen können (Danke an Bryan Brunton `<bryan@flesherfab.com>` für dieses Programm):

    fReg:= TRegistry.Create;
    fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True);
    fReg.WriteString('Database', 'Documents');
    fReg.WriteString('Description', ' ');
    fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll');
    fReg.WriteString('Flag', '1');
    fReg.WriteString('Password', '');
    fReg.WriteString('Port', ' ');
    fReg.WriteString('Server', 'xmark');
    fReg.WriteString('User', 'winuser');
    fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True);
    fReg.WriteString('DocumentsFab', 'MySQL');
    fReg.CloseKey;
    fReg.Free;

    Memo1.Lines.Add('DATABASE NAME=');
    Memo1.Lines.Add('USER NAME=');
    Memo1.Lines.Add('ODBC DSN=DocumentsFab');
    Memo1.Lines.Add('OPEN MODE=READ/WRITE');
    Memo1.Lines.Add('BATCH COUNT=200');
    Memo1.Lines.Add('LANGDRIVER=');
    Memo1.Lines.Add('MAX ROWS=-1');
    Memo1.Lines.Add('SCHEMA CACHE DIR=');
    Memo1.Lines.Add('SCHEMA CACHE SIZE=8');
    Memo1.Lines.Add('SCHEMA CACHE TIME=-1');
    Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT');
    Memo1.Lines.Add('SQLQRYMODE=');
    Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE');
    Memo1.Lines.Add('ENABLE BCD=FALSE');
    Memo1.Lines.Add('ROWSET SIZE=20');
    Memo1.Lines.Add('BLOBS TO CACHE=64');
    Memo1.Lines.Add('BLOB SIZE=32');

    AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines);

###### 25.1.6.2.2.3. MyODBC mit C++ Builder verwenden

Ist getestet mit BDE 3.0. Das einzige bekannte Problem ist: Wenn sich das Tabellenschema ändert, werden die Felder der Anfrage nicht aktualisiert. Allerdings erkennt BDE offenbar auch keine Primärschlüssel, sondern nur den Index mit dem Namen `PRIMARY`, was allerdings bisher noch keine Probleme verursacht hat.

##### 25.1.6.2.3. MyODBC mit ColdFusion verwenden

Die folgenden Informationen wurden der ColdFusion-Dokumentation entnommen:

Anhand der folgenden Informationen konfigurieren Sie den ColdFusion Server für Linux für die Benutzung des `unixODBC`-Treibers mit MyODBC für MySQL-Datenquellen. Allaire hat sichergestellt, dass MyODBC 2.50.26 mit MySQL 3.22.27 und ColdFusion für Linux funktioniert. (Auch alle neueren Versionen müssten funktionieren.) Sie können MyODBC unter folgender Adresse herunterladen: http://dev.mysql.com/downloads/connector/odbc/.

Die ColdFusion-Version 4.5.1 ermöglicht es, die MySQL-Datenquelle mit ColdFusion Administrator zu laden. Allerdings wird der Treiber mit der ColdFusion-Version 4.5.1 nicht mitgeliefert. Bevor der MySQL-Treiber in der Dropdown-Liste der ODBC-Datenquellen auftaucht, müssen Sie den MyODBC-Treiber bauen und in `/opt/coldfusion/lib/libmyodbc.so` kopieren.

Das Contrib-Verzeichnis enthält das Programm `mydsn-`xxx`.zip`, mit dem Sie die DSN-Registrierungsdatei für den MyODBC-Treiber in ColdFusion-Anwendungen erstellen und entfernen können.

Weitere Informationen und Hinweise für die Benutzung von ColdFusion und MyODBC finden Sie auf folgenden externen Sites:

- MySQL ColdFusion unixODBC MyODBC and Solaris - how to succeed

- ColdFusion (auf Solaris und NT mit Service Pack 5), How-to: MySQL and ColdFusion

- Troubleshooting Data Sources and Database Connectivity for Unix Platforms

##### 25.1.6.2.4. MyODBC mit OpenOffice verwenden

Open Office (http://www.openoffice.org) How-to: MySQL + OpenOffice. How-to: OpenOffice + MyODBC + unixODBC

##### 25.1.6.2.5. MyODBC mit Sambar Server verwenden

Sambar Server (http://www.sambarserver.info) How-to: MyODBC + SambarServer + MySQL

##### 25.1.6.2.6. MyODBC mit Pervasive Software DataJunction verwenden

Sie müssen dafür sorgen, dass `VARCHAR` statt `ENUM` ausgegeben wird, da `ENUM` in einer Weise exportiert wird, die MySQL Schwierigkeiten verursacht.

##### 25.1.6.2.7. MyODBC mit SunSystems Vision verwenden

Aktivieren Sie bitte die Option `Return matching rows`.

#### 25.1.6.3. MyODBC-Fehler und Lösungen

Im folgenden Abschnitt geht es um häufige Fehler und ihre Behebung oder Alternativlösungen. Wenn Sie danach immer noch Probleme haben, nutzen Sie bitte die MyODBC-Mailingliste unter Abschnitt 25.1.7.1, „MyODBC: Community-Support“.

Viele Probleme lassen sich bereits durch einen Upgrade der MyODBC-Treiber auf die neueste verfügbare Version beheben. Unter Windows müssen Sie auch darauf achten, immer die neueste Version der Microsoft Data Access Components (MDAC) zu installieren.

Questions

- 26.1.6.3.1: Sind MyODBC 2.50-Anwendungen kompatibel mit MyODBC 3.51?

- 26.1.6.3.2: Bei Transaktionen kommt es gelegentlich zu folgendem Fehler:

      Transactions are not enabled

- 26.1.6.3.3: Der folgende Fehler tritt bei der Übermittlung einer Anfrage auf:

      Cursor not found

- 26.1.6.3.4: Access meldet Datensätze als `#DELETED#`, wenn Einträge in verknüpften Tabellen eingefügt oder geändert werden.

- 26.1.6.3.5: Wie gehe ich mit Write Conflicts oder Row Location-Fehlern um?

- 26.1.6.3.6: Beim Exportieren von Daten aus Access 97 in MySQL wird ein `Syntax Error` gemeldet.

- 26.1.6.3.7: Beim Exportieren von Daten aus Microsoft DTS in MySQL wird ein `Syntax Error` gemeldet.

- 26.1.6.3.8: Wenn Sie ODBC.NET mit MyODBC benutzen, wird beim Abrufen von leeren Strings (Strings der Länge 0) die SQL_NO_DATA-Exception ausgelöst.

- 26.1.6.3.9: Wenn Sie `SELECT COUNT(*) FROM `tbl_name`` in Visual Basic und ASP benutzen, wird ein Fehler gemeldet.

- 26.1.6.3.10: Bei Verwendung der ADO-Methode `AppendChunk()` oder `GetChunk()` wird der Fehler `Multiple-step operation generated errors. Check each status value` gemeldet.

- 26.1.6.3.11: Access gibt beim Bearbeiten von Einträgen einer verknüpften Tabelle `Another user had modified the record that you have modified` zurück.

Questions and Answers

26.1.6.3.1: Sind MyODBC 2.50-Anwendungen kompatibel mit MyODBC 3.51?

Anwendungen, die auf MyODBC 2.50 basieren, müssten auch mit MyODBC 3.51 und späteren Versionen gut funktionieren. Wenn Sie feststellen, dass etwas mit der neuesten Version von MyODBC nicht mehr funktioniert, was mit einer älteren Version noch geklappt hat, schicken Sie uns bitte einen Bugreport. Siehe hierzu Abschnitt 25.1.7.2, „Melden von MyODBC-Problemen und -Fehlern“.

26.1.6.3.2: Bei Transaktionen kommt es gelegentlich zu folgendem Fehler:

    Transactions are not enabled

Dies bedeutet, dass Sie auf einer MySQL-Tabelle, die keine Transaktionen unterstützt, eine Transaktion versuchen. Transaktionen werden in MySQL nur von den Speicher-Engines `InnoDB` und `BDB` unterstützt.

Bitte prüfen Sie Folgendes:

- Vergewissern Sie sich, dass Ihr MySQL Server eine transaktionsfähige Speicher-Engine verwendet. `SHOW ENGINES` zeigt Ihnen die Liste der verfügbaren Engines an.

- Vergewissern Sie sich, dass die Tabellen, die Sie zu aktualisieren versuchen, eine transaktionsfähige Speicher-Engine verwenden.

- Achten Sie darauf, dass im DSN nicht die Option `disable transactions` eingeschaltet ist.

26.1.6.3.3: Der folgende Fehler tritt bei der Übermittlung einer Anfrage auf:

    Cursor not found

Dies bedeutet, dass die Anwendung die ältere Version MyODBC 2.50 verwendet und den Cursor-Namen nicht explizit mit SQLSetCursorName gesetzt hat. Dies beheben Sie durch einen Upgrade auf die Version MyODBC 3.51.

26.1.6.3.4: Access meldet Datensätze als `#DELETED#`, wenn Einträge in verknüpften Tabellen eingefügt oder geändert werden.

Wenn die eingefügten oder geänderten Datensätze als `#DELETED#` erscheinen:

- Wenn Sie Access 2000 benutzen, installieren Sie bitte die neueste Version (2.6 oder höher) der Microsoft MDAC (`Microsoft Data Access Components`) von http://www.microsoft.com/data/. Darin wird ein Access-Fehler behoben, der dazu führt, dass bei einem Export von Daten in MySQL die Tabellen- und Spaltennamen nicht angegeben werden. Eine andere Möglichkeit besteht darin, auf MyODBC 2.50.33 oder höher und auf MySQL 3.23.x oder höher aufzurüsten, da beide gemeinsam einen Workaround für dieses Problem enthalten.

  Außerdem sollten Sie das Microsoft Jet 4.0 Service Pack 5 (SP5) anwenden, das unter http://support.microsoft.com/default.aspx?scid=kb;EN-US;q239114 zur Verfügung steht. Damit werden einige Fälle behoben, bei denen Access-Zeilen als `#DELETED#` erscheinen.

  Hinweis: Wenn Sie MySQL 3.22 verwenden, müssen Sie den MDAC-Patch anwenden und MyODBC 2.50.32 oder 2.50.34 (oder höher) installieren, um dieses Problem zu umgehen.

- Für alle Versionen von Access müssen Sie die Option MyODBC `Return matching rows` einschalten. Für Access 2.0 sollten Sie zusätzlich die Option `Simulate ODBC 1.0` aktivieren.

- Alle Tabellen, die später updatefähig sein sollen, müssen einen Timestamp enthalten.

- Jede Tabelle sollte einen Primärschlüssel haben, sonst können neue oder aktualisierte Zeilen als `#DELETED#` erscheinen.

- Verwenden Sie nur `DOUBLE`-Float-Felder. Access kann Float-Werte mit einfacher Genauigkeit nicht vergleichen. Dies führt dazu, dass neue oder aktualisierte Zeilen als `#DELETED#` erscheinen oder nicht zu finden sind.

- Wenn Sie MyODBC zur Verknüpfung einer Tabelle benutzen, die eine `BIGINT`-Spalte hat, werden die Ergebnisse als `#DELETED` angezeigt. Hierfür gibt es folgenden Workaround:

  - Richten Sie eine zusätzliche Dummy-Spalte mit dem Datentyp `TIMESTAMP` ein.

  - Wählen Sie im Verbindungsdialog vom ODBC DSN Administrator die Option `Change BIGINT columns to INT`.

  - Löschen Sie die Tabellenverknüpfung von Access und erstellen Sie sie neu.

  Alte Einträge werden weiterhin als `#DELETED#` angezeigt, aber neue oder geänderte erscheinen in der richtigen Form.

26.1.6.3.5: Wie gehe ich mit Write Conflicts oder Row Location-Fehlern um?

Bei folgenden Fehlern sollten Sie die Option `Return Matching Rows` im DSN-Konfigurationsdialog einstellen oder `OPTION=2` als Verbindungsparameter angeben:

    Write Conflict. Another user has changed your data.

    Row cannot be located for updating. Some values may have been changed
    since it was last read.

26.1.6.3.6: Beim Exportieren von Daten aus Access 97 in MySQL wird ein `Syntax Error` gemeldet.

Dieser Fehler ist spezifisch für Access 97 und MyODBC-Versionen, die älter sind als 3.51.02. Rüsten Sie auf die neueste Version des MyODBC-Treibers auf.

26.1.6.3.7: Beim Exportieren von Daten aus Microsoft DTS in MySQL wird ein `Syntax Error` gemeldet.

Dieser Fehler tritt nur bei MySQL-Tabellen auf, in denen die Datentypen `TEXT` oder `VARCHAR` vorkommen. Rüsten Sie Ihren MyODBC-Treiber auf die Version 3.51.02 oder höher auf.

26.1.6.3.8: Wenn Sie ODBC.NET mit MyODBC benutzen, wird beim Abrufen von leeren Strings (Strings der Länge 0) die SQL_NO_DATA-Exception ausgelöst.

Hierfür gibt es einen Patch unter http://support.microsoft.com/default.aspx?scid=kb;EN-US;q319243.

26.1.6.3.9: Wenn Sie `SELECT COUNT(*) FROM `tbl_name`` in Visual Basic und ASP benutzen, wird ein Fehler gemeldet.

Dieser Fehler tritt auf, weil der Ausdruck `COUNT(*)` einen `BIGINT` zurückliefert, mit dem ADO nichts anfangen kann. Wählen Sie die Option `Change BIGINT columns to INT` (Optionswert 16384).

26.1.6.3.10: Bei Verwendung der ADO-Methode `AppendChunk()` oder `GetChunk()` wird der Fehler `Multiple-step operation generated errors. Check each status value` gemeldet.

Die Methoden `GetChunk()` und `AppendChunk()` von ADO funktionieren nicht richtig, wenn der Cursor-Standort mit `adUseServer` angegeben wird. Das beheben Sie, indem Sie `adUseClient` verwenden.

Ein einfaches Beispiel finden Sie unter http://www.dwam.net/iishelp/ado/docs/adomth02_4.htm.

26.1.6.3.11: Access gibt beim Bearbeiten von Einträgen einer verknüpften Tabelle `Another user had modified the record that you have modified` zurück.

Dies lässt sich meistens durch eine der folgenden Maßnahmen lösen:

- Sie geben der Tabelle einen Primärschlüssel, falls sie noch keinen hat.

- Sie geben der Tabelle einen Timestamp, falls sie noch keinen hat.

- Sie verwenden Float-Felder nur mit doppelter Genauigkeit. Manche Programme können Floats mit einfacher Genauigkeit nicht vergleichen.

Wenn dies alles nichts hilft, legen Sie eine Logdatei für den ODBC-Manager (das Log, das Sie bekommen, wenn Sie eines von ODBCADMIN anfordern) sowie ein MyODBC-Log an. So können Sie vielleicht dem Fehler auf die Spur kommen. Anleitungen finden Sie unter Abschnitt 25.1.3.8, „Erzeugen einer ODBC-Trace-Datei“.

### 25.1.7. MyODBC-Support

Es gibt viele Stellen, an denen Sie sich Hilfe zu MyODBC holen können. Schauen Sie immer als Erstes in die MyODBC-Mailingliste oder das MyODBC-Forum. Unter Abschnitt 25.1.7.1, „MyODBC: Community-Support“ erfahren Sie, was zu tun ist, ehe Sie einen Bug oder ein Problem an MySQL melden.

#### 25.1.7.1. MyODBC: Community-Support

MySQL AB stellt der Benutzergemeinde via Mailingliste Hilfe zur Verfügung. Bei MyODBC-Problemen helfen Ihnen erfahrene Nutzer in der Mailingliste `<myodbc@lists.mysql.com>` weiter. Die Archive stehen online unter http://lists.mysql.com/myodbc zur Verfügung.

Wie Sie die MySQL-Mailinglisten abonnieren oder die Archive durchforsten können, erfahren Sie unter http://lists.mysql.com/. Siehe Abschnitt 1.7.1, „Die MySQL-Mailinglisten“.

Support von erfahrenen Benutzern bekommen Sie auch im MyODBC Forum sowie in den anderen MySQL-Foren unter http://forums.mysql.com. Siehe Abschnitt 1.7.2, „MySQL-Community-Support in den MySQL-Foren“.

#### 25.1.7.2. Melden von MyODBC-Problemen und -Fehlern

Bei Schwierigkeiten oder Problemen mit MyODBC sollten Sie als Erstes eine Logdatei mit dem `ODBC Manager` (das Log, das Sie erhalten, wenn Sie eines von `ODBC ADMIN` anfordern) und für MyODBC anlegen. Wie das geht, erfahren Sie unter Abschnitt 25.1.3.8, „Erzeugen einer ODBC-Trace-Datei“.

Vielleicht finden Sie in der MyODBC-Trace-Datei die Fehlerursache. Der String `>mysql_real_query` im `myodbc.log` verrät Ihnen, welche Anweisungen abgesetzt wurden.

Außerdem können Sie versuchen, die Anweisungen aus dem mysql-Clientprogramm oder `admndemo` einzugeben. So können Sie herausfinden, ob das Problem an MyODBC oder MySQL liegt.

Wenn Sie feststellen, dass etwas schief geht, senden Sie bitte nur die relevanten Zeilen (maximal 40) an die `myodbc`-Mailingliste. Siehe auch Abschnitt 1.7.1, „Die MySQL-Mailinglisten“. Senden Sie bitte niemals die gesamte MyODBC- oder ODBC-Logdatei!

Im Idealfall sollte Ihre E-Mail folgende Informationen enthalten:

- Betriebssystem und Version

- MyODBC-Version

- ODBC-Treiber-Manager-Typ und -Version

- MySQL Server-Version

- ODBC-Trace vom Treiber-Manager

- MyODBC-Logdatei vom MyODBC-Treiber

- ein einfaches, reproduzierbares Beispiel

Denken Sie daran: Je mehr Informationen Sie uns geben können, umso wahrscheinlicher ist es, dass wir eine Lösung finden!

Schauen Sie jedoch immer in das Archiv der MyODBC-Mailingliste, ehe Sie uns einen Fehler melden: http://lists.mysql.com/myodbc.

Wenn Sie nicht herausfinden können, wo das Problem liegt, können Sie als letztes Mittel ein Archiv im tar- oder Zip-Format anlegen, das eine MyODBC-Trace-Datei, die ODBC-Logdatei und eine `README`-Datei mit einer Problembeschreibung enthält. Diese können Sie an ftp://ftp.mysql.com/pub/mysql/upload/ senden. Nur MySQL-Ingenieure haben Zugriff auf die Dateien, die Sie hochladen, und wir gehen sehr diskret mit den Daten um.

Wenn Sie ein Programm schreiben können, welches das Problem demonstriert, fügen Sie es bitte ebenfalls dem Archiv hinzu.

Wenn das Programm mit einem anderen SQL-Server läuft, legen Sie bitte eine ODBC-Logdatei bei, in der genau dieselben SQL-Anweisungen ausgeführt werden, damit wir die Ergebnisse der beiden Systeme miteinander vergleichen können.

Wieder gilt: Je mehr Informationen Sie uns geben können, umso wahrscheinlicher ist es, dass wir eine Lösung finden.

#### 25.1.7.3. Wie man einen MyODBC-Patch übermittelt

Einen Patch oder Lösungsvorschlag für vorhandenen Code oder bekannte Probleme übermitteln Sie bitte per E-Mail an `<myodbc@lists.mysql.com>`.

#### 25.1.7.4. Danksagungen

Die folgenden Entwickler haben an der Entwicklung von MyODBC und den MyODBC 3.51-Treibern von MySQL AB mitgearbeitet.

- Michael (Monty) Widenius

- Venu Anuganti

- Peter Harvey

## 25.2. Connector/NET

Mit Connector/NET lassen sich .NET-Anwendungen entwickeln, die sichere und leistungsfähige Datenbankverbindungen mit MySQL benutzen. Connector/NET implementiert die erforderlichen ADO.NET-Schnittstellen und lässt sich in ADO.NET-fähige Tools integrieren. Die Entwickler können ihre Anwendungen in den .NET-Sprachen ihrer Wahl schreiben. Connector/NET ist ein vollständig verwalteter ADO.NET-Treiber, der zu 100 % in C# geschrieben wurde.

Connector/NET bietet volle Unterstützung für:

- MySQL 5.0-Features (beispielsweise gespeicherte Prozeduren)

- MySQL 4.1-Features (vorbereitete Anweisungen auf der Serverseite, Unicode, Shared Memory-Zugriff usw.)

- große Pakete zum Senden und Empfangen von bis zu 2 Gbyte großen Zeilen und BLOBs

- Protokollkompression zum Komprimieren des Datenstroms zwischen Client und Server

- Verbindung über TCP/IP-Sockets, Named Pipes oder Shared Memory auf Windows

- Verbindung über TCP/IP-Sockets oder Unix-Sockets auf Unix

- Open Source Mono-Framework von Novell

- vollständig verwaltet, benutzt keine MySQL-Clientbibliothek

Dieses Dokument soll den Benutzer zur Verwendung von Connector/NET anleiten und enthält eine vollständige Syntaxreferenz. Syntaxinformationen finden Sie auch in der Datei `Documentation.chm` in Ihrer Connector/NET-Distribution.

### 25.2.1. Versionen von Connector/NET

Gegenwärtig ist nur eine Version von Connector/NET erhältlich:

- Connector/NET 1.0 bietet Unterstützung für die Features von MySQL 4.0 und MySQL 5.0 sowie volle Kompatibilität mit dem ADO.NET-Treiber.

### 25.2.2. Installation von Connector/NET

Connector/NET läuft auf jeder Plattform, die das .NET-Framework unterstützt. Das ist vor allem bei den neueren Versionen von Microsoft Windows der Fall, sowie bei Linux über das Open Source Mono-Framework (siehe http://www.mono-project.com).

Connector/NET können Sie von folgender Adresse herunterladen: http://dev.mysql.com/downloads/connector/net/1.0.html.

#### 25.2.2.1. Installation von Connector/NET auf Windows

Auf Windows installieren Sie Connector/NET entweder mit einer Binärversion oder aus einer heruntergeladenen Zip-Datei mit den Connector/NET-Komponenten.

Vor der Installation müssen Sie sicherstellen, dass Ihr System aktuell ist und dass Sie die neueste Version von .NET besitzen.

##### 25.2.2.1.1. Installation von Connector/NET mit dem Installer

Mit dem Installer gelingt die Installation von Connector/NET auf Windows am einfachsten. Er installiert den Quellcode, den Testcode und die vollständige Referenzdokumentation.

Connector/NET wird auf allen Windows-Betriebssystemen mit einem Windows-Installer (`.msi`-Installations-Package) installiert. Das MSI-Package liegt in einem ZIP-Archiv namens `mysql-connector-net-`version`.zip`, wobei `version` die Connector/NET-Version ist.

Connector/NET installieren Sie wie folgt:

1. Führen Sie einen Doppelklick auf die aus der heruntergeladenen Zip-Datei extrahierte MSI-Installer-Datei aus. Mit einem Klick auf Next starten Sie die Installation.

2. Sie müssen den gewünschten Installationstyp auswählen.

   Für die meisten Fälle eignet sich die typische Installation. Klicken Sie also auf Typical und fahren Sie fort mit Schritt 5. Mit der vollständigen (Complete) Installation installieren Sie sämtliche verfügbaren Dateien. Hierzu klicken Sie auf die Schaltfläche Complete und machen dann mit Schritt 5 weiter. Wenn Sie eine benutzerdefinierte Installation bevorzugen und die zu installierenden Komponenten und Optionen selbst auswählen möchten, klicken Sie auf Custom und machen mit Schritt 3 weiter.

3. Bei der benutzerdefinierten Installation können Sie die einzelnen zu installierenden Komponenten selbst aussuchen, einschließlich der Core-Interface-Komponente, der Dokumentation (einer CHM-Datei), Beispielen und des Quellcodes. Wählen Sie die zu installierenden Bestandteile aus und klicken Sie auf Next.

4. Bei einer benutzerdefinierten Installation können Sie auch entscheiden, ob die Connector/NET-Komponente im Global Assembly Cache registriert werden soll. Dann steht Connector/NET allen Anwendungen zur Verfügung, nicht nur denen, die explizit auf Connector/NET verweisen. Sie können auch die Erzeugung von entsprechenden Symbolen im Startmenü aktivieren oder deaktivieren. Wenn Sie die notwendigen Optionen ausgewählt haben, klicken Sie wieder auf Next.

5. Zum Schluss haben Sie Gelegenheit, die Installation zu bestätigen. Klicken Sie auf Install, um die Dateien auf Ihren Computer zu übertragen und zu installieren.

6. Ist die Installation abgeschlossen, schließen Sie den Installer mit einem Klick auf Finish.

Wenn Sie nichts anderes eingestellt haben, wird Connector/NET `C:\Program Files\MySQL\MySQL Connector Net `X.X.X`` installiert, wobei `X.X.X` die installierte Version von Connector/NET ist. Neue Installationen werden die vorhandenen Versionen von Connector/NET nicht überschreiben.

Je nach Installationstyp werden einige oder alle der folgenden Komponenten installiert:

- `bin` – Connector/NET MySQL-Bibliotheken für verschiedene Versionen der .NET-Umgebung

- `docs` – enthält eine CHM der Connector/NET-Dokumentation

- `samples` – Beispielcode und -anwendungen, die die Connector/NET-Komponente nutzen

- `src` – der Quellcode für die Connector/NET-Komponente

##### 25.2.2.1.2. Installation von Connector/NET aus dem Zip-Archiv

Wenn Sie Schwierigkeiten mit dem Installer haben, können Sie auch eine .zip-Datei ohne Installer herunterladen. Diese Datei heißt `mysql-connector-net-`version`-noinstall.zip`. Die darin enthaltenen Dateien extrahieren Sie in ein Verzeichnis Ihrer Wahl.

Die .zip-Datei enthält folgende Verzeichnisse:

- `bin` - Connector/NET MySQL-Bibliotheken für verschiedene Versionen von .NET

- `doc` – eine CHM-Version der Connector/NET-Dokumentation

- `Samples` – Beispielcode und -anwendungen, die die Connector/NET-Komponente nutzen

- `mysqlclient` – der Quellcode für die Connector/NET-Komponente

- `testsuite` – Testsuite zur Funktionsprüfung der Connector/NET-Komponente.

##### 25.2.2.1.3. Installation von Connector/NET auf Unix mit Mono

Es gibt keinen Installer für Connector/NET auf Unix, aber die Installation ist dennoch ganz einfach. Vorher müssen Sie gewährleisten, dass Sie über eine funktionierende Mono-Installation verfügen.

Installieren Sie Connector/NET bitte nur auf Unix, wenn Sie sich mit einem MySQL Server über Mono verbinden wollen. Möchten Sie Connector/NET in einer anderen Umgebung, wie beispielsweise Java oder Perl, installieren oder damit arbeiten, wählen Sie bitte eine passendere Komponente für die Verbindungen aus. Weitere Informationen finden Sie unter Kapitel 25, Connectors, oder Kapitel 24, APIs und Bibliotheken.

Um Connector/NET auf Unix/Mono zu installieren, gehen Sie folgendermaßen vor:

1. Laden Sie `mysql-connector-net-`version`-noinstall.zip` herunter und extrahieren Sie den Inhalt.

2. Kopieren Sie die Datei `MySql.Data.dll` in Ihren Installationsordner für das Mono-Projekt.

3. Mit folgendem `gacutil`-Befehl registrieren Sie die Connector/NET-Komponente im Global Assembly Cache:

       shell> gacutil /i MySql.Data.dll

Nach der Installation sind an Anwendungen, die mit der Connector/NET-Komponente installiert wurden, keine weiteren Änderungen mehr erforderlich. Sie müssen allerdings darauf achten, die Connector/NET-Komponente mit der Kommandozeilenoption `-r:MySqlData.dll` beim Kompilieren Ihrer Anwendungen einzubinden.

#### 25.2.2.2. Installation von Connector/NET aus der Quelldistribution

Vorsicht: Diesen Abschnitt sollten Sie nur lesen, wenn Sie uns beim Testen des neuen Codes unterstützen möchten. Wenn Sie lediglich Connector/NET auf Ihrem System zum Laufen bringen möchten, verwenden Sie am besten eine Standarddistribution.

Um auf den Connector/NET-Quellbaum zugreifen zu können, müssen Sie Subversion installieren. Sie erhalten Subversion kostenlos von http://subversion.tigris.org/.

Den aktuellsten Entwicklungsquellbaum erhalten Sie in unseren öffentlichen Subversion-Bäumen unter http://dev.mysql.com/tech-resources/sources.html.

Um die Quelldateien von Connector/NET auszuchecken, gehen Sie in das Verzeichnis, in welches Sie den Connector/NET-Baum kopieren möchten, und geben folgenden Befehl ein:

    shell> svn co
    http://svn.mysql.com/svnpublic/connector-net

Die Quelldateien enthalten auch ein Visual Studio-Projekt, das Sie nutzen können, um Connector/NET zu bauen.

### 25.2.3. Hinweise und Tipps zu Connector/NET

Dieser Abschnitt behandelt einige häufige Einsatzgebiete für Connector/NET, darunter den Umgang mit BLOBs und Datumswerten sowie die Kombination von Connector/NET mit gebräuchlichen Tools wie Crystal Reports.

#### 25.2.3.1. MySQL-Verbindung mit Connector/NET

##### 25.2.3.1.1. Einleitung

Jegliche Interaktion zwischen einer .NET-Anwendung und einem MySQL Server vollzieht sich durch ein `MySqlConnection`-Objekt. Also muss, ehe Sie mit dem Server kommunizieren können, zunächst ein `MySqlConnection`-Objekt erzeugt, konfiguriert und geöffnet werden.

Auch wenn die Klasse `MySqlHelper` benutzt wird, wird ein `MySqlConnection`-Objekt von dieser Hilfsklasse angelegt.

In diesem Abschnitt wird beschrieben, wie man über das `MySqlConnection`-Objekt mit MySQL Verbindung aufnimmt.

##### 25.2.3.1.2. Verbindungs-String erstellen

Das `MySqlConnection`-Objekt ist für einen Verbindungs-String konfiguriert. Dieser String enthält mehrere, durch Semikola getrennte Schlüssel/Wert-Paare, die jeweils durch ein Gleichheitszeichen verbunden sind.

Sehen Sie hier ein Beispiel für einen Verbindungs-String:

        Server=127.0.0.1;Uid=root;Pwd=12345;Database=test;

In diesem Beispiel ist das `MySqlConnection`-Objekt so konfiguriert, dass es sich mit einem MySQL Server auf `127.0.0.1` verbindet und dazu den Benutzernamen `root` und das Passwort `12345` verwendet. Als Standarddatenbank für alle Anweisungen benutzen wir `test`.

Die folgenden Optionen werden typischerweise gesetzt (eine vollständige Liste der Optionen finden Sie in der nachfolgenden Tabelle):

- `Server`: Der Name oder die Netzwerkadresse der MySQL-Instanz, mit der Verbindung aufgenommen werden soll. Der Standardwert ist `localhost`. Aliase sind `host`, `Data Source`, `DataSource`, `Address`, `Addr` und `Network Address`.

- `Uid`: Das MySQL-Benutzerkonto, das für die Verbindung genutzt wird. Aliase sind `User Id`, `Username` und `User name`.

- `Pwd`: Das Passwort für das verwendete MySQL-Konto. Der Alias `Password` kann ebenfalls gesetzt werden.

- `Database`: Die Standarddatenbank, auf die alle Anweisungen angewendet werden. Der Standardwert lautet `mysql`, aber es kann auch der Alias `Initial Catalog` verwendet werden.

- `Port`: Der Port, auf dem MySQL auf Verbindungen lauscht. Der Standardwert ist `3306`. Wenn Sie hier `-1` einsetzen, wird eine Named-Pipe-Verbindung verwendet.

Die folgende Tabelle führt die Namen für alle zulässigen Schlüsselwortwerte des `ConnectionString`s auf.

Name | Standardwert | Beschreibung
Connect Timeout -oder- Connection Timeout | 15 | So viele Sekunden wird auf eine Serververbindung gewartet, ehe der Versuch abgebrochen und ein Fehler ausgelöst wird.

Host -oder- Server -oder- Data Source -oder- DataSource -oder- Address -oder- Addr -oder- Network Address

localhost

Name oder Netzwerkadresse der MySQL-Instanz, mit der Verbindung aufgenommen wird. Es können mehrere, durch & getrennte Hosts angegeben werden. Das kann praktisch sein, wenn mehrere MySQL Server für die Replikation konfiguriert wurden und Sie nicht wissen, mit welchem Server Sie sich verbinden. Da der Provider Schreibvorgänge auf der Datenbank nicht synchronisiert, müssen Sie mit dieser Option vorsichtig sein. In einer Unix-Umgebung mit Mono kann dies ein vollqualifizierter Pfad zu einer MySQL-Socketdatei sein. Dann wird der Unix-Socket anstelle des TCP/IP-Sockets benutzt. Da zurzeit nur ein einziger Socketname angegeben werden kann, wird der MySQL-Zugriff in einer Replikationsumgebung über Unix-Sockets aktuell noch nicht unterstützt.

Port | 3306 | Der Port, auf dem MySQL auf Verbindungen lauscht. Wenn Sie hier -1 angeben, wird eine Named-Pipe-Verbindung benutzt (nur Windows). Dieser Wert wird bei Verwendung von Unix-Socket ignoriert.
Protocol | socket | Gibt an, welche Art von Serververbindung eingerichtet wird. Mögliche Werte sind: socket oder tcp für eine Socketverbindung, pipe für eine Named-Pipe-Verbindung, unix für eine Unix-Socketverbindung und memory für MySQL-Shared Memory
CharSet -oder- Character Set |  | Der Zeichensatz, mit dem alle an den Server gesandten Anfragen kodiert werden. Ergebnismengen werden weiterhin in dem Zeichensatz der Rückgabedaten kodiert.
Logging | false | Ist diese Option true, werden diverse Informationen an die eingestellten TraceListeners ausgegeben.
Allow Batch | true | Ist diese Option true, können mehrere SQL-Anweisungen mit einem einzigen Befehl ausgeführt werden. Hinweis: Seit MySQL 4.1.1 müssen Batch-Anweisungen durch das für den Server definierte Trennzeichen voneinander abgesetzt werden. Für frühere Versionen von MySQL ist ';' das Trennzeichen.
Encrypt | false | Ist diese Option `true`, wird für alle zwischen Client und Server übermittelten Daten SSL-Verschlüsselung verwendet, wenn auf dem Server ein Zertifikat installiert ist. Zulässige Werte sind `true`, `false`, `yes` und `no`. Hinweis: Dieser Parameter ist zurzeit wirkungslos.
Initial Catalog -oder- Database | mysql | Der Name der Datenbank, die anfangs genutzt wird
Password -oder- pwd |  | Das Passwort für das verwendete MySQL-Konto

Persist Security Info

false

Ist diese Option `false` oder `no` (was dringend empfohlen wird), werden sicherheitsrelevante Daten wie beispielsweise das Passwort nicht mit der Verbindung zurückgegeben, wenn die Verbindung geöffnet ist oder jemals war. Mit dem Verbindungs-String werden auch alle darin enthaltenen Werte zurückgesetzt, einschließlich des Passworts. Zulässige Werte sind `true`, `false`, `yes` und `no`.

User Id -oder- Username -oder- Uid -oder- User name |  | Das für das Login verwendete MySQL-Konto
Shared Memory Name | MYSQL | Der Name des Shared Memory-Objekts, das für die Kommunikation genutzt wird, wenn das Verbindungsprotokoll auf "memory" gesetzt wurde.
Allow Zero Datetime | false | Stellen Sie dies auf true, wenn MySqlDataReader.GetValue() für Datums-/Uhrzeitspalten, die unzulässige Werte aufweisen, eine MySqlDateTime zurückgeben soll, und auf false, wenn nur für zulässige Werte ein DateTime-Objekt, aber für unzulässige eine Ausnahme zurückgegeben werden soll.
Convert Zero Datetime | false | Ist diese Option true, geben MySqlDataReader.GetValue() und MySqlDataReader.GetDateTime() für Datums- oder Datums-/Uhrzeitspalten, die unzulässige Werte aufweisen, DateTime.MinValue zurück.
Old Syntax -oder- OldSyntax | false | Erlaubt '@' als Parameterkennzeichen. Mehr darüber in `MySqlCommand`. Dient nur der Kompatibilität. Zukünftig soll immer das Parameterkennzeichen '?' benutzt werden.
Pipe Name -oder- Pipe | mysql | Ist diese der Name einer Named Pipe, versucht `MySqlConnection`, diese zur Verbindung zu nutzen. Gilt nur für Windows.

##### 25.2.3.1.3. Eine Verbindung öffnen

Sobald Sie den Verbindungs-String angelegt haben, können Sie ihn nutzen, um eine Verbindung zu einem MySQL Server damit aufzubauen.

Der folgende Code erzeugt ein `MySqlConnection`-Objekt, weist den Verbindungs-String zu und öffnet die Verbindung.

Visual Basic-Beispiel

    Dim conn As New MySql.Data.MySqlClient.MySqlConnection
    Dim myConnectionString as String

    myConnectionString = "server=127.0.0.1;" _
                & "uid=root;" _
                & "pwd=12345;" _
                & "database=test;"

    Try
      conn.ConnectionString = myConnectionString
      conn.Open()

    Catch ex As MySql.Data.MySqlClient.MySqlException
      MessageBox.Show(ex.Message)
    End Try

C#-Beispiel

    MySql.Data.MySqlClient.MySqlConnection conn;
    string myConnectionString;

    myConnectionString = "server=127.0.0.1;uid=root;" +
        "pwd=12345;database=test;";

    try
    {
        conn = new MySql.Data.MySqlClient.MySqlConnection();
        conn.ConnectionString = myConnectionString;
        conn.Open();
    }
    catch (MySql.Data.MySqlClient.MySqlException ex)
    {
        MessageBox.Show(ex.Message);
    }

Sie können den Verbindungs-String auch an den Klassenkonstruktor von `MySqlConnection` übergeben:

Visual Basic-Beispiel

    Dim myConnectionString as String

    myConnectionString = "server=127.0.0.1;" _
                  & "uid=root;" _
                  & "pwd=12345;" _
                  & "database=test;"

    Try
        Dim conn As New MySql.Data.MySqlClient.MySqlConnection(myConnectionString)
        conn.Open()
    Catch ex As MySql.Data.MySqlClient.MySqlException
       MessageBox.Show(ex.Message)
    End Try

C#-Beispiel

    MySql.Data.MySqlClient.MySqlConnection conn;
    string myConnectionString;

    myConnectionString = "server=127.0.0.1;uid=root;" +
        "pwd=12345;database=test;";

    try
    {
        conn = new MySql.Data.MySqlClient.MySqlConnection(myConnectionString);
        conn.Open();
    }
    catch (MySql.Data.MySqlClient.MySqlException ex)
    {
        MessageBox.Show(ex.Message);
    }

Sobald die Verbindung geöffnet ist, können auch andere Connector/NET-Klassen sie zur Kommunikation mit dem MySQL Server nutzen.

##### 25.2.3.1.4. Behandlung von Verbindungsfehlern

Da eine Verbindung mit einem externen Server immer Unwägbarkeiten in sich birgt, muss Ihre .NET-Anwendung auch mit Fehlern umgehen können. Tritt bei der Verbindung ein Fehler auf, gibt die Klasse `MySqlConnection` ein `MySqlException`-Objekt zurück. Dieses Objekt hat zwei Eigenschaften, die für die Fehlerbehandlung interessant sind:

- `Message`: eine Meldung, die die Ausnahme beschreibt

- `Number`: die MySQL-Fehlernummer

Sie können die Reaktion Ihrer Anwendung auf Fehler auf der Basis der Fehlernummer gestalten. Die beiden Fehler, die bei Verbindungsproblemen am häufigsten auftreten, sind:

- `0`: Serververbindung nicht möglich

- `1045`: Benutzername und/oder Passwort ungültig

Der folgende Code zeigt, wie die Anwendung auf die jeweilige Fehlernummer reagieren kann:

Visual Basic-Beispiel

    Dim myConnectionString as String

    myConnectionString = "server=127.0.0.1;" _
              & "uid=root;" _
              & "pwd=12345;" _
              & "database=test;"

    Try
        Dim conn As New MySql.Data.MySqlClient.MySqlConnection(myConnectionString)
        conn.Open()
    Catch ex As MySql.Data.MySqlClient.MySqlException
        Select Case ex.Number
            Case 0
                MessageBox.Show("Cannot connect to server. Contact administrator")
            Case 1045
                MessageBox.Show("Invalid username/password, please try again")
        End Select
    End Try

C#-Beispiel

    MySql.Data.MySqlClient.MySqlConnection conn;
    string myConnectionString;

    myConnectionString = "server=127.0.0.1;uid=root;" +
        "pwd=12345;database=test;";

    try
    {
        conn = new MySql.Data.MySqlClient.MySqlConnection(myConnectionString);
        conn.Open();
    }
        catch (MySql.Data.MySqlClient.MySqlException ex)
    {
        switch (ex.Number)
        {
            case 0:
                MessageBox.Show("Cannot connect to server.  Contact administrator");
            case 1045:
                MessageBox.Show("Invalid username/password, please try again");
        }
    }

Wichtig: Wenn Sie Datenbanken mit mehreren Sprachen verwenden, müssen Sie den jeweiligen Zeichensatz im Verbindungs-String angeben, sonst wird `latin1` als Standardzeichensatz zugrunde gelegt. Ein Beispiel für die Angabe eines Zeichensatzes im Verbindungs-String folgt:

    MySqlConnection myConnection = new MySqlConnection("server=127.0.0.1;uid=root;" +
        "pwd=12345;database=test;Charset=latin1;");

#### 25.2.3.2. Connector/NET mit vorbereiteten Anweisungen verwenden

##### 25.2.3.2.1. Einleitung

Seit MySQL 4.1 ist es möglich, vorbereitete Anweisungen mit Connector/NET zu verwenden. Diese können bei Anfragen, die immer wieder ausgeführt werden müssen, die Leistung massiv steigern.

Die vorbereitete Ausführung von Anweisungen ist viel schneller als die direkte Ausführung, da die Anfrage nur ein einziges Mal geparst werden muss. Bei einer Direktausführung müsste sie jedes Mal von neuem geparst werden. Außerdem kann die vorbereitete Ausführung die Netzwerklast reduzieren, da bei der Ausführung einer vorbereiteten Anweisung nur die Parameterdaten übermittelt werden müssen.

Ein weiterer Vorteil vorbereiteter Anweisungen ist die Verwendung eines Binärprotokolls, das die Datenübertragung zwischen Client und Server beschleunigt.

##### 25.2.3.2.2. Anweisungen vorbereiten in Connector/NET

Um eine Anweisung vorzubereiten, erzeugen Sie ein Befehlsobjekt und stellen die Eigenschaft `.CommandText` auf Ihre Anfrage ein.

Nach dem Eintritt in die Anweisung rufen Sie die `.Prepare`-Methode des `MySqlCommand`-Objekts auf. Ist die Anweisung vorbereitet, fügen Sie die Parameter für die dynamischen Elemente der Anfrage hinzu.

Danach führen Sie die Anweisung mit `.ExecuteNonQuery()`-, `.ExecuteScalar()`- oder `.ExecuteReader`-Methoden aus.

Für jede weitere Ausführung müssen Sie nur noch die Parameterwerte einstellen und dann die Ausführungsmethode erneut aufrufen. Es ist nicht mehr erforderlich, die `.CommandText`-Eigenschaft zu setzen oder die Parameter umzudefinieren.

Visual Basic-Beispiel

    Dim conn As New MySqlConnection
    Dim cmd As New MySqlCommand

    conn.ConnectionString = strConnection

    Try
       conn.Open()
       cmd.Connection = conn

       cmd.CommandText = "INSERT INTO myTable VALUES(NULL, ?number, ?text)"
       cmd.Prepare()

       cmd.Parameters.Add("?number", 1)
       cmd.Parameters.Add("?text", "One")

       For i = 1 To 1000
           cmd.Parameters["?number"].Value = i
           cmd.Parameters["?text"].Value = "A string value"

           cmd.ExecuteNonQuery()
         Next
    Catch ex As MySqlException
        MessageBox.Show("Error " & ex.Number & " has occurred: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

C#-Beispiel

    MySql.Data.MySqlClient.MySqlConnection conn;
    MySql.Data.MySqlClient.MySqlCommand cmd;

    conn = new MySql.Data.MySqlClient.MySqlConnection();
    cmd = new MySql.Data.MySqlClient.MySqlCommand();

    conn.ConnectionString = strConnection;

    try
    {
        conn.Open();
        cmd.Connection = conn;

        cmd.CommandText = "INSERT INTO myTable VALUES(NULL, ?number, ?text)";
        cmd.Prepare();

        cmd.Parameters.Add("?number", 1);
        cmd.Parameters.Add("?text", "One");

        for (int i=1; i <= 1000; i++)
        {
            cmd.Parameters["?number"].Value = i;
            cmd.Parameters["?text"].Value = "A string value";

            cmd.ExecuteNonQuery();
        }
    }
    catch (MySql.Data.MySqlClient.MySqlException ex)
    {
        MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,
            "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

#### 25.2.3.3. Zugriff auf gespeicherte Prozeduren mit Connector/NET

##### 25.2.3.3.1. Einleitung

Seit der MySQL-Version 5 kennt der MySQL Server nun auch gespeicherte Prozeduren mit der Syntax von SQL 2003.

Eine gespeicherte Prozedur besteht in einer Reihe von SQL-Anweisungen, die im Server gespeichert werden können. fortan müssen die Clients keine individuellen Anweisungen mehr geben, sondern können stattdessen auf die gespeicherte Prozedur verweisen.

Gespeicherte Prozeduren können vor allem in folgenden Situationen nützlich sein:

- Wenn mehrere Clientanwendungen in verschiedenen Sprachen für unterschiedliche Plattformen geschrieben wurden, aber dieselben Datenbankoperationen ausführen.

- In Hochsicherheitsumgebungen. Banken nutzen beispielsweise für alle häufigen Operationen gespeicherte Prozeduren. So bleibt die Umgebung konsistent und sicher, und die Prozeduren sorgen dafür, dass jede Operation ordentlich protokolliert wird. In einer solchen Konstellation haben Anwendungen und Benutzer keinen Direktzugriff auf die Datenbanktabellen, sondern können lediglich bestimmte gespeicherte Prozeduren ausführen.

Connector/NET unterstützt den Aufruf von gespeicherten Prozeduren mit dem `MySqlCommand`-Objekt. Zur Übergabe von Daten in die und aus der gespeicherten Prozedur von MySQL dient die `MySqlCommand.Parameters`-Collection.

Hinweis: Wenn Sie eine gespeicherte Prozedur aufrufen, setzt das Befehlsobjekt einen zusätzlichen `SELECT`-Aufruf ab, um die Parameter der gespeicherten Prozedur zu ermitteln. Sie müssen sicherstellen, dass der Benutzer, der die Prozedur aufruft, die `SELECT`-Berechtigung für die `mysql.proc`-Tabelle besitzt, um die Parameter überprüfen zu können. Sonst wird beim Aufruf der Prozedur ein Fehler ausgelöst.

Eine tiefer gehende Erörterung zu gespeicherten Prozeduren finden Sie in http://dev.mysql.com/doc/mysql/en/stored-procedures.html, aber nicht im vorliegenden Abschnitt.

Eine Beispielanwendung zur Verwendung von gespeicherten Prozeduren mit Connector/NET finden Sie im `Samples`-Verzeichnis Ihrer Connector/NET-Installation.

##### 25.2.3.3.2. Erstellung von gespeicherten Prozeduren mit Connector/NET

In MySQL gibt es mehrere Möglichkeiten, gespeicherte Prozeduren anzulegen. Erstens können gespeicherte Prozeduren mit dem Kommandozeilen-Client mysql erzeugt werden, zweitens mit dem GUI-Client `MySQL Query Browser` und drittens mit der `.ExecuteNonQuery`-Methode des `MySqlCommand`-Objekts:

Visual Basic-Beispiel

    Dim conn As New MySqlConnection
    Dim cmd As New MySqlCommand

    conn.ConnectionString = "server=127.0.0.1;" _
        & "uid=root;" _
        & "pwd=12345;" _
        & "database=test"

    Try
        conn.Open()
        cmd.Connection = conn

        cmd.CommandText = "CREATE PROCEDURE add_emp(" _
            & "IN fname VARCHAR(20), IN lname VARCHAR(20), IN bday DATETIME, OUT empno INT) " _
            & "BEGIN INSERT INTO emp(first_name, last_name, birthdate) " _
            & "VALUES(fname, lname, DATE(bday)); SET empno = LAST_INSERT_ID(); END"

        cmd.ExecuteNonQuery()
    Catch ex As MySqlException
        MessageBox.Show("Error " & ex.Number & " has occurred: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

C#-Beispiel

    MySql.Data.MySqlClient.MySqlConnection conn;
    MySql.Data.MySqlClient.MySqlCommand cmd;

    conn = new MySql.Data.MySqlClient.MySqlConnection();
    cmd = new MySql.Data.MySqlClient.MySqlCommand();

    conn.ConnectionString = "server=127.0.0.1;uid=root;" +
        "pwd=12345;database=test;";

    try
    {
        conn.Open();
        cmd.Connection = conn;

        cmd.CommandText = "CREATE PROCEDURE add_emp(" +
            "IN fname VARCHAR(20), IN lname VARCHAR(20), IN bday DATETIME, OUT empno INT) " +
            "BEGIN INSERT INTO emp(first_name, last_name, birthdate) " +
            "VALUES(fname, lname, DATE(bday)); SET empno = LAST_INSERT_ID(); END";

        cmd.ExecuteNonQuery();
    }
    catch (MySql.Data.MySqlClient.MySqlException ex)
    {
    MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,
        "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

Wenn Sie gespeicherte Prozeduren in Connector/NET anlegen, sind Sie, anders als beim Kommandozeilen- oder GUI-Client, nicht auf ein bestimmtes Trennzeichen festgelegt.

##### 25.2.3.3.3. Aufruf einer gespeicherten Prozedur mit Connector/NET

Um eine gespeicherte Prozedur mit Connector/NET aufzurufen, erzeugen Sie ein `MySqlCommand`-Objekt und übergeben den Namen der Prozedur als `.CommandText`-Eigenschaft. Setzen Sie die `.CommandType`-Eigenschaft auf `CommandType.StoredProcedure`.

Auf die Angabe der gespeicherten Prozedur folgt für jeden ihrer Parameter ein `MySqlCommand`-Parameter. `IN`-Parameter werden mit ihrem Namen und dem Objekt, das ihren Wert enthält, definiert, und `OUT`-Parameter mit ihrem Namen und dem erwarteten Rückgabe-Datentyp. Alle Parameter müssen mit Richtung definiert werden.

Sind die Parameter angelegt, so kann die gespeicherte Prozedur mit der Methode `MySqlCommand.ExecuteNonQuery()` aufgerufen werden:

Visual Basic-Beispiel

    Dim conn As New MySqlConnection
    Dim cmd As New MySqlCommand

    conn.ConnectionString = "server=127.0.0.1;" _
        & "uid=root;" _
        & "pwd=12345;" _
        & "database=test"

    Try
        conn.Open()
        cmd.Connection = conn

        cmd.CommandText = "add_emp"
        cmd.CommandType = CommandType.StoredProcedure

        cmd.Parameters.Add("?lname", 'Jones')
        cmd.Parameters["?lname"].Direction = ParameterDirection.Input

        cmd.Parameters.Add("?fname", 'Tom')
        cmd.Parameters["?fname"].Direction = ParameterDirection.Input

        cmd.Parameters.Add("?bday", #12/13/1977 2:17:36 PM#)
        cmd.Parameters["?bday"].Direction = ParameterDirection.Input

        cmd.Parameters.Add("?empno", MySqlDbType.Int32)
        cmd.Parameters["?empno"].Direction = ParameterDirection.Output

        cmd.ExecuteNonQuery()

        MessageBox.Show(cmd.Parameters["?empno"].Value)
    Catch ex As MySqlException
        MessageBox.Show("Error " & ex.Number & " has occurred: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

C#-Beispiel

    MySql.Data.MySqlClient.MySqlConnection conn;
    MySql.Data.MySqlClient.MySqlCommand cmd;

    conn = new MySql.Data.MySqlClient.MySqlConnection();
    cmd = new MySql.Data.MySqlClient.MySqlCommand();

    conn.ConnectionString = "server=127.0.0.1;uid=root;" +
        "pwd=12345;database=test;";

    try
    {
        conn.Open();
        cmd.Connection = conn;

        cmd.CommandText = "add_emp";
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.Add("?lname", "Jones");
        cmd.Parameters["?lname"].Direction = ParameterDirection.Input;

        cmd.Parameters.Add("?fname", "Tom");
        cmd.Parameters["?fname"].Direction = ParameterDirection.Input;

        cmd.Parameters.Add("?bday", DateTime.Parse("12/13/1977 2:17:36 PM"));
        cmd.Parameters["?bday"].Direction = ParameterDirection.Input;

        cmd.Parameters.Add("?empno", MySqlDbType.Int32);
        cmd.Parameters["?empno"].Direction = ParameterDirection.Output;

        cmd.ExecuteNonQuery();

        MessageBox.Show(cmd.Parameters["?empno"].Value);
    }
    catch (MySql.Data.MySqlClient.MySqlException ex)
    {
        MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,
          "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

Sobald die gespeicherte Prozedur aufgerufen wird, können die Werte ihrer Ausgabeparameter mit der `.Value`-Eigenschaft der `MySqlConnector.Parameters`-Collection abgerufen werden.

#### 25.2.3.4. BLOB-Daten und Connector/NET

##### 25.2.3.4.1. Einleitung

Häufig werden mit MySQL Binärdaten in `BLOB`-Spalten gespeichert. MySQL unterstützt vier verschiedene BLOB-Datentypen: `TINYBLOB`, `BLOB`, `MEDIUMBLOB` und `LONGBLOB`.

Die Daten einer BLOB-Spalte können mit Connector/NET angesprochen und mit clientseitigem Code manipuliert werden. Es gibt keine Sonderbedingungen für den Einsatz von Connector/NET mit BLOB-Daten.

In diesem Abschnitt werden wir einfache Codebeispiele vorstellen. Eine vollständige Musteranwendung finden Sie im `Samples`-Verzeichnis der Connector/NET-Installation.

##### 25.2.3.4.2. Vorbereitung des MySQL Servers

Um MySQL für BLOB-Daten einsetzen zu können, müssen Sie als Erstes den Server konfigurieren. Zunächst werden wir eine Tabelle anlegen. Meine Dateitabellen haben normalerweise vier Spalten: Eine AUTO_INCREMENT-Spalte passender Größe (UNSIGNED SMALLINT) dient als Primärschlüssel, um die Datei zu identifizieren, eine VARCHAR-Spalte speichert den Dateinamen, eine UNSIGNED MEDIUMINT-Spalte hält die Größe der Datei fest und eine MEDIUMBLOB-Spalte enthält die Datei selbst. Für dieses Beispiel werde ich folgende Tabellendefinition einsetzen:

    CREATE TABLE file(
    file_id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    file_name VARCHAR(64) NOT NULL,
    file_size MEDIUMINT UNSIGNED NOT NULL,
    file MEDIUMBLOB NOT NULL);

Nach der Erstellung einer Tabelle muss eventuell die Systemvariable max_allowed_packet modifiziert werden, die festlegt, welche maximale Paketgröße (d. h. eine einzelne Zeile) an den MySQL Server geschickt werden kann. Nach Voreinstellung akzeptiert der Server nur 1 Mbyte als maximale Paketgröße von der Clientanwendung. Wenn Sie diesen Wert nicht überschreiten wollen, ist er in Ordnung, aber wenn doch, müssen Sie ihn heraufsetzen.

Die Option max_allowed_packet kann in den MySQL Administrator's Startup Variables eingestellt werden. Setzen Sie hierzu die Option Maximum allowed im Memory-Teil der Registerkarte Networking auf einen geeigneten Wert. Dann klicken Sie auf Apply Changes und starten den Server über den `Service Control`-Bildschirm des MySQL Administrators neu. Sie können diesen Wert allerdings auch direkt in der my.cnf-Datei einstellen (und die Zeile max_allowed_packet=xxM hinzufügen) oder die Syntax SET max_allowed_packet=xxM; in MySQL nutzen.

Bitte stellen Sie max_allowed_packet nicht zu hoch ein, da eine Übertragung von BLOB-Daten viel Zeit in Anspruch nehmen kann. Versuchen Sie, einen für Ihre Situation angemessenen Wert zu finden, und setzen Sie ihn notfalls später herauf.

##### 25.2.3.4.3. Eine Datei in die Datenbank speichern

Um eine Datei in eine Datenbank zu schreiben, konvertieren wir die Datei zuerst in ein Byte-Array und übergeben dieses dann als Parameter an die `INSERT`-Anfrage.

Der folgende Code öffnet eine Datei mithilfe eines FileStream-Objekts, liest sie in ein Byte-Array ein und fügt sie in die Tabelle `file` ein:

Visual Basic-Beispiel

    Dim conn As New MySqlConnection
    Dim cmd As New MySqlCommand

    Dim SQL As String

    Dim FileSize As UInt32
    Dim rawData() As Byte
    Dim fs As FileStream

    conn.ConnectionString = "server=127.0.0.1;" _
        & "uid=root;" _
        & "pwd=12345;" _
        & "database=test"

    Try
        fs = New FileStream("c:\image.png", FileMode.Open, FileAccess.Read)
        FileSize = fs.Length

        rawData = New Byte(FileSize) {}
        fs.Read(rawData, 0, FileSize)
        fs.Close()

        conn.Open()

        SQL = "INSERT INTO file VALUES(NULL, ?FileName, ?FileSize, ?File)"

        cmd.Connection = conn
        cmd.CommandText = SQL
        cmd.Parameters.Add("?FileName", strFileName)
        cmd.Parameters.Add("?FileSize", FileSize)
        cmd.Parameters.Add("?File", rawData)

        cmd.ExecuteNonQuery()

        MessageBox.Show("File Inserted into database successfully!", _
        "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

        conn.Close()
    Catch ex As Exception
        MessageBox.Show("There was an error: " & ex.Message, "Error", _
            MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

C#-Beispiel

    MySql.Data.MySqlClient.MySqlConnection conn;
    MySql.Data.MySqlClient.MySqlCommand cmd;

    conn = new MySql.Data.MySqlClient.MySqlConnection();
    cmd = new MySql.Data.MySqlClient.MySqlCommand();

    string SQL;
    UInt32 FileSize;
    byte[] rawData;
    FileStream fs;

    conn.ConnectionString = "server=127.0.0.1;uid=root;" +
        "pwd=12345;database=test;";

    try
    {
        fs = new FileStream(@"c:\image.png", FileMode.Open, FileAccess.Read);
        FileSize = fs.Length;

        rawData = new byte[FileSize];
        fs.Read(rawData, 0, FileSize);
        fs.Close();

        conn.Open();

        SQL = "INSERT INTO file VALUES(NULL, ?FileName, ?FileSize, ?File)";

        cmd.Connection = conn;
        cmd.CommandText = SQL;
        cmd.Parameters.Add("?FileName", strFileName);
        cmd.Parameters.Add("?FileSize", FileSize);
        cmd.Parameters.Add("?File", rawData);

        cmd.ExecuteNonQuery();

        MessageBox.Show("File Inserted into database successfully!",
            "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

        conn.Close();
    }
    catch (MySql.Data.MySqlClient.MySqlException ex)
    {
        MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,
            "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

Die Methode `Read` des `FileStream`-Objekts lädt die Datei in ein Byte-Array, über dessen Größe die `Length`-Eigenschaft des FileStream-Objekts entscheidet.

Nachdem das Byte-Array als Parameter des `MySqlCommand`-Objekts zugewiesen wurde, wird die `ExecuteNonQuery`-Methode aufgerufen und der BLOB in die `file`-Tabelle eingefügt.

##### 25.2.3.4.4. Einen BLOB aus der Datenbank in eine Datei oder auf Festplatte einlesen

Sobald wir eine Datei in der `file`-Tabelle gespeichert haben, können wir sie mit der Klasse `MySqlDataReader` abrufen.

Der folgende Code ruft eine Zeile aus der Tabelle `file` ab und lädt die Daten dann in ein `FileStream`-Objekt, das auf die Festplatte geschrieben wird:

Visual Basic-Beispiel

    Dim conn As New MySqlConnection
    Dim cmd As New MySqlCommand
    Dim myData As MySqlDataReader
    Dim SQL As String
    Dim rawData() As Byte
    Dim FileSize As UInt32
    Dim fs As FileStream

    conn.ConnectionString = "server=127.0.0.1;" _
        & "uid=root;" _
        & "pwd=12345;" _
        & "database=test"

    SQL = "SELECT file_name, file_size, file FROM file"

    Try
        conn.Open()

        cmd.Connection = conn
        cmd.CommandText = SQL

        myData = cmd.ExecuteReader

        If Not myData.HasRows Then Throw New Exception("There are no BLOBs to save")

        myData.Read()

        FileSize = myData.GetUInt32(myData.GetOrdinal("file_size"))
        rawData = New Byte(FileSize) {}

        myData.GetBytes(myData.GetOrdinal("file"), 0, rawData, 0, FileSize)

        fs = New FileStream("C:\newfile.png", FileMode.OpenOrCreate, FileAccess.Write)
        fs.Write(rawData, 0, FileSize)
        fs.Close()

        MessageBox.Show("File successfully written to disk!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

        myData.Close()
        conn.Close()
    Catch ex As Exception
        MessageBox.Show("There was an error: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

C#-Beispiel

    MySql.Data.MySqlClient.MySqlConnection conn;
    MySql.Data.MySqlClient.MySqlCommand cmd;
    MySql.Data.MySqlClient.MySqlDataReader myData;

    conn = new MySql.Data.MySqlClient.MySqlConnection();
    cmd = new MySql.Data.MySqlClient.MySqlCommand();

    string SQL;
    UInt32 FileSize;
    byte[] rawData;
    FileStream fs;

    conn.ConnectionString = "server=127.0.0.1;uid=root;" +
        "pwd=12345;database=test;";

    SQL = "SELECT file_name, file_size, file FROM file";

    try
    {
        conn.Open();

        cmd.Connection = conn;
        cmd.CommandText = SQL;

        myData = cmd.ExecuteReader();

        if (! myData.HasRows)
            throw new Exception("There are no BLOBs to save");

        myData.Read();

        FileSize = myData.GetUInt32(myData.GetOrdinal("file_size"));
        rawData = new byte[FileSize];

        myData.GetBytes(myData.GetOrdinal("file"), 0, rawData, 0, FileSize);

        fs = new FileStream(@"C:\newfile.png", FileMode.OpenOrCreate, FileAccess.Write);
        fs.Write(rawData, 0, FileSize);
        fs.Close();

        MessageBox.Show("File successfully written to disk!",
            "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

        myData.Close();
        conn.Close();
    }
    catch (MySql.Data.MySqlClient.MySqlException ex)
    {
        MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,
            "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

Nach dem Aufbau der Verbindung werden die Daten der `file`-Tabelle in ein `MySqlDataReader`-Objekt geladen. Die Methode `GetBytes` des MySqlDataReaders lädt den BLOB in ein Byte-Array, das dann mit einem FileStream-Objekt auf die Festplatte geschrieben wird.

Die Methode `GetOrdinal` des MySqlDataReaders kann den ganzzahligen Index einer benannten Spalte ermitteln. Wenn Sie GetOrdinal verwenden, vermeiden Sie Fehler, die bei einer Änderung der Spaltenreihenfolge in der `SELECT`-Anfrage entstehen könnten.

#### 25.2.3.5. Connector/NET mit Crystal Reports

##### 25.2.3.5.1. Einleitung

Crystal Reports ist ein Tool, das Windows-Anwendungsentwickler gerne für das Reporting und zur Dokumenterstellung einsetzen. In diesem Abschnitt erfahren Sie, wie man Crystal Reports XI mit MySQL und Connector/NET einsetzt.

##### 25.2.3.5.2. Datenquelle anlegen

Wenn Sie in Crystal Reports einen Bericht anlegen, können Sie in zwei Weisen auf MySQL-Daten für den Bericht zugreifen.

Die erste Möglichkeit: Sie verwenden Connector/ODBC als ADO-Datenquelle, wenn Sie Ihren Bericht entwerfen. Sie können dann in der Datenbank stöbern und Tabellen und Felder mit Drag & Drop in den Bericht einbinden. Der Nachteil dieser Methode: Es ist zusätzliche Arbeit an Ihrer Anwendung erforderlich, um ein zu Ihrem Bericht passendes Dataset zu erzeugen.

Die zweite Möglichkeit: Sie erstellen ein Dataset in VB.NET und speichern Sie im XML-Format. Diese XML-Datei kann dann zur Berichterstellung eingesetzt werden. Das funktioniert zwar recht gut, wenn Sie den Bericht in Ihrer Anwendung anzeigen, ist aber zur Entwurfszeit unpraktisch, da Sie alle relevanten Spalten auswählen müssen, wenn Sie das Dataset anlegen. Vergessen Sie eine Spalte, so müssen Sie das gesamte Dataset neu anlegen, um die Spalte dem Bericht hinzuzufügen.

Mit dem folgenden Code erzeugen Sie aus einer Anfrage ein Dataset und schreiben es auf die Festplatte:

Visual Basic-Beispiel

    Dim myData As New DataSet
    Dim conn As New MySqlConnection
    Dim cmd As New MySqlCommand
    Dim myAdapter As New MySqlDataAdapter

    conn.ConnectionString = "server=127.0.0.1;" _
        & "uid=root;" _
        & "pwd=12345;" _
        & "database=world"

    Try
        conn.Open()
        cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " _
            & "country.name, country.population, country.continent " _
            & "FROM country, city ORDER BY country.continent, country.name"
        cmd.Connection = conn

        myAdapter.SelectCommand = cmd
        myAdapter.Fill(myData)

        myData.WriteXml("C:\dataset.xml", XmlWriteMode.WriteSchema)
    Catch ex As Exception
        MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

C#-Beispiel

    DataSet myData = new DataSet();
    MySql.Data.MySqlClient.MySqlConnection conn;
    MySql.Data.MySqlClient.MySqlCommand cmd;
    MySql.Data.MySqlClient.MySqlDataAdapter myAdapter;

    conn = new MySql.Data.MySqlClient.MySqlConnection();
    cmd = new MySql.Data.MySqlClient.MySqlCommand();
    myAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter();

    conn.ConnectionString = "server=127.0.0.1;uid=root;" +
      "pwd=12345;database=test;";

    try
    {
      cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " +
      "country.name, country.population, country.continent " +
      "FROM country, city ORDER BY country.continent, country.name";
      cmd.Connection = conn;

      myAdapter.SelectCommand = cmd;
      myAdapter.Fill(myData);

      myData.WriteXml(@"C:\dataset.xml", XmlWriteMode.WriteSchema);
    }
    catch (MySql.Data.MySqlClient.MySqlException ex)
    {
      MessageBox.Show(ex.Message, "Report could not be created",
      MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

Die resultierende XML-Datei kann bei der Berichterstellung als ADO.NET XML-Datenquelle verwendet werden.

Wenn Sie Ihre Berichte mit Connector/ODBC erstellen möchten, können Sie diese Komponente von dev.mysql.com herunterladen.

##### 25.2.3.5.3. Bericht erstellen

Für die meisten Zwecke müsste der Standard Report-Assistent für die ersten Schritte der Berichterstellung ausreichen. Um den Assistenten zu starten, öffnen Sie Crystal Reports und wählen aus dem Dateimenü die Option `Neu > Standard Report`.

Der Assistent fragt Sie dann nach einer Datenquelle. Wenn Sie Connector/ODBC verwenden, wählen Sie die Option OLEDB provider for ODBC aus dem OLE DB (ADO)-Baum statt aus dem ODBC (RDO)-Baum, wenn Sie die Datenquelle einstellen. Wenn Sie ein gespeichertes Dataset verwenden, wählen Sie die Option ADO.NET (XML) und gehen zu diesem Dataset.

Der Rest des Berichterstellungsprozesses läuft im Assistenten automatisch ab.

Nachdem der Bericht angelegt wurde, wählen Sie den Eintrag Report Options... aus dem Dateimenü. Deaktivieren Sie die Option Save Data With Report, damit keine gespeicherten Daten das Laden der Daten in Ihrer Anwendung behindern.

##### 25.2.3.5.4. Bericht anzeigen

Um einen Bericht anzuzeigen, laden wir zuerst das Dataset hinein, in dem die benötigten Daten gespeichert sind, laden dann den Bericht und binden ihn an das Dataset. Zum Schluss übergeben wir den Bericht an den crViewer, damit er dem Benutzer angezeigt wird.

Folgendes müssen Sie in einem Projekt, das einen Bericht anzeigt, referenzieren:

- CrytalDecisions.CrystalReports.Engine

- CrystalDecisions.ReportSource

- CrystalDecisions.Shared

- CrystalDecisions.Windows.Forms

Der folgende Code geht davon aus, dass Sie Ihren Bericht mit einem Dataset angelegt haben, das wie in Abschnitt 25.2.3.5.2, „Datenquelle anlegen“, gezeigt gespeichert wurde, und dass Sie einen crViewer namens `myViewer` auf Ihrem Formular haben.

Visual Basic-Beispiel

    Imports CrystalDecisions.CrystalReports.Engine
    Imports System.Data
    Imports MySql.Data.MySqlClient

    Dim myReport As New ReportDocument
    Dim myData As New DataSet
    Dim conn As New MySqlConnection
    Dim cmd As New MySqlCommand
    Dim myAdapter As New MySqlDataAdapter

    conn.ConnectionString = _
        "server=127.0.0.1;" _
        & "uid=root;" _
        & "pwd=12345;" _
        & "database=test"

    Try
        conn.Open()

        cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " _
            & "country.name, country.population, country.continent " _
            & "FROM country, city ORDER BY country.continent, country.name"
        cmd.Connection = conn

        myAdapter.SelectCommand = cmd
        myAdapter.Fill(myData)

        myReport.Load(".\world_report.rpt")
        myReport.SetDataSource(myData)
        myViewer.ReportSource = myReport
    Catch ex As Exception
        MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

C#-Beispiel

    using CrystalDecisions.CrystalReports.Engine;
    using System.Data;
    using MySql.Data.MySqlClient;

    ReportDocument myReport = new ReportDocument();
    DataSet myData = new DataSet();
    MySql.Data.MySqlClient.MySqlConnection conn;
    MySql.Data.MySqlClient.MySqlCommand cmd;
    MySql.Data.MySqlClient.MySqlDataAdapter myAdapter;

    conn = new MySql.Data.MySqlClient.MySqlConnection();
    cmd = new MySql.Data.MySqlClient.MySqlCommand();
    myAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter();

    conn.ConnectionString = "server=127.0.0.1;uid=root;" +
        "pwd=12345;database=test;";

    try
    {
        cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " +
            "country.name, country.population, country.continent " +
            "FROM country, city ORDER BY country.continent, country.name";
        cmd.Connection = conn;

        myAdapter.SelectCommand = cmd;
        myAdapter.Fill(myData);

        myReport.Load(@".\world_report.rpt");
        myReport.SetDataSource(myData);
        myViewer.ReportSource = myReport;
    }
    catch (MySql.Data.MySqlClient.MySqlException ex)
    {
        MessageBox.Show(ex.Message, "Report could not be created",
            MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

Ein neues Dataset wird mit derselben Anfrage wie das zuvor gespeicherte angelegt. Sobald es mit Daten gefüllt ist, wird die Berichtsdatei mithilfe eines ReportDocuments geladen und an das Dataset gebunden. Das ReportDocument wird als ReportSource des crViewers übergeben.

Denselben Ansatz verfolgen wir, wenn ein Bericht mit Connector/ODBC aus einer einzelnen Tabelle erstellt wird. Das Dataset ersetzt die im Bericht verwendete Tabelle und der Bericht wird korrekt angezeigt.

Wird ein Bericht mit Connector/ODBC aus mehreren Tabellen erstellt, müssen wir in unserer Anwendung ein Dataset aus mehreren Tabellen anlegen. So kann jede Tabelle aus der Berichtsdatenquelle im Dataset durch einen Bericht ersetzt werden.

Um mehrere Tabellen in ein Dataset zu laden, sind mehrere `SELECT`-Anweisungen in unserem MySqlCommand-Objekt erforderlich. Diese `SELECT`-Anweisungen beruhen auf der SQL-Anfrage, die in Crystal Reports in der Option Show SQL Query des Datenbankmenüs angezeigt wird. Legen wir einmal folgende Anfrage zugrunde:

    SELECT `country`.`Name`, `country`.`Continent`, `country`.`Population`, `city`.`Name`, `city`.`Population`
    FROM `world`.`country` `country` LEFT OUTER JOIN `world`.`city` `city` ON `country`.`Code`=`city`.`CountryCode`
    ORDER BY `country`.`Continent`, `country`.`Name`, `city`.`Name`

Diese Anfrage wird in zwei `SELECT`-Anfragen aufgespalten und mit folgendem Code angezeigt:

Visual Basic-Beispiel

    Imports CrystalDecisions.CrystalReports.Engine
    Imports System.Data
    Imports MySql.Data.MySqlClient

    Dim myReport As New ReportDocument
    Dim myData As New DataSet
    Dim conn As New MySqlConnection
    Dim cmd As New MySqlCommand
    Dim myAdapter As New MySqlDataAdapter

    conn.ConnectionString = "server=127.0.0.1;" _
        & "uid=root;" _
        & "pwd=12345;" _
        & "database=world"

    Try
        conn.Open()
        cmd.CommandText = "SELECT name, population, countrycode FROM city ORDER BY countrycode, name; " _
            & "SELECT name, population, code, continent FROM country ORDER BY continent, name"
        cmd.Connection = conn

        myAdapter.SelectCommand = cmd
        myAdapter.Fill(myData)

        myReport.Load(".\world_report.rpt")
        myReport.Database.Tables(0).SetDataSource(myData.Tables(0))
        myReport.Database.Tables(1).SetDataSource(myData.Tables(1))
        myViewer.ReportSource = myReport
    Catch ex As Exception
        MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

C#-Beispiel

    using CrystalDecisions.CrystalReports.Engine;
    using System.Data;
    using MySql.Data.MySqlClient;

    ReportDocument myReport = new ReportDocument();
    DataSet myData = new DataSet();
    MySql.Data.MySqlClient.MySqlConnection conn;
    MySql.Data.MySqlClient.MySqlCommand cmd;
    MySql.Data.MySqlClient.MySqlDataAdapter myAdapter;

    conn = new MySql.Data.MySqlClient.MySqlConnection();
    cmd = new MySql.Data.MySqlClient.MySqlCommand();
    myAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter();

    conn.ConnectionString = "server=127.0.0.1;uid=root;" +
        "pwd=12345;database=test;";

    try
    {
        cmd.CommandText = "SELECT name, population, countrycode FROM city ORDER " +
            "BY countrycode, name; SELECT name, population, code, continent FROM " +
            "country ORDER BY continent, name";
        cmd.Connection = conn;

        myAdapter.SelectCommand = cmd;
        myAdapter.Fill(myData);

        myReport.Load(@".\world_report.rpt");
        myReport.Database.Tables(0).SetDataSource(myData.Tables(0));
        myReport.Database.Tables(1).SetDataSource(myData.Tables(1));
        myViewer.ReportSource = myReport;
    }
    catch (MySql.Data.MySqlClient.MySqlException ex)
    {
        MessageBox.Show(ex.Message, "Report could not be created",
            MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

Die `SELECT`-Anfragen müssen unbedingt in alphabetischer Reihenfolge stehen, da der Bericht erwartet, dass seine Quelltabellen diese Reihenfolge haben. Für jede Tabelle im Bericht ist eine SetDataSource-Anweisung erforderlich.

Dieser Ansatz kann Performanceprobleme mit sich bringen, da Crystal Reports die Tabellen auf der Clientseite aneinander binden muss. Das braucht mehr Zeit als ein vordefiniertes, gespeichertes Dataset.

#### 25.2.3.6. Datums- und Uhrzeitdaten in Connector/NET

##### 25.2.3.6.1. Einleitung

MySQL und die .NET-Sprachen gehen unterschiedlich mit Datums- und Uhrzeitinformationen um: MySQL erlaubt Datumswerte, die von keinem .NET-Datentyp dargestellt werden können, wie etwa '`0000-00-00 00:00:00`'. Diese Unterschiede können Probleme verursachen, wenn man nicht richtig damit umgeht.

In diesem Abschnitt werden wir zeigen, wie Datums- und Uhrzeitinformationen mit Connector/NET korrekt behandelt werden.

##### 25.2.3.6.2. Probleme bei Verwendung ungültiger Datumswerte

Die Unterschiede in der Datumsbehandlung können Probleme bereiten, wenn Entwickler ungültige Datumswerte verwenden. Ungültige MySQL-Datumswerte, einschließlich `NULL`-Datumswerten, lassen sich nicht in native `DateTime`-Objekte von .NET laden.

Daher können `DataSet`-Objekte von .NET nicht mit der `Fill`-Methode der Klasse `MySqlDataAdapter` gefüllt werden, da ungültige Datumswerte eine `System.ArgumentOutOfRangeException` verursachen würden.

##### 25.2.3.6.3. Ungültige Datumswerte unterbinden

Datumsprobleme lassen sich am besten dadurch in den Griff bekommen, dass die Benutzer gar keine Möglichkeit erhalten, ungültige Datumswerte einzugeben. Dies lässt sich auf der Client- oder der Serverseite bewerkstelligen.

Um ungültige Datumswerte auf der Clientseite zu unterbinden, müssen Sie die Datumswerte nur immer mit der .NET-Klasse `DateTime` behandeln. Diese erlaubt nämlich nur gültige Datumswerte und stellt dadurch sicher, dass auch in Ihre Datenbank nur gültige Werte gelangen. Leider kann man sie jedoch nicht in einer gemischten Umgebung einsetzen, in der die Datenbank sowohl mit .NET- als auch mit Nicht-.NET-Code bearbeitet wird, da jede Anwendung ihre eigene Datumsvalidierung vornehmen muss.

Auf MySQL 5.0.2 und höher können Sie den neuen SQL-Modus `traditional` einstellen, um ungültige Datumswerte zu unterbinden. Informationen über diesen SQL-Modus erhalten Sie unter `traditional`, Abschnitt 5.2.5, „Der SQL-Modus des Servers“.

##### 25.2.3.6.4. Umgang mit ungültigen Datumswerten

Zwar raten wir von ungültigen Datumswerten in .NET-Anwendungen ausdrücklich ab, aber es ist immerhin möglich, ungültige Datumswerte über den Datentyp `MySqlDateTime` zu behandeln.

Der Datentyp `MySqlDateTime` unterstützt dieselben Datumswerte wie der MySQL Server. Standardmäßig gibt Connector/NET für gültige Datumswerte ein DateTime-Objekt von .NET und für ungültige Datumswerte einen Fehler zurück. Diese Voreinstellung können Sie jedoch so abändern, dass Connector/NET `MySqlDateTime`-Objekte für ungültige Datumswerte zurückliefert.

Damit Connector/NET für ungültige Datumswerte ein `MySqlDateTime`-Objekt zurückgibt, fügen Sie Ihrem Verbindungs-String folgende Zeile hinzu:

      Allow Zero Datetime=True

Bitte beachten Sie, dass die Verwendung der Klasse `MySqlDateTime` immer problematisch sein kann. Folgende Probleme sind bereits aufgetreten:

1. Die Datenbindung an ungültige Datumswerte kann trotz allem Fehler verursachen (Null-Datumswerte wie 0000-00-00 scheinen jedoch keine Schwierigkeiten zu bereiten).

2. Die `ToString`-Methode gibt ein Datum im MySQL-Standardformat zurück (zum Beispiel `2005-02-23 08:50:25`). Dieses unterscheidet sich von dem `ToString`-Verhalten der .NET-Klasse DateTime.

3. Die Klasse `MySqlDateTime` unterstützt NULL-Datumswerte, die .NET-Klasse DateTime hingegen nicht. Das kann Fehler verursachen, wenn Sie versuchen, eine MySQLDateTime in ein DateTime-Objekt zu konvertieren, ohne sie zuvor auf NULL zu prüfen.

Wegen dieser bekannten Probleme lautet der beste Rat: Verwenden Sie bitte nur gültige Datumswerte Ihrer Anwendung.

##### 25.2.3.6.5. Umgang mit NULL-Datumswerten

Der .NET-Datentyp `DateTime` kann mit `NULL`-Werten nicht umgehen. Daher müssen Sie, wenn Sie Werte aus einer Anfrage an eine `DateTime`-Variable zuweisen, immer zuerst prüfen, ob nicht ein `NULL`-Wert vorliegt.

Wenn Sie einen `MySqlDataReader` verwenden, sollten Sie mit der Methode `.IsDBNull` überprüfen, ob ein `NULL`-Wert vorliegt, bevor Sie die Zuweisung vornehmen:

Visual Basic-Beispiel

    If Not myReader.IsDBNull(myReader.GetOrdinal("mytime")) Then
        myTime = myReader.GetDateTime(myReader.GetOrdinal("mytime"))
    Else
        myTime = DateTime.MinValue
    End If

C#-Beispiel

    if (! myReader.IsDBNull(myReader.GetOrdinal("mytime")))
        myTime = myReader.GetDateTime(myReader.GetOrdinal("mytime"));
    else
        myTime = DateTime.MinValue;

`NULL`-Werte funktionieren nicht in einem Dataset und können ohne Sonderbehandlung an Formularelemente gebunden werden.

### 25.2.4. Support für Connector/NET

Den Entwicklern von Connector/NET ist die Meinung der Benutzer und ihr Beitrag zum Softwareentwicklungsprozess sehr wichtig. Wenn Sie bei Connector/NET ein Feature vermissen oder einen Fehler finden und einen Bugreport übermitteln müssen, richten Sie sich bitte nach den Hinweisen in Abschnitt 1.8, „Wie man Bugs oder Probleme meldet“.

#### 25.2.4.1. Support von der Connector/NET-Community

- Community-Support zu Connector/NET finden Sie in den Foren unter http://forums.mysql.com.

- Außerdem erhalten Sie in den Mailinglisten unter http://lists.mysql.com Community-Support für Connector/NET.

- MySQL AB bietet auch einen zahlungspflichtigen Support. Informationen darüber finden Sie in http://www.mysql.com/support/.

#### 25.2.4.2. Probleme und Fehler von Connector/NET melden

Wenn Sie Probleme mit Connector/NET haben, wenden Sie sich bitte zuerst an die Connector/NET-Community, siehe Abschnitt 25.2.4.1, „Support von der Connector/NET-Community“.

Zuerst versuchen Sie jedoch, SQL-Anweisungen und -Befehle vom mysql-Client oder `admndemo` abzusetzen. So können Sie erkennen, ob das Problem an Connector/NET oder MySQL liegt.

Wenn Sie ein Problem melden, geben Sie uns bitte per E-Mail folgende Informationen:

- Betriebssystem und Version

- Connector/NET-Version

- MySQL Server-Version

- Kopien von Fehlermeldungen oder anderen unerwarteten Ausgaben

- Einfaches, reproduzierbares Beispiel

Achtung: Je mehr Informationen Sie uns geben können, umso wahrscheinlicher ist es, dass wir das Problem beheben können.

Wenn Sie der Auffassung sind, dass es sich um einen Bug handelt, senden Sie uns einen Bugreport über http://bugs.mysql.com/.

## 25.3. MySQL Connector/J

MySQL stellt für Clientprogramme, die in Java erstellt wurden, Verbindungsmöglichkeiten über einen JDBC-Treiber namens MySQL Connector/J zur Verfügung.

MySQL Connector/J ist ein JDBC-3.0-Treiber vom „Typ 4“, also reines Java. Er implementiert die Version 3.0 der JDBC-Spezifikation und kommuniziert mit dem MySQL-Server direkt über das MySQL-Protokoll.

JDBC ist zwar sehr hilfreich, doch wenn Sie nach der Lektüre der ersten Abschnitte dieses Kapitels noch nicht voll und ganz damit vertraut sind, sollten Sie mit JDBC alleine nur sehr einfache Probleme bearbeiten. Den Löwenanteil der wiederkehrenden Aufgaben sollten Sie mit einem der populären Persistence-Frameworks wie etwa Hibernate, Spring's JDBC Templates oder Ibatis SQL Maps erledigen und die Grundrenovierungen, die manchmal erforderlich sind, mit JDBC.

Dieser Abschnitt ist nicht als umfassendes JDBC-Tutorial konzipiert. Wenn Sie mehr über JDBC erfahren möchten, schauen Sie bitte in eines der folgenden Online-Tutorials, die mehr in die Tiefe gehen als die vorliegenden Ausführungen:

- JDBC Basics — Ein JDBC-Tutorial von Sun für Anfänger

- JDBC Short Course — Ein detaillierteres Tutorial von Sun und JGuru

### 25.3.1. Connector/J-Versionen

Zurzeit stehen drei Versionen von MySQL Connector/J zur Verfügung:

- Connector/J 3.0 stellt die Kernfunktionalität zur Verfügung und wurde für die Verbindung mit MySQL 3.x oder MySQL 4.1 geschaffen, obwohl es auch mit neueren Versionen von MySQL grundsätzlich kompatibel ist. Connector/J 3.0 unterstützt keine vorbereiteten Anweisungen auf der Serverseite und keine neuen Features der MySQL-Versionen nach 4.1.

- Connector/J 3.1 dient der Verbindung mit MySQL 4.1- und MySQL 5.0-Servern und unterstützt alle Funktionen von MySQL 5.0 außer verteilten Transaktionen (XA).

- Connector/J 5.0 unterstützt dieselben Funktionen wie Connector/J 3.1, aber zusätzlich auch verteilte Transaktionen (XA).

Die zurzeit empfohlene Version von Connector/J ist 5.0. Die vorliegende Anleitung bezieht sich auf alle drei Connector-Versionen und weist besonders darauf hin, wenn eine Einstellung nur für eine bestimmte Option gilt.

#### 25.3.1.1. Unterstützte Java-Versionen

MySQL Connector/J unterstützt Java-2-JVMs, einschließlich:

- JDK 1.2.x

- JDK 1.3.x

- JDK 1.4.x

- JDK 1.5.x

Wenn Sie Connector/J mit der Quelldistribution aus den Quelldateien erstellen (siehe Abschnitt 25.3.2.4, „Installation vom Entwicklungsquellbaum“), dann müssen Sie JDK 1.4.x oder höher zum Kompilieren des Connectors einsetzen.

MySQL Connector/J funktioniert nicht mit JDK-1.1.x oder JDK-1.0.x

Wegen der Implementierung von `java.sql.Savepoint` funktioniert Connector/J 3.1.0 und höher nicht mit JDKs, die älter als 1.4 sind, es sei denn, Sie schalten die Klassenprüfung aus (`-Xverify:none`). Diese würde nämlich versuchen, die Klassendefinition für `java.sql.Savepoint` zu laden, obwohl der Treiber auf diese Klasse nur zugreift, wenn Savepoint-Funktionalität genutzt wird.

Auch die Caching-Funktionalität von Connector/J 3.1.0 oder höher steht für JVMs, die älter als 1.4.x sind, nicht zur Verfügung, da sie sich auf die Klasse `java.util.LinkedHashMap` stützt, die erstmals im JDK-1.4.0 eingeführt wurde.

### 25.3.2. Installation von Connector/J

Sie können Connector/J entweder aus der Binär- oder aus der Quelldistribution installieren. Die Binärdistribution ist die einfachste Methode, während die Quelldistribution mehr Anpassungen ermöglicht.

#### 25.3.2.1. Connector/J aus einer Binärdistribution installieren

Am einfachsten installieren Sie Connector/J mit der Binärdistribution. Diese steht als Tar/Gzip- oder Zip-Datei zur Verfügung. Extrahieren Sie das Archiv in ein passendes Verzeichnis und stellen Sie optional Informationen über das verwendete Package zur Verfügung, indem Sie Ihren `CLASSPATH` ändern (siehe Abschnitt 25.3.2.2, „Treiber installieren und `CLASSPATH` konfigurieren“).

MySQL Connector/J wird als .zip- oder .tar.gz-Archiv vertrieben, das die Quell- und Klassendateien sowie das JAR-Archiv namens `mysql-connector-java-`[version]`-bin.jar` enthält. Seit Connector/J 3.1.8 ist auch ein Debug-Build des Treibers in einer Datei namens `mysql-connector-java-`[version]`-bin-g.jar` inbegriffen.

Ab der Version Connector/J 3.1.9 sind die `.class`-Dateien, die die JAR-Dateien bilden, nur als Teil der Treiber-JAR-Datei enthalten.

Den „Debug“-Build des Treibers sollten Sie bitte nur benutzen, wenn Sie dazu aufgefordert werden, um ein Problem oder einen Fehler an MySQL AB zu melden, da dieser Build nicht für Produktionsumgebungen geschaffen ist und sich nachteilig auf die Performance auswirkt. Die Debug-Binärdatei ist außerdem von der Aspect/J-Laufzeitbibliothek abhängig, die Sie in der zur Connector/J-Distribution gehörigen Datei `src/lib/aspectjrt.jar` finden.

Um die Distribution auspacken zu können, benötigen Sie ein geeignetes Hilfsprogramm (zum Beispiel WinZip für das .zip-Archiv und tar für das .tar.gz-Archiv). Da die Distribution lange Dateinamen enthalten kann, verwenden wir das GNU-Format für tar-Archive. Mit GNU tar (oder einer Anwendung, die das GNU-tar-Archivformat versteht) können Sie die .tar.gz-Variante der Distribution auspacken.

#### 25.3.2.2. Treiber installieren und `CLASSPATH` konfigurieren

WennSie das Archiv der Distribution extrahiert haben, installieren Sie den Treiber, indem Sie Ihrem Klassenpfad `mysql-connector-java-[version]-bin.jar` hinzufügen. Hierzu schreiben Sie entweder den vollständigen Pfad in Ihre Umgebungsvariable `CLASSPATH` oder geben ihn direkt mit der Kommandozeilenoption -cp an, wenn Sie Ihre JVM starten.

Wenn Sie den Treiber mit dem JDBC DriverManager benutzen, verwenden Sie `com.mysql.jdbc.Driver` als die Klasse, die `java.sql.Driver` implementiert.

Die Umgebungsvariable `CLASSPATH` können Sie unter UNIX, Linux oder Mac OS X entweder lokal für einen Benutzer in seinem `.profile` oder in `.login` oder in einer anderen Login-Datei setzen. Sie kann aber auch global in der Datei `/etc/profile` eingestellt werden.

In einer C-Shell (csh, tcsh) würde der Connector/J-Treiber dem `CLASSPATH` folgendermaßen hinzugefügt:

    shell> setenv CLASSPATH /path/to/mysql-connector-java-[version]-bin.jar:$CLASSPATH

In einer Bourne-kompatiblen Shell (sh, ksh, bash) würden Sie dieses tun:

    export set CLASSPATH=/path/to/mysql-connector-java-[version]-bin.jar:$CLASSPATH

In Windows 2000, Windows XP und Windows Server 2003 muss die Umgebungsvariable in der Systemsteuerung eingestellt werden.

Wenn Sie MySQL Connector/J mit einem Anwendungsserver wie etwa Tomcat oder JBoss benutzen möchten, müssen Sie in der Herstellerdokumentation nachlesen, wie Klassenbibliotheken von Drittanbietern konfiguriert werden, da die meisten Anwendungsserver die Umgebungsvariable `CLASSPATH` ignorieren. Beispiele für die Konfiguration einiger J2EE-Anwendungsserver finden Sie in Abschnitt 25.3.5.2, „Connector/J mit J2EE und anderen Java-Frameworks einsetzen“. Die maßgebliche Quelle für die Konfiguration eines JDBC-Verbindungspools auf Ihrem konkreten Anwendungsserver ist jedoch dessen Dokumentation.

Wenn Sie Servlets oder JSPs entwickeln und Ihr Anwendungsserver J2EE-fähig ist, können Sie die .jar-Datei des Treibers in das Unterverzeichnis WEB-INF/lib Ihrer Webanwendungen legen, da dies der Standardspeicherort für Bibliotheken von Drittanbietern in J2EE-Webanwendungen ist.

Sie können auch die Klasse MysqlDataSource oder MysqlConnectionPoolDataSource im Package `com.mysql.jdbc.jdbc2.optional` verwenden, wenn Ihr J2EE-Anwendungsserver sie unterstützt oder benötigt. Ab Connector/J 5.0.0 ist über die Klasse `com.mysql.jdbc.jdbc2.optional.MysqlXADataSource` auch die Schnittstelle `javax.sql.XADataSource` implementiert, die in Verbindung mit dem MySQL-Server 5.0 verteilte XA-Transaktionen unterstützt.

Die diversen MysqlDataSource-Klassen unterstützen (über Standard-Set-Mutators) folgende Parameter:

- user

- password

- serverName (siehe vorhergehenden Abschnitt über Ausfall-Hosts)

- databaseName

- port

#### 25.3.2.3. Ältere Versionen aufrüsten

MySQL AB versucht, den Upgrade-Prozess so einfach wie möglich zu halten, doch wie bei jeder Software müssen gelegentlich in neuen Versionen neue Features unterstützt, vorhandene verbessert oder neue Standards erfüllt werden.

In diesem Abschnitt erfahren Benutzer, die von einer Connector/J-Version auf eine andere aufrüsten (oder, im Hinblick auf die JDBC-Funktionalität, auf eine neue Version des MySQL-Servers), worauf sie achten müssen.

##### 25.3.2.3.1. Aufrüsten von MySQL Connector/J 3.0 auf 3.1

Connector/J 3.1 ist auf größtmögliche Abwärtskompatibilität mit Connector/J 3.0 ausgelegt. Größere Änderungen beschränken sich auf die neuen Funktionen von MySQL 4.1 und höher, darunter Unicode-Zeichensätze, vorbereitete Anweisungen auf der Serverseite, SQLState-Codes die in Fehlermeldungen vom Server zurückgegeben werden, und verschiedene Leistungsverbesserungen, die mit Konfigurationseigenschaften ein- und ausgeschaltet werden können.

- Unicode-Zeichensätze — Informationen über dieses neue MySQL-Feature finden Sie im folgenden Abschnitt und in Kapitel 10, Zeichensatz-Unterstützung. Wenn Sie etwas falsch konfiguriert haben, merken Sie das in der Regel an einer Fehlermeldung wie `Illegal mix of collations`.

- Vorbereitete Anweisungen auf der Serverseite — Connector/J 3.1 erkennt und nutzt vorbereitete Anweisungen auf der Serverseite automatisch, wenn sie verfügbar sind (MySQL -Server der Version 4.1.0 und höher).

  Seit Version 3.1.7 untersucht der Server alle Arten mit `Connection.prepareStatement()` vorbereiteter SQL-Anweisungen, um festzustellen, ob es sich um eine Anweisungsart handelte deren Vorbereitung auf der Serverseite unterstützt wird. Ist dies nicht der Fall, emuliert der Server sie als clientseitige vorbereitete Anweisung. Dieses Feature können Sie deaktivieren, indem Sie emulateUnsupportedPstmts=false in Ihren JDBC-URL einbinden.

  Wenn Ihre Anwendung Probleme mit vorbereiteten Anweisungen auf der Serverseite hat, können Sie auf den älteren Code für emulierte vorbereitete Anweisungen auf der Clientseite zurückgreifen, der immer noch für ältere MySQL-Server als 4.1.0 mit der Verbindungseigenschaft useServerPrepStmts=false unterstützt wird.

- Datums- und Uhrzeitwerte, die nur aus Nullen bestehen (`0000-00-00 ...`) — Diese Werte lassen sich in Java nicht zuverlässig darstellen. Connector/J 3.0.x wandelte sie immer in NULL um, wenn sie aus einem ResultSet gelesen wurden.

  Connector/J 3.1 löst nach Voreinstellung eine Ausnahme aus, wenn diese Werte auftreten, da dies nach den Standards von JDBC und SQL das korrekte Verhalten ist. Sie können dieses Verhalten aber mit der Konfigurationseigenschaft zeroDateTimeBehavior ändern, die folgende Werte annehmen kann:

  - `exception` (der Standardwert) löst eine SQLException mit dem SQLState `S1009` aus.

  - `convertToNull` gibt `NULL` anstelle des Datums zurück.

  - `round` rundet das Datum auf den nächstgelegenen Wert auf, also auf `0001-01-01`.

  Ab Connector/J 3.1.7 lässt sich `ResultSet.getString()` mit der Eigenschaft noDatetimeStringSync=true von diesem Verhalten abkoppeln (der Standardwert ist `false`). Auf diese Weise können Sie den Wert mit den Nullen unverändert als String abrufen. Da dies allerdings jegliche Zeitzonenkonvertierungen ausschließt, erlaubt Ihnen der Treiber nicht, noDatetimeStringSync und useTimezone gleichzeitig einzuschalten.

- Neue SQLState-Codes — Connector/J 3.1 benutzt die SQLState-Codes von SQL:1999, die vom MySQL-Server (sofern er dies unterstützt) zurückgegeben werden. Diese unterscheiden sich von den alten X/Open-Zustandscodes, die Connector/J 3.0 verwendet. Wenn der Treiber mit einem älteren MySQL-Server als MySQL 4.1.0 verbunden ist (die älteste Version, die SQLStates in Fehlercodes zurückliefert), verwendet er eine integrierte Zuordnung. Sie können auf die alte Zuordnung umschalten, indem Sie die Konfigurationseigenschaft useSqlStateCodes=false einstellen.

- `ResultSet.getString()` — Wenn Sie `ResultSet.getString()` auf einer BLOB-Spalte aufrufen, wird nunmehr die Adresse ihres byte[]-Arrays anstelle einer Stringdarstellung des BLOBs zurückgegeben. Da BLOBs keinen Zeichensatz haben, können sie nicht ohne Datenverlust oder Schäden in java.lang.Strings konvertiert werden.

  Um in MySQL Strings mit LOB-Verhalten zu speichern, verwenden Sie einen der TEXT-Typen, die der Treiber alle als java.sql.Clob behandelt.

- Debug-Builds — Seit Connector/J 3.1.8 wird ein Debug-Build des Treibers in einer Datei namens `mysql-connector-java-`[version]`-bin-g.jar` zusammen mit der normalen Binär-jar-Datei namens `mysql-connector-java-`[version]`-bin.jar` mitgeliefert.

  Seit Connector/J 3.1.9 liefern wir die .class-Dateien nur noch im Bundle aus, also nur in den JAR-Archiven zusammen mit dem Treiber.

  Den „Debug“-Build des Treibers sollten Sie bitte nur benutzen, wenn Sie dazu aufgefordert werden, um ein Problem oder einen Fehler an MySQL AB zu melden, da dieser Build nicht für Produktionsumgebungen geschaffen ist und sich nachteilig auf die Performance auswirkt. Die Debug-Binärdatei ist außerdem von der Aspect/J-Laufzeitbibliothek abhängig, die Sie in der zur Connector/J-Distribution gehörigen Datei `src/lib/aspectjrt.jar` finden.

##### 25.3.2.3.2. JDBC-spezifische Probleme beim Upgrade auf MySQL Server 4.1 oder höher

- Verwendung der UTF-8-Zeichencodes - Vor MySQL Server 4.1 wurde die UTF-8-Zeichencodierung vom Server nicht unterstützt. Der JDBC-Treiber dagegen konnte diese Codierung nutzen, sodass mehrere Zeichensätze in latin1-Tabellen auf dem Server gespeichert werden konnten.

  Seit MySQL-4.1 ist diese Funktionalität veraltet. Wenn Sie Anwendungen haben, die sich darauf stützen und sich nicht auf die Unterstützung der offiziellen Unicode-Zeichen in MySQL Server 4.1 oder höher aktualisieren lassen, müssen Sie folgende Eigenschaft in Ihren Verbindungs-URL aufnehmen:

  `useOldUTF8Behavior=true`

- Vorbereitete Anweisungen auf der Serverseite - Connector/J 3.1 erkennt und nutzt vorbereitete Anweisungen auf der Serverseite automatisch, wenn sie verfügbar sind (MySQL -Server der Version 4.1.0 und höher). Wenn Ihre Anwendung Probleme mit vorbereiteten Anweisungen auf der Serverseite hat, können Sie auf den älteren Code für emulierte vorbereitete Anweisungen auf der Clientseite zurückgreifen, der immer noch für ältere MySQL-Server als 4.1.0 mit folgender Verbindungseigenschaft unterstützt wird:

  `useServerPrepStmts=false`

#### 25.3.2.4. Installation vom Entwicklungsquellbaum

Caution. Sie sollten diesen Abschnitt nur lesen, wenn Sie Interesse daran haben, uns beim Testen unseres neuen Codes behilflich zu sein. Wenn Sie MySQL Connector/J lediglich in funktionsfähiger Form auf Ihrem System einrichten wollen, sollten Sie einen Standard-Release verwenden.

Um MySQL Connector/J vom Entwicklungsquellbaum zu installieren, müssen folgende Voraussetzungen erfüllt sein:

- Sie benötigen Subversion (erhältlich bei http://subversion.tigris.org/), um die Quelldateien aus unserem Repository auszuchecken .

- Sie benötigen Apache Ant Version 1.6 oder höher (erhältlich bei http://ant.apache.org/).

- Sie benötigen JDK-1.4.2 oder höher. Zwar kann MySQL Connector/J auch auf älteren JDKs installiert werden, aber um es von der Quelle zu kompilieren, ist mindestens JDK-1.4.2 erforderlich.

Das Subversion-Quellcode-Repository für MySQL Connector/J liegt unter http://svn.mysql.com/svnpublic/connector-j. Generell sollten Sie nicht gleich das ganze Repository auschecken, da es jeden Branch und Tag für MySQL Connector/J enthält und daher sehr groß ist.

Einen konkreten Branch von MySQL Connector/J checken Sie folgendermaßen aus:

1. Zurzeit sind drei Branches von Connector/J aktiv: `branch_3_0`, `branch_3_1` und `branch_5_0`. Checken Sie den neuesten Code aus dem gewünschten Branch mit folgendem Befehl aus (wobei `[major]` und `[minor]` durch die passenden Versionsnummern ersetzt werden müssen):

       shell> svn co »
       http://svn.mysql.com/svnpublic/connector-j/branches/branch_[major]_[minor]/connector-j

   Dies erzeugt im aktuellen Verzeichnis ein Unterverzeichnis namens `connector-j`, das die neuesten Quelldateien für den gewünschten Branch enthält.

2. Wechseln Sie nun in das Verzeichnis `connector-j`, um es zu Ihrem aktuellen Arbeitsverzeichnis zu machen:

       shell> cd connector-j

3. Mit folgendem Befehl können Sie den Treiber kompilieren und eine `.jar`-Datei für die Installation anlegen:

       shell> ant dist

   Dies erzeugt im aktuellen Verzeichnis ein `build`-Verzeichnis, in das die gesamte Ausgabe des Builds gespeichert wird. Unter dem `build`-Verzeichnis wird ein weiteres Verzeichnis angelegt, das die Versionsnummer der für den Build verwendeten Quelle enthält. Dieses Verzeichnis enthält die Quelldateien, die kompilierten `.class`-Dateien und eine `.jar`-Datei, die sich für die Installation eignet. Für andere mögliche Ziele, einschließlich einer kompletten Package-Distribution, geben Sie folgenden Befehl:

       shell> ant --projecthelp

4. Nun wird eine neu erzeugte `.jar`-Datei, die den JDBC-Treiber enthält, in das Verzeichnis `build/mysql-connector-java-`[version]`` gelegt.

   Diesen neu erstellten JDBC-Treiber installieren Sie genau so, als sei es eine `.jar`-Datei, die Sie gemäß den Anleitungen in Abschnitt 25.3.2.2, „Treiber installieren und `CLASSPATH` konfigurieren“ von MySQL heruntergeladen haben.

### 25.3.3. Connector/J-Beispiele

Im ganzen Dokument finden sich immer wieder Beispiele für Connector/J, die nachfolgend verlinkt und zusammengefasst werden.

- Beispiel 25.1, „Eine Verbindung vom `DriverManager` erhalten“

- Beispiel 25.2, „Mit java.sql.Statement eine `SELECT`-Anfrage ausführen“

- Beispiel 25.3, „Gespeicherte Prozeduren“

- Beispiel 25.4, „Using `Connection.prepareCall()`“

- Beispiel 25.5, „Registrierung von Ausgabeparametern“

- Beispiel 25.6, „Einstellung von `CallableStatement`-Eingabeparametern“

- Beispiel 25.7, „Abruf von Ergebnissen und Ausgabeparameterwerten“

- Beispiel 25.8, „`AUTO_INCREMENT`-Spaltenwerte mit `Statement.getGeneratedKeys()` abrufen“

- Beispiel 25.9, „Abruf von `AUTO_INCREMENT`-Spaltenwerten mit `SELECT LAST_INSERT_ID()`“

- Beispiel 25.10, „Retrieving `AUTO_INCREMENT` column values in `Updatable ResultSets`“

- Beispiel 25.11, „Verwendung eines Verbindungspools mit einem J2EE-Anwendungsserver“

- Beispiel 25.12, „Beispiel einer Transaktion mit Retry-Logik“

### 25.3.4. Connector/J (JDBC)-Referenz

Dieser Abschnitt des Handbuchs enthält Referenzmaterial zu MySQL Connector/J, das zum Teil während des Build-Prozesses von Connector/J automatisch generiert wurde.

#### 25.3.4.1. Driver/Datasource-Klassennamen, URL-Syntax und Konfigurationseigenschaften für Connector/J

Die Klasse, die java.sql.Driver in MySQL Connector/J implementiert, heißt `com.mysql.jdbc.Driver`. Der Klassenname `org.gjt.mm.mysql.Driver` eignet sich auch, um die Abwärtskompatibilität mit MM.MySQL zu bewahren. Verwenden Sie also diesen Klassennamen, wenn Sie den Treiber registrieren oder andere Software konfigurieren, die MySQL Connector/J benutzen soll.

Es folgt das JDBC-URL-Format für MySQL Connector/J, wobei die Elemente in den eckigen Klammern ([, ]) optional sind:

    jdbc:mysql://[host][,failoverhost...][:port]/[database] »
    [?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...

Ist kein Hostname angegeben, wird der Standardwert 127.0.0.1 verwendet. Fehlt die Port-Angabe, wird 3306, die Standard-Portnummer für MySQL-Server eingesetzt.

    jdbc:mysql://[host:port],[host:port].../[database] »
    [?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...

Wenn die Datenbank nicht angegeben ist, wird keine Verbindung mit einer Standarddatenbank aufgenommen. Sie müssen dann entweder die Methode `setCatalog()` auf dem Connection-Objekt aufrufen, oder in der SQL-Anweisung Tabellennamen mit dem Datenbanknamen vollständig qualifizieren (d.h. `SELECT dbname.tablename.colname FROM dbname.tablename...`). Bei der Verbindung keine Datenbank anzugeben ist jedoch normalerweise nur dann sinnvoll, wenn Sie Tools erstellen, die mit mehreren Datenbanken arbeiten sollen, wie beispielsweise GUI-Datenbankmanager.

MySQL Connector/J unterstützt Ausfallsicherungen. So kann der Treiber auf beliebig viele Slave-Hosts zurückgreifen und immer noch nur-lesende Anfragen ausführen. Die Ausfallsicherung tritt nur dann in Kraft, wenn für die Verbindung `autoCommit(true)` gilt, da bei laufenden Transaktionen kein zuverlässiges Umschalten möglich ist. Die meisten Anwendungsserver und Verbindungspools setzen `autoCommit` am Ende jeder Transaktion/Verbindungsnutzung auf `true`.

Die Ausfallsicherung verhält sich folgendermaßen:

- Wenn die URL-Eigenschaft autoReconnect false ist, wird nur bei der Initialisierung einer Verbindung auf den Sekundär-Host umgeschaltet (sog. Failover), und auf den Primär-Host wird wieder zurückgeschaltet (sog. Failback), wenn der Treiber feststellt, dass dieser wieder zur Verfügung steht.

- Wenn die URL-Eigenschaft autoReconnect true ist, wird auf den Sekundär-Host umgeschaltet, wenn der Treiber feststellt, das die Verbindung (vor der Ausführung jeglicher Anfrage) gescheitert ist, und wieder auf den Primär-Host zurückgeschaltet, wenn dieser wieder verfügbar ist (nach der Ausführung von `queriesBeforeRetryMaster`-Anfragen).

In beiden Fällen gilt: Wenn Sie mit einem "Sekundär"-Server verbunden sind, wird die Verbindung in einen nur-lesenden Zustand versetzt, sodass Anfragen, die Daten modifizieren würden, Ausnahmen auslösen (eine solche Anfrage wird niemals vom MySQL-Server verarbeitet).

Wie Connector/J eine Verbindung zu einem MySQL-Server einrichtet, ist in den Konfigurationseigenschaften definiert. Wenn nichts anderes gesagt wird, können die Eigenschaften für ein DataSource- oder für ein Connection-Objekt gesetzt werden.

Konfigurationseigenschaften können auf folgende Weisen eingestellt werden:

- Mit den set*()-Methoden von MySQL-Implementierungen auf java.sql.DataSource (die bevorzugte Methode, wenn Implementierungen von java.sql.DataSource verwendet werden):

  - com.mysql.jdbc.jdbc2.optional.MysqlDataSource

  - com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource

- Als Schlüssel/Wert-Paar in der java.util.Properties-Instanz, die an `DriverManager.getConnection()` oder `Driver.connect()` übergeben wird.

- Als JDBC-URL-Parameter in dem an `java.sql.DriverManager.getConnection()`, `java.sql.Driver.connect()` oder MySQL-Implementierungen der `setURL()`-Methode von `javax.sql.DataSource` übergebenen URL.

  Hinweis. Wenn Sie zur Konfiguration eines JDBC-URLs einen XML-Mechanismus verwenden, müssen sie den XML-Zeichenliteral &amp; auf andere Konfigurationsparameter einstellen, da das Ampersand in XML ein reserviertes Zeichen ist.

Die Eigenschaften werden in den folgenden Tabellen aufgeführt.

Verbindung/Authentifizierung.

Name der Eigenschaft | Definition | Standardwert | Seit Version
user | Der Benutzername für die Verbindung |  | alle
password | Das Passwort für die Verbindung |  | alle
socketFactory | Der Name der Klasse, die der Treiber zur Einrichtung von Socket-Verbindungen zum Server benutzen soll. Diese Klasse muss die Schnittstelle `com.mysql.jdbc.SocketFactory` implementieren und einen öffentlichen, parameterlosen Konstruktor haben. | com.mysql.jdbc.StandardSocketFactory | 3.0.3
connectTimeout | Timeout für Socket-Verbindung (in Millisekunden). 0 bedeutet: kein Timeout. Funktioniert nur mit JDK-1.4 oder höher. Standardwert ist 0. | 0 | 3.0.1
socketTimeout | Timeout für Socket-Operationen im Netzwerk. (Die Standardeinstellung 0 bedeutet: kein Timeout). | 0 | 3.0.1
useConfigs | Lade die kommagetrennte Liste der Konfigurationseigenschaften vor dem Parsen des URLs oder der Anwendung benutzerdefinierter Eigenschaften. Siehe Abschnitt 25.3.4.1, „Driver/Datasource-Klassennamen, URL-Syntax und Konfigurationseigenschaften für Connector/J“ |  | 3.1.5
interactiveClient | Setzt das Flag CLIENT_INTERACTIVE, damit MySQL das Verbindungs-Timeout gemäß INTERACTIVE_TIMEOUT anstelle von WAIT_TIMEOUT einstellt | false | 3.1.0
propertiesTransform | Eine Implementierung von `com.mysql.jdbc.ConnectionPropertiesTransform`, die der Treiber benutzt, um an ihn übergebene URL-Eigenschaften zu modifizieren, ehe er versucht, eine Verbindung einzurichten |  | 3.1.4
useCompression | Verwendung von zlib-Kompression zur Kommunikation mit dem Server (true/false)? Standardwert ist `false`. | false | 3.0.17

Hochverfügbarkeit und Clustering.

Name der Eigenschaft | Definition | Standardwert | Seit Version

autoReconnect

Sollte der Treiber alte und/oder tote Verbindungen wiederbeleben oder nicht? Wenn diese Eigenschaft aktiviert ist, löst der Treiber eine Ausnahme aus, wenn Anfragen, die zur laufenden Transaktion gehören, über eine alte oder tote Verbindung gesendet werden. Werden über die Verbindung jedoch Anfragen gesendet, die zu einer neuen Transaktion gehören, versucht der Server vor der nächsten Anfrage eine Neuverbindung. Von der Verwendung dieses Features wird abgeraten, da es Auswirkungen auf den Session-Zustand und die Datenkonsistenz hat, wenn Anwendungen nicht richtig mit SQLExceptions umgehen können. Es sollte nur verwendet werden, wenn die Anwendung nicht richtig konfiguriert werden kann, um SQLExceptions, die aus alten oder toten Verbindungen resultieren, richtig zu handhaben. Als Alternative können Sie eventuell die MySQL-Server-Variable "wait_timeout" auf einen höheren als den Standardwert von 8 Stunden setzen.

false

1.1

autoReconnectForPools | Verwendung einer Neuverbindungsstrategie, die sich für Verbindungspools eignet (Standardwert ist 'false') | false | 3.1.3
failOverReadOnly | Soll die Verbindung 'read-only' gesetzt werden, wenn im autoReconnect-Modus ein Ausfall passiert? | true | 3.0.12
reconnectAtTxEnd | Soll der Treiber am Ende jeder Transaktion eine Neuverbindung versuchen, wenn autoReconnect auf true gesetzt ist? | false | 3.0.10
roundRobinLoadBalance | Sollen Verbindungs-Hosts round-robin ausgewählt werden, wenn autoReconnect eingeschaltet und failoverReadonly auf false gesetzt ist? | false | 3.1.2
queriesBeforeRetryMaster | Anzahl der Anfragen, die bei einem Ausfall (Failover) abgesetzt werden, ehe wieder auf den Master zurückgegriffen wird (bei Verwendung von Multi-Host-Failover). Die Bedingung, die zuerst erfüllt wird, ('queriesBeforeRetryMaster' oder 'secondsBeforeRetryMaster') veranlasst einen neuen Verbindungsversuch mit dem Master. Standardwert ist 50. | 50 | 3.0.2
secondsBeforeRetryMaster | Wie lange soll der Treiber bei einem Ausfall warten, ehe er wieder eine Verbindung zum Masterserver versucht? Die Bedingung, die zuerst erfüllt wird, ('queriesBeforeRetryMaster' oder 'secondsBeforeRetryMaster') veranlasst einen neuen Verbindungsversuch mit dem Master. Zeitangabe in Sekunden, Standardwert ist 30 | 30 | 3.0.2
resourceId | Ein global eindeutiger Bezeichner für die Ressource, mit welcher diese Datenquelle oder Verbindung verbunden ist, wird für `XAResource.isSameRM()` verwendet, wenn der Treiber diesen Wert nicht anhand der Hostnamen im URL ermitteln kann |  | 5.0.1

Sicherheit.

Name der Eigenschaft | Definition | Standardwert | Seit Version
allowMultiQueries | Erlaubt das Trennzeichen' ;', um mehrere Anfragen in einer einzigen Anweisung abzugrenzen. (true/false, Standardwert ist 'false') | false | 3.1.1
useSSL | SSL wird zur Kommunikation mit dem Server eingesetzt (true/false), Standardwert ist 'false' | false | 3.0.2
requireSSL | Wird SSL-Verbindung verlangt, wenn useSSL=true? (Standardwert ist 'false'). | false | 3.1.0
allowUrlInLocalInfile | Soll der Treiber URLs in 'LOAD DATA LOCAL INFILE'-Anweisungen zulassen? | false | 3.1.4
paranoid | Maßnahmen ergreifen, damit keine schutzwürdigen Informationen in Fehlermeldungen erscheinen und Datenstrukturen, die schutzwürdige Daten enthalten, nach Möglichkeit löschen? (Standardwert ist 'false') | false | 3.0.1

Performance-Erweiterungen.

Name der Eigenschaft | Definition | Standardwert | Seit Version
metadataCacheSize | Die Anzahl der Anfragen, für die cacheResultSetMetadata eintritt, wenn cacheResultSetMetaData auf 'true' gesetzt ist (Standardwert 50) | 50 | 3.1.1
prepStmtCacheSize | Wie viele vorbereitete Anweisungen sollen gespeichert werden, wenn Caching von vorbereiteten Anweisungen eingeschaltet ist? | 25 | 3.0.10
prepStmtCacheSqlLimit | Wie lang darf eine SQL-Anweisung, deren Parse-Ergebnis der Treiber speichert, höchstens sein, wenn Caching von vorbereiteten Anweisungen eingeschaltet ist? | 256 | 3.0.10
useCursorFetch | Wenn bei einer Anweisung MySQL > 5.0.2 und `setFetchSize()` > 0 gilt, soll diese Anweisung Zeilen mit Cursor-Fetching abholen? | false | 5.0.0
blobSendChunkSize | Datenblöcke dieser Größe verwenden, wenn BLOB/CLOBs mit ServerPreparedStatements verschickt werden | 1048576 | 3.1.9
cacheCallableStmts | Soll der Treiber das Parsing-Stadium von CallableStatements cachen? | false | 3.1.2
cachePrepStmts | Soll der Treiber das Parsing-Stadium von PreparedStatements von clientseitigen vorbereiteten Anweisungen sowie die Eignungsprüfung von serverseitigen vorbereiteten Anweisungen und die serverseitigen vorbereiteten Anweisungen selbst cachen? | false | 3.0.10
cacheResultSetMetadata | Soll der Treiber ResultSetMetaData für Statements und PreparedStatements cachen? (JDK-1.4+ erforderlich, true/false, Standardwert 'false') | false | 3.1.1
cacheServerConfiguration | Soll der Treiber die Ergebnisse von `SHOW VARIABLES` und `SHOW COLLATION` pro URL cachen? | false | 3.1.5
defaultFetchSize | Der Treiber ruft setFetchSize(n) mit diesem Wert auf allen neu erstellten Anweisungen auf | 0 | 3.1.9

dontTrackOpenResources

Laut JDBC-Spezifikation muss der Treiber automatisch Ressourcen verfolgen und schließen, doch wenn Ihre Anwendung nicht gut darin ist, explizit `close()` auf Anweisungen oder Ergebnismengen aufzurufen, kann dies zu Speicherverlust führen. Wenn Sie diese Eigenschaft auf true setzen, lockern Sie diese Einschränkung und erhöhen für bestimmte Anwendungen die Speichereffizienz

false

3.1.7

dynamicCalendars | Soll der Treiber den Standardkalender abrufen, oder ihn pro Verbindung/Session cachen? | false | 3.1.5
elideSetAutoCommits | Für MySQL-4.1 oder neuer: Soll der Treiber 'set autocommit=n'-Anfragen nur absetzen, wenn der Server-Zustand nicht dem durch `Connection.setAutoCommit(boolean)` geforderten Zustand entspricht? | false | 3.1.3
holdResultsOpenOverStatementClose | Soll der Treiber bei `Statement.close()` Ergebnismengen abschließen, wie es die JDBC-Spezifikation fordert? | false | 3.1.7
locatorFetchBufferSize | Wenn 'emulateLocators' auf 'true' gesetzt ist: Wie groß soll der Puffer sein, wenn BLOB-Daten für einen getBinaryInputStream abgeholt werden? | 1048576 | 3.2.1

rewriteBatchedStatements

Soll der Treiber Multiqueries verwenden (unabhängig von der Einstellung von `allowMultiQueries`) und vorbereitete `INSERT`-Anweisungen in Insert-Operationen mit mehreren Werten umformulieren, wenn executeBatch() aufgerufen wird? Beachten Sie, dass dies die Gefahr von SQL-Injection birgt, wenn Sie einfache java.sql.Statements verwenden und Ihr Code die Eingabewerte nicht richtig säubert. Für vorbereitete Anweisungen müssen Sie wissen, dass serverseitige vorbereitete Anweisungen gegenwärtig noch nicht von dieser Umformulierungsoption Gebrauch machen können. Wenn Sie PreparedStatement.set*Stream() ohne Angabe von Stream-Längen verwenden, kann darüber hinaus der Treiber die optimale Anzahl der Parameter pro Batch nicht ermitteln und meldet einen Fehler, dass das resultierende Paket zu groß wird. Statement.getGeneratedKeys() funktioniert für diese umformulierten Anweisungen nur dann, wenn der gesamte Batch INSERT-Anweisungen enthält.

false

3.1.13

useFastIntParsing | Interne String->Integer-Konvertierungsroutinen verwenden, damit nicht zu viele Objekte angelegt werden? | true | 3.1.4
useJvmCharsetConverters | Immer die in der JVM integrierten Zeichencodierungsroutinen verwenden, anstatt Lookup-Tabellen für Single-Byte-Zeichensätze zu benutzen? (Der Standardwert "true" ist für neuere JVMs geeignet) | true | 5.0.1
useLocalSessionState | Soll der Treiber die internen Werte für Autocommit und Transaktionsisolation benutzen, die von Connection.setAutoCommit() und Connection.setTransactionIsolation() gesetzt werden, anstatt die Datenbank anzufragen? | false | 3.1.7
useReadAheadInput | Soll beim Lesen von Serverdaten der optimierte nicht-blockierende, gepufferte Eingabestrom verwendet werden? | true | 3.1.5

Debugging/Profiling.

Name der Eigenschaft | Definition | Standardwert | Seit Version
logger | Name einer Klasse, die 'com.mysql.jdbc.log.Log' implementiert und zur Protokollierung von Nachrichten verwendet wird. (Standardwert ist 'com.mysql.jdbc.log.StandardLogger', eine Klasse, die in STDERR schreibt) | com.mysql.jdbc.log.StandardLogger | 3.1.1
profileSQL | Anfragen und ihre Ausführungs/Fetch-Zeiten werden im konfigurierten Logger verfolgt (true/false), Standardwert ist 'false' | false | 3.1.0
reportMetricsIntervalMillis | Wenn 'gatherPerfMetrics' aktiviert ist: In welchen Abständen sollen diese Daten gesammelt werden (in Millisekunden)? | 30000 | 3.1.2
maxQuerySizeToLog | Die maximale Länge einer Anfrage, die bei Profiling oder Tracing prokolliert wird | 2048 | 3.1.3
packetDebugBufferSize | Die Höchstzahl der Pakete, die gepuffert werden, wenn 'enablePacketDebug' true ist | 20 | 3.1.3
slowQueryThresholdMillis | Wenn 'logSlowQueries' eingeschaltet ist: Wie lange darf eine Anfrage (in ms) dauern, ehe sie als 'langsam' protokolliert wird? | 2000 | 3.1.2
useUsageAdvisor | Soll der Treiber ins Log 'usage'-Warnungen schreiben, um eine korrekte und effiziente Nutzung von JDBC und MySQL Connector/J anzuraten (true/false, Standardwert ist 'false')? | false | 3.1.1
autoGenerateTestcaseScript | Soll der Treiber ausgeführtes SQL einschließlich serverseitige vorbereitete Anweisungen in STDERR speichern? | false | 3.1.9
dumpMetadataOnColumnNotFound | Soll der Treiber feldbezogene Metadaten einer Ergebnismenge in die Ausnahmemeldung schreiben, wenn ResultSet.findColumn() fehlschlägt? | false | 3.1.13
dumpQueriesOnException | Soll der Treiber den Inhalt der an den Server gesandten Anfrage in der Meldung für SQLExceptions speichern? | false | 3.1.3
enablePacketDebug | Wenn dies eingeschaltet ist, wird ein Ring-Puffer mit 'packetDebugBufferSize'-Paketen behalten und gespeichert, sofern in bestimmten Bereichen des Treibercodes Ausnahmen ausgelöst werden | false | 3.1.3
explainSlowQueries | Wenn 'logSlowQueries' eingeschaltet ist: Soll der Treiber automatisch eine 'EXPLAIN'-Anweisung an den Server stellen und die Ergebnisse auf WARN-Level an das konfigurierte Log schicken? | false | 3.1.2
logSlowQueries | Sollen Anfragen protokolliert werden, die länger als 'slowQueryThresholdMillis' dauern? | false | 3.1.2
traceProtocol | Soll das Trace-Netzwerkprotokoll ins Log gespeichert werden? | false | 3.1.2

Verschiedenes.

Name der Eigenschaft | Definition | Standardwert | Seit Version
useUnicode | Soll der Treiber zur Behandlung von Strings Unicode-Zeichencodes verwenden? Dies sollte nur eingesetzt werden, wenn der Treiber die Zeichensatzzuordnung nicht ermitteln kann, oder wenn Sie versuchen, dem Treiber einen Zeichensatz 'aufzuzwingen', den MySQL nicht nativ unterstützt (wie UTF-8). true/false, Standardwert ist 'true' | true | 1.1g
characterEncoding | Wenn 'useUnicode' auf true gesetzt ist: Welche Zeichencodierung soll der Treiber für den Umgang mit Strings verwenden? (Standardwert ist 'autodetect') |  | 1.1g
characterSetResults | Mit diesem Zeichensatz soll der Server Ergebnismengen zurückgeben. |  | 3.0.13
connectionCollation | Wenn dies gesetzt ist, verwendet der Server die mit 'set collation_connection' eingestellte Sortierreihenfolge für Zeichen |  | 3.0.13
sessionVariables | Eine kommagetrennte Liste von Namen/Wert-Paaren, die als SET SESSION ... an den Server geschickt wird, wenn sich der Treiber verbindet |  | 3.1.8
allowNanAndInf | Soll der Treiber NaN- oder +/- INF-Werte in PreparedStatement.setDouble() zulassen? | false | 3.1.5
autoClosePStmtStreams | Soll der Treiber automatisch .close() auf Streams/Readern aufrufen, die mit set*()-Methoden als Argumente übergeben wurden? | false | 3.1.12
autoDeserialize | Soll der Treiber in BLOB-Feldern gespeicherte Objekte automatisch erkennen und deserialisieren? | false | 3.1.5
capitalizeTypeNames | Sollen Typnamen in DatabaseMetaData groß geschrieben werden? (Ist normalerweise nur für WebObjects nützlich, true/false, Standardwert ist 'false') | false | 2.0.7
clobCharacterEncoding | Diese Zeichencodierung soll anstelle der für die Verbindung konfigurierten characterEncoding zum Senden und Abrufen von TEXT-, MEDIUMTEXT- und LONGTEXT-Werten verwendet werden. |  | 5.0.0
clobberStreamingResults | Sorgt dafür, dass ein 'streaming'-ResultSet automatisch geschlossenwird, und dass anhängige Daten, die immer vom Server eintreffen, verworfen werden, wenn eine andere Anfrage ausgeführt wird, bevor alle Daten vom Server eingelesen worden sind. | false | 3.0.9
continueBatchOnError | Soll der Treiber weiterhin Batch-Befehle ausführen, wenn eine Anweisung gescheitert ist? Laut JDBC-Spezifikation sind beide Möglichkeiten erlaubt (Standardwert ist 'true'). | true | 3.0.3
createDatabaseIfNotExist | Legt die im URL angegebene Datenbank an, wenn sie noch nicht existiert, vorausgesetzt, der Benutzer hat die Berechtigung zum Anlegen von Datenbanken. | false | 3.1.9
emptyStringsConvertToZero | Soll der Treiber erlauben, dass leere String-Felder in '0'-Werte konvertiert werden? | true | 3.1.8
emulateLocators | N/A | false | 3.1.0
emulateUnsupportedPstmts | Soll der Treiber vorbereitete Anweisungen erkennen, die nicht vom Server unterstützt werden, und sie durch emulierte Versionen auf der Clientseite ersetzen? | true | 3.1.7
ignoreNonTxTables | Warnungen wegen nicht-transaktionssicherer Tabellen beim Rollback ignorieren? (Standardwert ist 'false'). | false | 3.0.9
jdbcCompliantTruncation | Soll der Treiber beim Kappen von Daten java.sql.DataTruncation-Ausnahmen auslösen, wie es die JDBC-Spezifikation verlangt, wenn er mit einem Server verbunden ist, der Warnungen unterstützt (MySQL 4.1.0 und neuer)? | true | 3.1.2
maxRows | So viele Zeilen werden maximal zurückgegeben (der Standardwert 0 bedeutet, dass alle Zeilen zurückgegeben werden). | -1 | alle Versionen
noAccessToProcedureBodies | Soll der Treiber grundlegende Metadaten erstellen (alle Parameter werden als INOUT VARCHARs gemeldet), anstatt eine Ausnahme auszulösen, wenn er Prozedurparametertypen für CallableStatements ermitteln soll und der Benutzer nicht mit "SHOW CREATE PROCEDURE" auf die Prozdedurrümpfe zugreifen oder mysql.proc abfragen kann? | false | 5.0.3
noDatetimeStringSync | Nicht dafür sorgen, dass ResultSet.getDatetimeType().toString().equals(ResultSet.getString()) | false | 3.1.7
noTimezoneConversionForTimeType | TIME-Werte nicht auf die Server-Zeitzone umstellen, wenn 'useTimezone'='true' | false | 5.0.0
nullCatalogMeansCurrent | Wenn DatabaseMetadataMethods einen 'catalog'-Parameter abfragen, steht dann der Wert Null für den aktuellen Katalog? (Das ist zwar nicht JDBC-konform, entspricht aber dem Verhalten älterer Treiberversionen) | true | 3.1.8
nullNamePatternMatchesAll | Sollen DatabaseMetaData-Methoden, die *pattern-Parameter entgegennehmen, Null ebenso wie '%' behandeln (ist zwar nicht JDBC-konform, aber ältere Treiberversionen akzeptierten diese Abweichung von der Spezifikation) | true | 3.1.8

overrideSupportsIntegrityEnhancementFacility

Soll der Treiber für DatabaseMetaData.supportsIntegrityEnhancementFacility() auch dann "true" zurückgeben, wenn die Datenbank es nicht akzeptiert, um einen Workaround für Anwendungen (wie beispielsweise OpenOffice) zu ermöglichen, die verlangen, dass diese Methode "true" zurückgibt, um Unterstützung für Fremdschlüssel zu signalisieren, auch wenn die SQL-Spezifikation besagt, dass diese Facility noch viel mehr als nur Fremdschlüsselunterstützung umfasst?

false

3.1.12

pedantic | Die JDBC-Spezifikation wortwörtlich befolgen | false | 3.0.0
pinGlobalTxToPhysicalConnection | Wenn XAConnections verwendet werden: Soll der Treiber gewährleisten, dass Operationen auf einer konkreten XID immer an dieselbe physikalische Verbindung weitergeleitet werden? So kann die XAConnection "XA START ... JOIN" auch nach dem Aufruf von "XA END" noch unterstützen. | false | 5.0.1
processEscapeCodesForPrepStmts | Soll der Treiber Escape-Codes in vorbereiteten Anweisungen verarbeiten? | true | 3.1.12
relaxAutoCommit | Wenn sich der Treiber mit einer MySQL-Version verbindet, die keine Transaktionen unterstützt: Sollen dennoch commit(), rollback() und setAutoCommit() erlaubt sein? (true/false, Standardwert ist 'false')? | false | 2.0.13
retainStatementAfterResultSetClose | Soll sich der Treiber die Statement-Referenz in einem ResultSet merken, nachdem ResultSet.close() aufgerufen wurde? Dies ist nach JDBC-4.0 nicht mehr JDBC-konform. | false | 3.1.11
rollbackOnPooledClose | Soll der Treiber rollback() aufrufen, wenn die logische Verbindung in einem Pool geschlossen wird? | true | 3.0.15
runningCTS13 | Ermöglicht Workarounds für Fehler in der JDBC Compliance Testsuite Version 1.3 von Sun | false | 3.1.7
serverTimezone | Überschreibt die Erkennung/Zuordnung der Zeitzone. Wird verwendet, wenn sich die Zeitzone des Servers nicht auf die Java-Zeitzone abbilden lässt. |  | 3.0.2
strictFloatingPoint | Wird nur in älteren Versionen des Compliance Tests verwendet | false | 3.0.0
strictUpdates | Soll der Treiber eine strenge Prüfung (aller ausgewählten Primärschlüssel) aktualisierbarer Ergebnismenge vornehmen? (true, false, Standardwert ist 'true') | true | 3.0.4
tinyInt1isBit | Soll der Treiber den Datentyp TINYINT(1) als BIT-Typ behandeln (da der Server insgeheim sowieso eine BIT -> TINYINT(1)-Konvertierung vornimmt, wenn er Tabellen anlegt)? | true | 3.0.16
transformedBitIsBoolean | Wenn der Treiber TINYINT(1) in einen anderen Datentyp konvertiert: Soll er BOOLEAN anstelle von BIT verwenden (dient der zukünftigen Kompatibilität mit MySQL-5.0, da MySQL-5.0 einen BIT-Typ hat)? | false | 3.1.9
ultraDevHack | Wenn nötig PreparedStatements für prepareCall() erstellen, da UltraDev nicht funktioniert und prepareCall() für alle Anweisungen aufruft? (true/false, Standardwert ist 'false') | false | 2.0.3
useGmtMillisForDatetimes | Konvertiert zwischen Session-Zeitzone und GMT vor der Erzeugung von Date- und Timestamp-Objekten ("false" ist veraltetes Verhalten, "true" ist eher JDBC-konform). | false | 3.1.12
useHostsInPrivileges | Den Benutzern in DatabaseMetaData.getColumn/TablePrivileges() einen '@hostname' hinzufügen (true/false), Standardwert ist 'true'. | true | 3.0.2
useInformationSchema | Soll der Treiber bei Verbindung mit MySQL-5.0.7 oder neuer die von DatabaseMetaData benötigten Informationen aus dem INFORMATION_SCHEMA ableiten? | false | 5.0.0
useJDBCCompliantTimezoneShift | Soll der Treiber sich beim Konvertieren der Zeitzoneninformationen von TIME/TIMESTAMP/DATETIME-Werten für JDBC-Argumente, die ein java.util.Calendar-Argument nehmen an den JDBC-Standard halten? (Achtung, diese Option und die Konfigurationsoption "useTimezone=true" schließen sich gegenseitig aus.) | false | 5.0.0
useOldUTF8Behavior | Stellt das alte UTF-8-Verhalten ein, das der Treiber bei Kommunikation mit 4.0 und älteren Servern an den Tag legt. | false | 3.1.6
useOnlyServerErrorMessages | Keine 'Standard'-SQLState-Fehlermeldungen den vom Server zurückgelieferten Fehlermeldungen voranstellen. | true | 3.0.15
useServerPrepStmts | Serverseitige vorbereitete Anweisungen verwenden, wenn der Server sie unterstützt? (Standardwert ist 'true'). | true | 3.1.0
useSqlStateCodes | Zustandscodes gemäß SQL-Standard anstelle der 'alten' X/Open/SQL-Zustandscodes verwenden? (true/false), Standardwert ist 'true' | true | 3.1.3
useStreamLengthsInPrepStmts | StreamLength-Parameter in Aufrufen der PreparedStatement/ResultSet.setXXXStream()-Methode berücksichtigen? (true/false, Standardwert ist 'true') | true | 3.0.2
useTimezone | Datums/Uhrzeittypen zwischen Client- und Server-Zeitzone konvertieren (true/false, Standardwert ist 'false')? | false | 3.0.2
useUnbufferedInput | Keinen BufferedInputStream zum Lesen von Daten auf dem Server verwenden | true | 3.0.11
yearIsDateType | Soll der JDBC-Treiber den MySQL-Typ "YEAR" als java.sql.Date oder als SHORT behandeln? | true | 3.1.9
zeroDateTimeBehavior | Was soll geschehen, wenn der Server auf DATETIME-Werte trifft, die ausschließlich aus Nullen bestehen (so stellt MySQL ungültige Datumswerte dar)? Zulässige Werte sind 'exception', 'round' und 'convertToNull'. | exception | 3.1.4

Connector/J bietet auch MySQL-Zugriff über Named Pipes für Windows NT/2000/XP. Hierzu wird die NamedPipeSocketFactory als Plugin-Socket-Factory mithilfe der Eigenschaft socketFactory eingestellt. Wenn Sie keine namedPipePath-Eigenschaft einstellen, wird standardmäßig '\\.\pipe\MySQL' benutzt. Verwenden Sie die `NamedPipeSocketFactory`, so werden der Hostname und die Port-Nummer im JDBC-URL ignoriert. Sie können dieses Feature wie folgt einschalten:

    socketFactory=com.mysql.jdbc.NamedPipeSocketFactory

Named Pipes funktinieren nur, wenn Sie sich mit dem MySQL-Server auf demselben Computer verbinden, auf dem auch der JDBC-Treiber eingesetzt wird. In einfachen Performance-Tests sieht es so aus, als sei der Zugriff über Named Pipes um 30%-50% schneller als der traditionelle TCP/IP-Zugriff.

Mit dem Beispielcode in `com.mysql.jdbc.NamedPipeSocketFactory` oder `com.mysql.jdbc.StandardSocketFactory` können Sie eigene Socket-Factories bauen.

#### 25.3.4.2. Hinweise zur Implementierung der JDBC-API

MySQL Connector/J besteht alle Tests der öffentlich zugänglichen JDBC Compliance Testsuite von Sun. Doch an vielen Stellen sagt die JDBC-Spezifikation nicht genau, wie eine Funktionalität implementiert werden soll.

In diesem Abschnitt wird für jede Schnittstelle untersucht, wie sich Ihre Implementierungsentscheidungen auf die Verwendung von MySQL Connector/J auswirken können.

- Blob

  Die BLOB-Implementierung erlaubt keine Modifikationen an Ort und Stelle (sondern nur in Kopien, die von der Methode `DatabaseMetaData.locatorsUpdateCopies()` angezeigt werden). Daher sollten Sie Änderungen mit der entsprechenden `PreparedStatement.setBlob()`- oder `ResultSet.updateBlob()`-Methode (für aktualisierbare Ergebnismengen) in die Datenbank zurückspeichern.

  Seit Connector/J version 3.1.0 können Sie Blobs mit Locators emulieren, indem Sie Ihrem JDBC-URL die Eigenschaft 'emulateLocators=true' hinzufügen. Sie müssen dann einen Spaltenalias einsetzen, wobei der Wert der Spalte auf den tatsächlichen Namen der Blob-Spalte in der `SELECT`-Anweisung gesetzt wird, die Sie zum Abrufen des Blob schreiben. Die `SELECT`-Anweisung darf nur eine einzige Tabelle referenzieren, die Tabelle muss einen Primärschlüssel haben, und das `SELECT` muss alle Spalten enthalten, die diesen Primärschlüssel ausmachen. Der Treiber wird dann das Laden der tatsächlichen Blob-Daten so lange aufschieben, bis Sie den Blob abrufen und auf ihm entsprechende Abrufmethoden aufrufen (`getInputStream()`, `getBytes()` usw.).

- CallableStatement

  Seit Connector/J 3.1.1 werden über die Schnittstelle `CallableStatement` bei Verbindungen mit MySQL 5.0 oder neuer gespeicherte Prozeduren unterstützt. Die Methode `getParameterMetaData()` von `CallableStatement` wird gegenwärtig noch nicht unterstützt.

- Clob

  Die CLOB-Implementierung erlaubt keine Modifikationen an Ort und Stelle (sondern nur in Kopien, die von der Methode `DatabaseMetaData.locatorsUpdateCopies()` angezeigt werden). Daher sollten Sie Änderungen mit der entsprechenden `PreparedStatement.setClob()`-Methode in die Datenbank zurückspeichern. Die JDBC-API kennt keine `ResultSet.updateClob()`-Methode.

- Connection

  Im Gegensatz zu älteren Versionen von MM.MySQL wird die Methode `isClosed()` den Server nicht pingen, um festzustellen, ob er noch lebendig ist. Entsprechend der JDBC-Spezifikation gibt sie lediglich true zurück, wenn `closed()` auf der Verbindung aufgerufen worden ist. Wenn Sie feststellen möchten, ob die Verbindung noch steht, setzen Sie eine einfache Anfrage wie beispielsweise `SELECT 1` ab. Ist die Verbindung ungültig geworden, löst der Treiber eine Ausnahme aus.

- DatabaseMetaData

  Fremdschlüsselinformationen (`getImportedKeys()`/`getExportedKeys()` und `getCrossReference()`) sind nur für InnoDB-Tabellen erhältlich. Da der Server diese Informationen jedoch mit `SHOW CREATE TABLE` abruft, wird er auch andere Speicher-Engines unterstützen, die Fremdschlüssel kennen.

- PreparedStatement

  PreparedStatements werden vom Treiber implementiert, da MySQL keine vorbereiteten Anweisungen kennt. Dahler implementiert der Treiber auch kein `getParameterMetaData()` oder `getMetaData()`, da er dann einen kompletten SQL-Parser im Client benötigen würde.

  Seit Version 3.1.0 verwendet MySQL Connector/J serverseitige vorbereitete Anweisungen und binär codierte Ergebnsmengen, wenn der Server diese ermöglicht.

  Seien Sie vorsichtig, wenn Sie eine serverseitige vorbereitete Anweisung mit großen Parametern verwenden, die mit `setBinaryStream()`, `setAsciiStream()`, `setUnicodeStream()`, `setBlob()` oder `setClob()` eingestellt werden. Wenn Sie die Anweisung erneut ausführen, aber dabei die großen auf kleine Parameter umstellen möchten, müssen Sie `clearParameters()` aufrufen und alle Parameter neu einstellen. Dies hat folgenden Grund:

  - Wenn der Parameter gesetzt ist, lässt der Treiber die großen Daten Band-extern in die vorbereitete Anweisung auf der Serverseite streamen (und zwar vor Ausführung der vorbereiteten Anweisung).

  - Wenn dies erledigt ist, wird der Stream, mit dem Daten auf der Clientseite gelesen wurden, geschlossen (genz JDBC-konform), und kann nicht mehr gelesen werden.

  - Wird der Parameter von groß auf klein umgestellt, muss der Treiber den serverseitigen Zustand der vorbereiteten Anweisung zurücksetzen, damit der neue Parameter den Platz des vorherigen, großen Werts einnehmen kann. Dadurch werden alle großen Daten, die bereits an den Server geschickt wurden, entfernt, sodass sie mit einer der Methoden `setBinaryStream()`, `setAsciiStream()`, `setUnicodeStream()`, `setBlob()` oder `setClob()` erneut gesandt werden müssen.

  Um einen Parameter von einem großen auf einen kleinen Typ umzustellen, müssen Sie folglich `clearParameters()` aufrufen und alle Parameter der vorbereiteten Anweisung neu einstellen, ehe diese wieder ausgeführt werden kann.

- ResultSet

  Nach Voreinstellung werden ResultSets vollständig abgeholt und in den Arbeitsspeicher geladen. Meist ist dies am effizientesten und durch den Entwurf des MySQL-Netzwerkprotokolls auch am einfachsten zu implementieren. Wenn Sie jedoch mit ResultSets arbeiten, die viele Zeilen oder große Werte enthalten, und in Ihrer JVM keinen Heap-Space für den erforderlichen Arbeitsspeicher zuweisen können, können Sie den Treiber auch veranlassen, die Ergebnisse zeilenweise hereinströmen zu lassen.

  Um diese Funktionalität nutzen zu können, müssen Sie ein Statement-Objekt wie folgt erzeugen:

      stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                    java.sql.ResultSet.CONCUR_READ_ONLY);
      stmt.setFetchSize(Integer.MIN_VALUE);

  Die Kombination aus einer forward-only, nur-lesenden Ergebnismenge der Größe `Integer.MIN_VALUE` ist für den Treiber das Signal, die Ergebnismengen zeilenweise hereinströmen zu lassen. Danach werden auch alle weiteren mit dieser Anweisung abgerufenen Ergebnismengen zeilenweise eingelesen.

  Dieser Ansatz hat einige Tücken. Sie müssen alle Zeilen der Ergebnismenge lesen (oder sie schließen), ehe Sie auf der Verbindung weitere Anfragen absetzen können. Sonst wird eine Ausnahme ausgelöst.

  Die Sperren, die diese Anweisungen halten, können frühestens freigegeben werden, wenn die Anweisung abgeschlossen ist. (Dies gilt für `MyISAM`-Tabellensperren ebenso wie für die Zeilensperren einiger anderer Speicher-Engines, wie etwa `InnoDB`.)

  Wenn die Anweisung zu einer Transaktion gehört, werden die Sperren erst freigegeben, wenn die Transaktion fertig ist (was impliziert, dass auch die Anweisung zuerst fertig sein muss). Wie in den meisten anderen Datenbanken auch, sind Anweisungen erst dann abgeschlossen, wenn alle Ergebnisse gelesen wurden, oder die aktive Ergebnismenge der Anweisung geschlossen worden ist.

  Daher sollten Sie Streaming-Ergebnisse immer so schnell wie möglich lesen, wenn die von der Anweisung referenzierten Tabellen weiterhin nebenläufig zugänglich sein sollen.

- ResultSetMetaData

  Die Methode `isAutoIncrement()` funktioniert nur mit MySQL 4.0 und neuer.

- Statement

  Wenn Sie ältere JDBC-Treiberversionen als 3.2.1 in Verbindung mit älteren älteren Server-Versionen als 5.0.3 benutzen, hat die Methode "setFetchSize()" keine andere Wirkung, als das Ergebnismengen-Streaming umzuschalten, wie oben beschrieben.

  MySQL unterstützt keine SQL-Cursors und der JDBC-Treiber emuliert sie auch nicht. Daher hat "setCursorName()" keine Wirkung.

#### 25.3.4.3. Datentypen von Java, JDBC und MySQL

MySQL Connector/J ist flexibel in Bezug auf die Konvertierung von MySQL- und Java-Datentypen.

Generell lässt sich jeder MySQL-Datentyp in einen java.lang.String und jeder numerische Typ in einen numerischen Java-Typ umwandeln, wobei jedoch Rundungen, Überlauf oder Genauigkeitsverluste eintreten können.

Seit Connector/J 3.1.0 gibt der JDBC-Treiber Warnungen oder DataTruncation-Ausnahmen im Einklang mit der JDBC-Spezifikation aus, wenn Sie dies nicht ausdrücklich unterbinden, indem Sie die Eigenschaft jdbcCompliantTruncation auf `false` setzen.

Die in der folgenden Tabelle aufgeführten Konvertierungen funktionieren garantiert:

Verbindungseigenschaften - Diverse.

Diese MySQL-Datentypen | lassen sich immer in diese Java-Typen konvertieren
`CHAR, VARCHAR, BLOB, TEXT, ENUM, and SET` | `java.lang.String, java.io.InputStream, java.io.Reader, java.sql.Blob, java.sql.Clob`
`FLOAT, REAL, DOUBLE PRECISION, NUMERIC, DECIMAL, TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT` | `java.lang.String, java.lang.Short, java.lang.Integer, java.lang.Long, java.lang.Double, java.math.BigDecimal`
`DATE, TIME, DATETIME, TIMESTAMP` | `java.lang.String, java.sql.Date, java.sql.Timestamp`

Hinweis: Wenn Sie einen numerischen Java-Typ auswählen, der weniger genau oder groß als der MySQL-Typ ist, aus oder in welchen Sie konvertieren, kann es zu Rundungsverhalten, Überlauf oder Genauigkeitsverlust kommen.

Die Methode `ResultSet.getObject()` nimmt folgende Konvertierungen zwischen MySQL- und Java-Typen vor, wobei sie sich möglichst an die JDBC-Spezifikation hält:

Konvertierung von MySQL- in Java-Typen für ResultSet.getObject().

MySQL-Typname | Rückgabe als Java-Klasse
BIT(1) (neu in MySQL-5.0) | `java.lang.Boolean`
BIT( > 1) (neu in MySQL-5.0) | `byte[]`
TINYINT | `java.lang.Boolean`, wenn die Konfigurationseigenschaft `tinyInt1isBit` auf `true` gesetzt ist (der Standardwert) und die Speichergröße 1 ist, andernfalls `java.lang.Integer`.
BOOL, BOOLEAN | Siehe TINYINT weiter oben, da diese Typen zurzeit Aliase für TINYINT(1) sind.
SMALLINT[(M)] [UNSIGNED] | `java.lang.Integer` (egal ob UNSIGNED oder nicht)
MEDIUMINT[(M)] [UNSIGNED] | `java.lang.Integer,` wenn UNSIGNED `java.lang.Long`
INT,INTEGER[(M)] [UNSIGNED] | `java.lang.Integer`, wenn UNSIGNED `java.lang.Long`
BIGINT[(M)] [UNSIGNED] | `java.lang.Long`, wenn UNSIGNED `java.math.BigInteger`
FLOAT[(M,D)] | `java.lang.Float`
DOUBLE[(M,B)] | `java.lang.Double`
DECIMAL[(M[,D])] | `java.math.BigDecimal`
DATE | `java.sql.Date`
DATETIME | `java.sql.Timestamp`
TIMESTAMP[(M)] | `java.sql.Timestamp`
TIME | `java.sql.Time`
YEAR[(2|4)] | `java.sql.Date` (Datum wird um Mitternacht auf 1. Januar umgestellt)
CHAR(M) | `java.lang.String` (wenn der Zeichensatz für die Spalte BINARY ist, wird `byte[]` zurückgegeben).
VARCHAR(M) [BINARY] | `java.lang.String` (wenn der Zeichensatz für die Spalte BINARY ist, wird `byte[]` zurückgegeben).
BINARY(M) | `byte[]`
VARBINARY(M) | `byte[]`
TINYBLOB | `byte[]`
TINYTEXT | `java.lang.String`
BLOB | `byte[]`
TEXT | `java.lang.String`
MEDIUMBLOB | `byte[]`
MEDIUMTEXT | `java.lang.String`
LONGBLOB | `byte[]`
LONGTEXT | `java.lang.String`
ENUM('value1','value2',...) | `java.lang.String`
SET('value1','value2',...) | `java.lang.String`

#### 25.3.4.4. Zeichensätze und Unicode

Alle vom JDBC-Treiber zum Server geschickten Strings werden automatisch vom nativen Java-Unicode in die Zeichencodierung des Clients konvertiert, einschließlich aller mit `Statement.execute()`, `Statement.executeUpdate()` und `Statement.executeQuery()` übermittelten Anfragen, sowie aller `PreparedStatement` - und `CallableStatement` - Parameter mit Ausnahme der Parameter, die mit `setBytes()`, `setBinaryStream()`, `setAsciiStream()`, `setUnicodeStream()` und `setBlob()` eingestellt wurden.

Vor MySQL Server 4.1 unterstützte Connector/J eine einzige Zeichencodierung pro Verbindung. Diese konnte entweder automatisch aus der Severkonfiguration erschlossen oder vom Benutzer mit den Eigenschaften `useUnicode` und "`characterEncoding`" eingestellt werden.

Seit MySQL Server 4.1 unterstützt Connector/J eine einzige Zeichencodierung zwischen Client und Server, aber beliebig viele Zeichencodierungen für Daten, die vom Server in `ResultSets` an den Client zurückgeliefert werden.

Die Zeichencodierung zwischen Client und Server wird automatisch beim Verbindungsaufbau ermittelt. Die vom Treiber verwendete Codierung wird auf dem Server mit der Systemvariablen `character_set` (für ältere Server-Versionen als 4.1.0) oder `character_set_server` (für Server-Versionen ab 4.1.0 ) eingestellt. Weitere Informationen finden Sie unter Abschnitt 10.3.1, „Serverzeichensatz und -sortierfolge“.

Um die automatische Erkennung der Codierung auf der Clientseite außer Kraft zu setzen, setzen Sie die Eigenschaft `characterEncoding` in den für die Server-Verbindung verwendeten URL.

Zeichencodierungen auf der Clientseite geben Sie bitte mit Java-Namen an. In der folgenden Tabelle werden die Java-Namen der MySQL-Zeichensätze aufgeführt:

Übersetzung der Zeichencodierungen von MySQL in Java.

Zeichensatzname in MySQL | Name der Zeichencodierung in Java
usa7 | US-ASCII
big5 | Big5
gbk | GBK
sjis | SJIS (oder Cp932 oder MS932 für MySQL Server < 4.1.11)
cp932 | Cp932 oder MS932 (MySQL Server > 4.1.11)
gb2312 | EUC_CN
ujis | EUC_JP
euc_kr | EUC_KR
latin1 | ISO8859_1
latin1_de | ISO8859_1
german1 | ISO8859_1
danish | ISO8859_1
latin2 | ISO8859_2
czech | ISO8859_2
hungarian | ISO8859_2
croat | ISO8859_2
greek | ISO8859_7
hebrew | ISO8859_8
latin5 | ISO8859_9
latvian | ISO8859_13
latvian1 | ISO8859_13
estonia | ISO8859_13
dos | Cp437
pclatin2 | Cp852
cp866 | Cp866
koi8_ru | KOI8_R
tis620 | TIS620
win1250 | Cp1250
win1250ch | Cp1250
win1251 | Cp1251
cp1251 | Cp1251
win1251ukr | Cp1251
cp1257 | Cp1257
macroman | MacRoman
macce | MacCentralEurope
utf8 | UTF-8
ucs2 | UnicodeBig

Warnung. Verwenden Sie niemals die Anfrage 'set names' mit Connector/J, da der Treiber dann nicht erkennt, dass der Zeichensatz geändert wurde, und weiterhin den Zeichensatz verwendet, den er beim Einrichten der Verbindung gefunden hat.

Wenn Sie ermöglichen möchten, dass mehrere Zeichensätze vom Client gesendet werden können, verwenden Sie bitte die UTF-8-Codierung. Diese können Sie einstellen, indem Sie entweder `utf8` als Standardzeichensatz des Servers angeben, oder den JDBC-Treiber mit der Eigenschaft `characterEncoding` zur Benutzung von UTF-8 veranlassen.

#### 25.3.4.5. Sichere Verbindungen mit SSL

SSL in MySQL Connector/J verschlüsselt alle Daten (außer dem Handshake am Anfang) zwischen dem JDBC-Treiber und dem Server. Allerdings dauert die Verarbeitung von Anfragen, je nach ihrer Größe und dem Umfang der Rückgabedaten, bei Einschaltung von SSL 36% bis 50% länger.

Damit die SSL-Unterstützung funktioniert, ist folgendes erforderlich:

- Ein JDK, das JSSE (Java Secure Sockets Extension) enthält, wie etwa JDK 1.4.1 oder höher. SSL funktioniert zurzeit nicht mit einem JDK, zu dem man JSSE hinzufügen kann, wie JDK-1.2.x oder JDK-1.3.x. Das liegt an folgendem Fehler in JSSE: http://developer.java.sun.com/developer/bugParade/bugs/4273544.html

- Ein MySQL-Server, der SSL unterstützt und auch für SSL kompiliert und konfiguriert ist, also MySQL-4.0.4 oder höher. Mehr Informationen finden Sie unter Abschnitt 5.9.7, „Verwendung sicherer Verbindungen“.

- Ein Client-Zertifikat (wird weiter unten in diesem Abschnitt noch erklärt)

Sie müssen als Erstes das CA-Zertifikat des MySQL-Servers in einen Java-Truststore importieren. Ein Beispiel eines CA-Zertifikats für MySQL-Server finden Sie im Unterverzeichnis `SSL` der MySQL-Quelldistribution. Anhand dieses Zertifikats wird SSL feststellen, ob Sie mit einem sicheren MySQL-Server kommunizieren.

Um mit dem Java-keytool einen Truststore im aktuellen Verzeichnis anzulegen und das CA-Zertifikat des Servers (`cacert.pem`) zu importieren, gehen Sie wie unten beschrieben vor (vorausgesetzt, das keytool liegt in Ihrem Pfad). (Das keytool müsste im Unterverzeichnis `bin` Ihres JDK oder JRE zu finden sein):

    shell> keytool -import -alias mysqlServerCACert -file cacert.pem -keystore truststore

Keytool antwortet mit folgenden Informationen:

    Enter keystore password:  *********
    Owner: EMAILADDRESS=walrus@example.com, CN=Walrus, O=MySQL AB, L=Orenburg, ST=Some
    -State, C=RU
    Issuer: EMAILADDRESS=walrus@example.com, CN=Walrus, O=MySQL AB, L=Orenburg, ST=Som
    e-State, C=RU
    Serial number: 0
    Valid from: Fri Aug 02 16:55:53 CDT 2002 until: Sat Aug 02 16:55:53 CDT 2003
    Certificate fingerprints:
             MD5:  61:91:A0:F2:03:07:61:7A:81:38:66:DA:19:C4:8D:AB
             SHA1: 25:77:41:05:D5:AD:99:8C:14:8C:CA:68:9C:2F:B8:89:C3:34:4D:6C
    Trust this certificate? [no]:  yes
    Certificate was added to keystore

Dann müssen sie ein Client-Zertifikat generieren, damit der MySQL-Server weiß, dass er es mit einem sicheren Client zu tun hat:

     shell> keytool -genkey -keyalg rsa -alias mysqlClientCertificate -keystore keystore

Das Keytool fragt Sie nach folgenden Informationen und erstellt einen Keystore namens `keystore` im aktuellen Verzeichnis.

Bitte geben Sie die passenden Informationen für Ihre Situation ein:

    Enter keystore password:  *********
    What is your first and last name?
      [Unknown]:  Matthews
    What is the name of your organizational unit?
      [Unknown]:  Software Development
    What is the name of your organization?
      [Unknown]:  MySQL AB
    What is the name of your City or Locality?
      [Unknown]:  Flossmoor
    What is the name of your State or Province?
      [Unknown]:  IL
    What is the two-letter country code for this unit?
      [Unknown]:  US
    Is <CN=Matthews, OU=Software Development, O=MySQL AB,
     L=Flossmoor, ST=IL, C=US> correct?
      [no]:  y

    Enter key password for <mysqlClientCertificate>
            (RETURN if same as keystore password):

Damit JSSE den Keystore und den Truststore auch benutzt, müssen Sie zum Schluss die folgenden Systemeigenschaften einstellen, wenn Sie Ihre JVM starten. Ersetzen Sie dabei path_to_keystore_file durch den vollständigen Pfad zu der von Ihnen angelegten Keystore-Datei und path_to_truststore_filedurch den vollständigen Pfad zu der von Ihnen angelegten Truststore-Datei und benutzen Sie für jede Eigenschaft die passenden Passwortwerte.

    -Djavax.net.ssl.keyStore=path_to_keystore_file
    -Djavax.net.ssl.keyStorePassword=*********
    -Djavax.net.ssl.trustStore=path_to_truststore_file
    -Djavax.net.ssl.trustStorePassword=*********

Außerdem müssen Sie in den Verbindungsparametern für SQL Connector/JuseSSL auf `true` setzen, indem Sie entweder `useSSL=true` in Ihren URL einfügen, oder die Eigenschaft useSSL in dem `java.util.Properties`-Objekt, das Sie an `DriverManager.getConnection()` übergeben, auf `true` einstellen.

Das Funktionieren von SSL können Sie testen, indem Sie JSSE-Debugging (wie unten beschrieben) einschalten und nach folgenden Key-Ereignissen Ausschau halten:

    ...
     *** ClientHello, v3.1
     RandomCookie:  GMT: 1018531834 bytes = { 199, 148, 180, 215, 74, 12, 54, 244, 0, 168, 55, 103, 215, 64, 16, 138, 225, 190, 132, 153, 2, 217, 219, 239, 202, 19, 121, 78 }
     Session ID:  {}
     Cipher Suites:  { 0, 5, 0, 4, 0, 9, 0, 10, 0, 18, 0, 19, 0, 3, 0, 17 }
     Compression Methods:  { 0 }
     ***
     [write] MD5 and SHA1 hashes:  len = 59
     0000: 01 00 00 37 03 01 3D B6   90 FA C7 94 B4 D7 4A 0C  ...7..=.......J.
     0010: 36 F4 00 A8 37 67 D7 40   10 8A E1 BE 84 99 02 D9  6...7g.@........
     0020: DB EF CA 13 79 4E 00 00   10 00 05 00 04 00 09 00  ....yN..........
     0030: 0A 00 12 00 13 00 03 00   11 01 00                 ...........
     main, WRITE:  SSL v3.1 Handshake, length = 59
     main, READ:  SSL v3.1 Handshake, length = 74
     *** ServerHello, v3.1
     RandomCookie:  GMT: 1018577560 bytes = { 116, 50, 4, 103, 25, 100, 58, 202, 79, 185, 178, 100, 215, 66, 254, 21, 83, 187, 190, 42, 170, 3, 132, 110, 82, 148, 160, 92 }
     Session ID:  {163, 227, 84, 53, 81, 127, 252, 254, 178, 179, 68, 63, 182, 158, 30, 11, 150, 79, 170, 76, 255, 92, 15, 226, 24, 17, 177, 219, 158, 177, 187, 143}
     Cipher Suite:  { 0, 5 }
     Compression Method: 0
     ***
     %% Created:  [Session-1, SSL_RSA_WITH_RC4_128_SHA]
     ** SSL_RSA_WITH_RC4_128_SHA
     [read] MD5 and SHA1 hashes:  len = 74
     0000: 02 00 00 46 03 01 3D B6   43 98 74 32 04 67 19 64  ...F..=.C.t2.g.d
     0010: 3A CA 4F B9 B2 64 D7 42   FE 15 53 BB BE 2A AA 03  :.O..d.B..S..*..
     0020: 84 6E 52 94 A0 5C 20 A3   E3 54 35 51 7F FC FE B2  .nR..\ ..T5Q....
     0030: B3 44 3F B6 9E 1E 0B 96   4F AA 4C FF 5C 0F E2 18  .D?.....O.L.\...
     0040: 11 B1 DB 9E B1 BB 8F 00   05 00                    ..........
     main, READ:  SSL v3.1 Handshake, length = 1712
     ...

JSSE bietet Debugging (in STDOUT), wenn Sie die Systemeigenschaft `-Djavax.net.debug=all` einstellen. So erfahren Sie, welche Keystores und Truststores benutzt werden und was während des SSL-Handshakes und beim Austauschen des Zertifikats passiert. Dies ist nützlich, wenn eine SSL-Verbindung einmal nicht erfolgreich aufgebaut werden kann und Sie versuchen, den Fehler zu finden.

#### 25.3.4.6. Master/Slave-Replikation mit ReplicationConnection

Seit Connector/J 3.1.7 haben wir eine Variante des Treibers entwickelt, die Anfragen je nach dem Zustand von `Connection.getReadOnly()` automatisch an einen lesenden und schreibenden Master oder eine Ausfallserver oder eine nach dem Round-Robin-Verfahren lastbalancierte Gruppe von Slaves weiterleitet.

Wenn eine Anwendung durch Aufruf von `Connection.setReadOnly(true)` signalisiert, dass eine Transaktion nur-lesend sein soll, verwendet diese replikationsfähige Verbindung eine der per round-robin lastbalancierten Slave-Verbindungen (eine Verbindung verbleibt bei einem Slave, bis dieser aus dem Dienst genommen wird). Wenn Sie eine schreibende Transaktion haben oder eine zeitsensible Leseoperation ausführen müssen (vergessen Sie nicht, die Replikation in MySQL ist asynchron), dann stellen Sie die Verbindung mit `Connection.setReadOnly(false)` so ein, dass sie nicht nur-lesend ist. Der Treiber sorgt dann dafür, dass zukünftige Aufrufe an den MySQL-Masterserver gehen. Außerdem reicht der Server den aktuellen Zustand von Autocommit, Isolationsebene und Katalog an alle Verbindungen weiter, die er für diese Lastverteilungsfunktionalität benötigt.

Um diese Funktionalität zu ermöglichen, verwenden Sie die Klasse " `com.mysql.jdbc.ReplicationDriver` ", wenn Sie den Verbindungspool Ihres Anwendungsservers konfigurieren, oder wenn Sie eine Instanz eines JDBC-Treibers für Ihre Standalone-Anwendung erzeugen. Da der `ReplicationDriver` dasselbe URL-Format wie der Standard-MySQL-JDBC-Treiber akzeptiert, funktioniert er gegenwärtig mit einem Verbindungsaufbau à la `java.sql.DriverManager` nur dann, wenn er der einzige MySQL-JDBC-Treiber ist, der beim `DriverManager` registriert wurde.

Hier sehen Sie ein einfaches, kurzes Beispiel dafür, wie man einen ReplicationDriver in einer Standalone-Anwendung einsetzen könnte.

    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.util.Properties;

    import com.mysql.jdbc.ReplicationDriver;

    public class ReplicationDriverDemo {

        public static void main(String[] args) throws Exception {
            ReplicationDriver driver = new ReplicationDriver();

            Properties props = new Properties();

            // Für die Ausfallsicherung mit Slaves
            props.put("autoReconnect", "true");

            // Lastverteilung zwischen den Slaves
            props.put("roundRobinLoadBalance", "true");

            props.put("user", "foo");
            props.put("password", "bar");

            //
            // Sieht aus wie ein normaler MySQL-JDBC-URL mit einer kommagetrennten Liste von Hosts,
            // wobei der erste der 'Master' und die restlichen
            // die Slaves sind, auf die der Treiber die Last verteilt
            //

            Connection conn =
                driver.connect("jdbc:mysql://master,slave1,slave2,slave3/test",
                    props);

            //
            // Lese/Schreiboperationen auf dem Master ausführen, indem
            // das Readonly-Flag auf "false" gesetzt wird.
            //

            conn.setReadOnly(false);
            conn.setAutoCommit(false);
            conn.createStatement().executeUpdate("UPDATE some_table ....");
            conn.commit();

            //
            // Nun eine Anfrage auf einem Slave ausführen, wobei der Treiber automatisch
            // einen aus der Liste auswählt
            //

            conn.setReadOnly(true);

            ResultSet rs = conn.createStatement().executeQuery("SELECT a,b,c FROM some_other_table");

             .......
        }
    }

### 25.3.5. Hinweise und Tipps zu Connector/J

#### 25.3.5.1. Grundkonzepte von JDBC

In diesem Abschnitt wird Grundlagenwissen über JDBC vermittelt.

##### 25.3.5.1.1. Verbindung mit MySQL über die Schnittstelle `DriverManager`

Wenn Sie JDBC außerhalb eines Anwendungsservers benutzen, wird die Einrichtung von Verbindungen über die Klasse `DriverManager` verwaltet.

Sie müssen dem `DriverManager` mitteilen, mit welchen JDBC-Treibern er sich verbinden soll. Die einfachste Möglichkeit besteht darin, die Methode `Class.forName()` auf der Klasse aufzurufen, welche die `java.sql.Driver`-Schnittstelle implementiert. Bei MySQL Connector/J heißt diese Klasse `com.mysql.jdbc.Driver`. Mit dieser Methode können Sie eine externe Konfigurationsdatei verwenden, um den Namen der Treiberklasse und die Treiberparameter zu übergeben, wenn eine Datenbankverbindung aufgebaut wird.

Der folgende Java-Code zeigt, wie Sie MySQL Connector/J in der `main()`-Methode Ihrer Anwendung registrieren könnten:

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;

    // Achtung, nicht com.mysql.jdbc.* importieren,
    // sonst bekommen Sie Probleme!

    public class LoadDriver {
        public static void main(String[] args) {
            try {
                // Der Aufruf von newInstance() ist ein Workaround
                // für einige misslungene Java-Implementierungen

                Class.forName("com.mysql.jdbc.Driver").newInstance();
            } catch (Exception ex) {
                // Fehler behandeln
            }
    }

Nachdem der Treiber beim `DriverManager` registriert wurde, können Sie eine `Connection`-Instanz zur Verbindung mit einer bestimmten Datenbank erzeugen, indem Sie `DriverManager.getConnection()` aufrufen:

Beispiel 25.1. Eine Verbindung vom `DriverManager` erhalten

Dieses Beispiel zeigt, wie Sie eine `Connection`-Instanz vom `DriverManager` bekommen können. Es gibt verschiedene Signaturen für die `getConnection()`-Methode. Wie man mit ihnen umgeht, entnehmen Sie bitte der API-Dokumentation, die mit Ihrem JDK mitgeliefert wurde.

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;

        ... try {
                Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb");

                // Verbindung benutzen

               ....
            } catch (SQLException ex) {
                // Fehler behandeln
                System.out.println("SQLException: " + ex.getMessage());
                System.out.println("SQLState: " + ex.getSQLState());
                System.out.println("VendorError: " + ex.getErrorCode());
            }

Sobald eine `Connection` eingerichtet ist, kann sie genutzt werden, um `Statement`- und `PreparedStatement`-Objekte auszuführen und Metadaten über die Datenbank abzurufen. Dies wird in den folgenden Abschnitten erklärt.

##### 25.3.5.1.2. SQL-Anweisungen mit Statement-Objekten ausführen

Mit `Statement`-Objekten können Sie grundlegende SQL-Anfragen ausführen und die Ergebnisse mithilfe der weiter unten beschriebenen Klasse `ResultSet` abrufen.

Um ein `Statement`-Objekt zu erzeugen, rufen Sie die Methode `createStatement()` auf dem `Connection`-Objekt auf, das Sie mit einer der zuvor beschriebenen Methoden `DriverManager.getConnection()` oder `DataSource.getConnection()` erzeugt haben.

Wenn Sie ein `Statement`-Objekt angelegt haben, können Sie eine `SELECT`-Anfrage ausführen, indem Sie `executeQuery(String)` mit der gewünschten SQL-Anweisung aufrufen.

Um Daten in der Datenbank zu aktualisieren, verwenden Sie die Methode `executeUpdate(String SQL)`. Diese liefert die Anzahl der von dem Update betroffenen Zeilen zurück.

Wenn Sie im Voraus noch nicht wissen, ob Ihre SQL-Anweisung ein `SELECT` oder ein `UPDATE`/`INSERT` wird, können Sie die Methode `execute(String SQL)` verwenden. Sie gibt true zurück, wenn die SQL-Anfrage ein `SELECT` ist, oder false, wenn sie ein `UPDATE`, `INSERT` oder `DELETE` ist. Handelt es sich um ein `SELECT`, so können Sie die Ergebnisse mit der Methode `getResultSet()` abrufen. Für `UPDATE`-, `INSERT`- oder `DELETE`-Anweisungen können Sie die Anzahl der betroffenen Zeilen in Erfahrung bringen, indem Sie `getUpdateCount()` auf dem `Statement`-Objekt aufrufen.

Beispiel 25.2. Mit java.sql.Statement eine `SELECT`-Anfrage ausführen

    // conn sei eine bereits vorhandene JDBC-Verbindung
    Statement stmt = null;
    ResultSet rs = null;

    try {
        stmt = conn.createStatement();
        rs = stmt.executeQuery("SELECT foo FROM bar");

        // oder, wenn Sie im Voraus nicht wissen, ob die
        // Anfrage ein SELECT ist...

        if (stmt.execute("SELECT foo FROM bar")) {
            rs = stmt.getResultSet();
        }

        // Tue etwas mit dem ResultSet ....
    } finally {
        // Ressourcen sollten immer in einem
        // finally{}-Block
        // in der umgekehrten Reihenfolge ihrer Zuweisung
        // freigegeben werden

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException sqlEx) { // ignore }

            rs = null;
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException sqlEx) { // ignore }

            stmt = null;
        }
    }

##### 25.3.5.1.3. Gespeicherte Prozeduren mit `CallableStatements` ausführen

Seit der MySQL-Server-Version 5.0 in Verbindung mit Connector/J 3.1.1 oder höher ist die Schnittstelle `java.sql.CallableStatement` mit Ausnahme der Methode `getParameterMetaData()` vollständig implementiert.

Mehr über gespeicherte Prozeduren in MySQL erfahren Sie in Kapitel 19, Gespeicherte Prozeduren und Funktionen.

Connector/J stellt Funktionalität für gespeicherte Prozeduren über die JDBC-Schnittstelle `CallableStatement` zur Verfügung.

Hinweis. Aktuelle Versionen von MySQL-Server geben nicht genug Informationen zurück, damit der JDBC-Treiber Ergebnismengen-Metadaten für Callable Statements liefern kann. Folglich wird `ResultSetMetaData` für `CallableStatement` unter Umständen den Wert `NULL` zurückgeben.

Das folgende Beispiel zeigt eine gespeicherte Prozedur, die den Wert von `inOutParam` um 1 inkrementiert und den im `inputParam` übergebenen String als `ResultSet` zurückgibt:

Beispiel 25.3. Gespeicherte Prozeduren

    CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), INOUT inOutParam INT)
    BEGIN
        DECLARE z INT;
        SET z = inOutParam + 1;
        SET inOutParam = z;

        SELECT inputParam;

        SELECT CONCAT('zyxw', inputParam);
    END

Um die Prozedur `demoSp` mit Connector/J einzusetzen, gehen Sie folgendermaßen vor:

1. Sie bereiten das Callable Statement mit `Connection.prepareCall()` vor.

   Beachten Sie, dass Sie die Escape-Syntax von JDBC anwenden müssen, und dass die runden Klammern um die Parameter-Platzhalter obligatorisch sind:

   Beispiel 25.4. Using `Connection.prepareCall()`

       import java.sql.CallableStatement;

       ...

           //
           // Bereite Aufruf der gespeicherten Prozedur 'demoSp'
           // mit zwei Parametern vor
           //
           // Beachten Sie die JDBC-Escape-Syntax ({call ...})
           //

           CallableStatement cStmt = conn.prepareCall("{call demoSp(?, ?)}");

           cStmt.setString(1, "abcdefg");

   Note. `Connection.prepareCall()` ist eine aufwändige Methode, da der Treiber Metadaten abfragen muss, um die Ausgabeparameter zu unterstützen. Aus Performance-Gründen sollten Sie unnötige Aufrufe von `Connection.prepareCall()` vermeiden, indem Sie `CallableStatement`-Objekte in Ihrem Code wiederverwenden.

2. Registrieren Sie die Ausgabeparameter (sofern vorhanden)

   Um die Werte der Ausgabeparameter (Parameter, die Sie beim Anlegen der gespeicherten Prozedur als `OUT` oder `INOUT` gekennzeichnet haben) abrufen zu können, müssen sie in JDBC vor der Ausführung der Anweisung mit einer der diversen `registerOutputParameter()`-Methoden in der Klasse `CallableStatement` registriert worden sein:

   Beispiel 25.5. Registrierung von Ausgabeparametern

       import java.sql.Types;
       ...
       //
       // Connector/J unterstützt benannte und indizierte
       // Ausgabeparameter. Mit beiden Methoden können Sie
       // Ausgabeparameter registrieren oder, unabhängig
       // von der gewählten Registrierungsmethode,
       // auch abrufen.
       //
       // Die folgenden Beispiele zeigen, wie die verschiedenen
       // Registrierungsmethoden für Ausgabeparameter verwendet werden
       // (wobei Sie natürlich nur eine Registrierung
       // pro Parameter verwenden).
       //

       //
       // Registriert den zweiten Parameter als Ausgabe und
       // verwendet den Typ 'INTEGER' für Rückgabewerte von
       // getObject()
       //

       cStmt.registerOutParameter(2, Types.INTEGER);

       //
       // Registriert den benannten Parameter 'inOutParam' und
       // verwendet den Typ 'INTEGER' für Rückgabewerte von
       // getObject()
       //

       cStmt.registerOutParameter("inOutParam", Types.INTEGER);
       ...

3. Stellt die Eingabeparameter ein (sofern vorhanden)

   Eingabe und Ein/Ausgabeparameter werden ebenso gesetzt, wie für `PreparedStatement`-Objekte. Allerdings können `CallableStatement`-Parameter auch namentlich eingestellt werden:

   Beispiel 25.6. Einstellung von `CallableStatement`-Eingabeparametern

       ...

           //
           // Parameter nach Index einstellen
           //

           cStmt.setString(1, "abcdefg");

           //
           // Oder Parameter mit
           // Namen einstellen
           //

           cStmt.setString("inputParameter", "abcdefg");

           //
           // 'in/out'-Parameter nach Index einstellen
           //

           cStmt.setInt(2, 1);

           //
           // Oder 'in/out'-Parameter
           // mit Namen einstellen
           //

           cStmt.setInt("inOutParam", 1);

       ...

4. Führen Sie `CallableStatement` aus und rufen Sie Ergebnismengen oder Ausgabeparameter, sofern vorhanden, ab.

   `CallableStatement` unterstützt zwar alle Ausführungsmethoden von `Statement` (`executeUpdate()`, `executeQuery()` oder `execute()`), aber `execute()` ist am flexibelsten, da Sie mit dieser Methode nicht im Voraus wissen müssen, ob die gespeicherte Prozedur Ergebnismengen unterstützt:

   Beispiel 25.7. Abruf von Ergebnissen und Ausgabeparameterwerten

       ...

           boolean hadResults = cStmt.execute();

           //
           // Alle zurückgelieferten Ergebnismengen verarbeiten
           //

           while (hadResults) {
               ResultSet rs = cStmt.getResultSet();

           // Ergebnismenge verarbeiten
               ...

               hadResults = rs.getMoreResults();
           }

           //
           // Ausgabeparameter abrufen
           //
           // Connector/J unterstützt Abruf sowohl nach Index
           // als auch nach Namen
           //

           int outputValue = rs.getInt(2); // index-based

           outputValue = rs.getInt("inOutParam"); // name-based

       ...

##### 25.3.5.1.4. Abruf von `AUTO_INCREMENT`-Spaltenwerten

Vor der Version 3.0 der JDBC-API gab es kein Standardmittel, um Schlüsselwerte aus Datenbanken zu holen, die „Auto Increment“- oder Identitätsspalte unterstützten. Mit älteren JDBC-Treibern für MySQL konnten Sie immer eine MySQL-spezifische Methode auf der Schnittstelle `Statement` verwenden, oder `SELECT LAST_INSERT_ID()` sagen, wenn Sie eine `INSERT`-Operation auf einer Tabelle mit `AUTO_INCREMENT`-Schlüssel ausgeführt hatten. Doch die MySQL-spezifische Methode ist nicht portierbar und der Abruf der Werte des `AUTO_INCREMENT`-Schlüssels mit `SELECT` macht einen zusätzlichen Datenbankzugriff erforderlich, ist also nicht die effizienteste Methode. Die folgenden Codestücke zeigen die drei unterschiedlichen Möglichkeiten zum Abruf von `AUTO_INCREMENT`-Werten. Zuerst zeigen wir, wie die neue JDBC-3.0-Methode `getGeneratedKeys()` benutzt wird, die jetzt die Methode der Wahl ist, wenn Sie `AUTO_INCREMENT`-Schlüssel abfragen müssen und Zugang zu JDBC-3.0 haben. Das zweite Beispiel zeigt, wie Sie denselben Wert mit einer standardmäßigen `SELECT LAST_INSERT_ID()`-Anfrage abholen können. Das letzte Beispiel zeigt, wie aktualisierbare Ergebnismengen den `AUTO_INCREMENT`-Wert abrufen können, wenn die Methode `insertRow()` verwendet wurde.

Beispiel 25.8. `AUTO_INCREMENT`-Spaltenwerte mit `Statement.getGeneratedKeys()` abrufen

       Statement stmt = null;
       ResultSet rs = null;

       try {

        //
        // Erzeugt ein Statement-Objekt, das wir für
        // 'normale' Ergebnismengen verwenden können.
        // Die 'conn'-Verbindung zu einer MySQL-Datenbank
        // sei bereits vorhanden.

        stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                                    java.sql.ResultSet.CONCUR_UPDATABLE);

        //
        // DDL-Anfragen für dieses Beispiel
        //

        stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
        stmt.executeUpdate(
                "CREATE TABLE autoIncTutorial ("
                + "priKey INT NOT NULL AUTO_INCREMENT, "
                + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

        //
        // Fügt eine Zeile ein, die einen AUTO INCREMENT-Schlüssel im
        // Feld 'priKey' generiert
        //

        stmt.executeUpdate(
                "INSERT INTO autoIncTutorial (dataField) "
                + "values ('Can I Get the Auto Increment Field?')",
                Statement.RETURN_GENERATED_KEYS);

        //
        // So kann man den Wert einer Auto-Increment-Spalte mit
        // Statement.getGeneratedKeys() abholen
        //

        int autoIncKeyFromApi = -1;

        rs = stmt.getGeneratedKeys();

        if (rs.next()) {
            autoIncKeyFromApi = rs.getInt(1);
        } else {

        // hier Ausnahme auslösen
        }

        rs.close();

        rs = null;

        System.out.println("Key returned from getGeneratedKeys():"
            + autoIncKeyFromApi);
    } finally {

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException ex) {
                // ignorieren
            }
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException ex) {
                // ignorieren
            }
        }
    }

Beispiel 25.9. Abruf von `AUTO_INCREMENT`-Spaltenwerten mit `SELECT LAST_INSERT_ID()`

       Statement stmt = null;
       ResultSet rs = null;

       try {

        //
        // Erzeugt ein Statement-Objekt, das wir für
        // 'normale' Ergebnismengen benutzen können.

        stmt = conn.createStatement();

        //
        // DDL-Anfragen für dieses Beispiel
        //

        stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
        stmt.executeUpdate(
                "CREATE TABLE autoIncTutorial ("
                + "priKey INT NOT NULL AUTO_INCREMENT, "
                + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

        //
        // Fügt eine Zeile ein, die einen AUTO INCREMENT-Schlüssel im Feld
        // 'priKey' generiert
        //

        stmt.executeUpdate(
                "INSERT INTO autoIncTutorial (dataField) "
                + "values ('Can I Get the Auto Increment Field?')");

        //
        // Verwendet die Funktion MySQL LAST_INSERT_ID(),
        // um dasselbe wie getGeneratedKeys() zu tun
        //

        int autoIncKeyFromFunc = -1;
        rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");

        if (rs.next()) {
            autoIncKeyFromFunc = rs.getInt(1);
        } else {
            // hier Ausnahme auslösen
        }

        rs.close();

        System.out.println("Key returned from " + "'SELECT LAST_INSERT_ID()': "
            + autoIncKeyFromFunc);

    } finally {

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException ex) {
                // ignorieren
            }
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException ex) {
                // ignorieren
            }
        }
    }

Beispiel 25.10. Retrieving `AUTO_INCREMENT` column values in `Updatable ResultSets`

       Statement stmt = null;
       ResultSet rs = null;

       try {

        //
        // Erzeugt ein Statement-Objekt, das wir für
        // 'normale' ebenso wie für 'aktualisierbare' Ergebnismengen verwenden können.
        // Die 'conn''-Verbindung zu
        // einer MySQL-Datenbank sei bereits vorhanden
        //

        stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                                    java.sql.ResultSet.CONCUR_UPDATABLE);

        //
        // DDL-Anfragen für dieses Beispiel
        //

        stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
        stmt.executeUpdate(
                "CREATE TABLE autoIncTutorial ("
                + "priKey INT NOT NULL AUTO_INCREMENT, "
                + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

        //
        // So wird ein AUTO INCREMENT-Schlüssel von einer
        // aktualisierbaren Ergebnismenge abgerufen
        //

        rs = stmt.executeQuery("SELECT priKey, dataField "
           + "FROM autoIncTutorial");

        rs.moveToInsertRow();

        rs.updateString("dataField", "AUTO INCREMENT here?");
        rs.insertRow();

        //
        // Der Treiber fügt die Zeilen am Ende hinzu
        //

        rs.last();

        //
        // Jetzt müsste die zuvor eingefügte Zeile erreicht sein
        //

        int autoIncKeyFromRS = rs.getInt("priKey");

        rs.close();

        rs = null;

        System.out.println("Key returned for inserted row: "
            + autoIncKeyFromRS);

    } finally {

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException ex) {
                // ignorieren
            }
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException ex) {
                // ignorieren
            }
        }
    }

Wenn Sie den Code des obigen Beispiels ausführen, müsste folgende Ausgabe erscheinen: Key returned from `getGeneratedKeys()`: 1 Key returned from `SELECT LAST_INSERT_ID()`: 1 Key returned for inserted row: 2 Bitte denken Sie daran, dass die Verwendung der Anfrage `SELECT LAST_INSERT_ID()` gelegentlich knifflig sein kann, da der Wert dieser Funktion als Geltungsbereich die Verbindung hat. Wenn also eine andere Anfrage auf derselben Verbindung ausgeführt wird, wird der Wert überschrieben. Dagegen hat die Methode `getGeneratedKeys()` das `Statement`-Objekt als Geltungsbereich und kann daher zwar genutzt werden, wenn andere Anfragen auf derselben Verbindung ausgeführt werden, aber nicht, wenn die Anfragen auf dem `Statement`-Objekt ausgeführt werden.

#### 25.3.5.2. Connector/J mit J2EE und anderen Java-Frameworks einsetzen

In diesem Abschnitt wird beschrieben, wie Sie Connector/J in in unterschiedlichen Zusammenhängen einsetzen können.

##### 25.3.5.2.1. Grundkonzepte von J2EE

Dieser Abschnitt vermittelt einige Grundkonzepte von J2EE, die für die Arbeit mit Connector/J von Bedeutung sind.

###### 25.3.5.2.1.1. Verbindungspooling

Verbindungspooling ist eine Technik, die darin besteht, einen Pool von Verbindungen aufzubauen und zu verwalten, damit diese für Threads, die sie benötigen, bereits zur Verfügung stehen.

Diese Technik beruht auf der Tatsache, dass die meisten Anwendungen nur dann Thread-Zugriff auf eine JDBC-Verbindung benötigen, wenn sie gerade aktiv eine Transaktion abwickeln, die in wenigen Millisekunden fertig ist. Wenn nicht gerade eine Transaktion verarbeitet wird, würde die Verbindung normalerweise untätig herumsitzen. In einem Verbindungspool kann sie dagegen von anderen Threads sinnvoll eingesetzt werden.

In der Praxis sieht das so aus: Wenn ein Thread auf MySQL oder eine andere Datenbank mit JDBC zugreifen muss, fordert er eine Verbindung aus dem Pool an. Hat er seine Arbeit auf der Verbindung beendet, gibt er sie an den Pool zurück, damit andere Threads sie wiederverwenden können.

Eine Verbindung, die aus dem Pool entliehen wurde, wird ausschließlich von dem Thread benutzt, der sie angefordert hatte. Aus Sicht der Programmierung ist dies dasselbe, als riefe der Thread jedesmal, wenn ein eine JDBC-Verbindung benötigt, `DriverManager.getConnection()` auf. Beim Verbindungspooling kann er allerdings am Ende entweder eine neue oder eine bereits vorhandene Verbindung erwerben.

Verbindungspooling kann die Performance einer Java-Anwendung deutlich verbessern, da weniger Ressourcen verbraucht werden. Die Hauptvorteile des Verbindungspoolings sind:

- Schnellerer Verbindungsaufbau

  MySQL baut zwar im Vergleich zu anderen Datenbanken ohnehin Verbindungen sehr schnell auf, aber dennoch steigt bei der Aufnahme neuer JDBC-Verbindungen immer noch die Belastung für Netzwerk und JDBC-Treiber. Diese Belastung wird durch die Wiederverwendung von Verbindungen vermieden.

- Einfacheres Programmiermodell

  Durch das Verbindungspooling kann sich jeder einzelne Thread verhalten, als hätte er eine eigene JDBC-Verbindung. So können Sie ganz einfache JDBC-Programmiertechniken verwenden.

- Bessere Kontrolle über den Ressourcenverbrauch

  Wenn Sie auf Verbindungspooling verzichten und stattdessen jedesmal eine neue Verbindung öffnen, wenn ein Thread eine braucht, wird Ihre Anwendung unter Umständen viele Ressourcen unnötig belegen. Bei besonderer Belastung kann dies zu unvorhersehbarem Verhalten führen.

Bedenken Sie, dass jede Verbindung zu MySQL einen Aufwand bedeutet (für Arbeitsspeicher, CPU, Kontextumschaltungen usw.), und dies sowohl auf der Client- als auch auf der Serverseite. Mit jeder weiteren Verbindung schrumpfen die Ressourcen, die Ihrer Anwendung und dem MySQL-Server noch zur Verfügung stehen. Viele dieser Ressourcen werden ganz unabhängig davon belegt, ob die Verbindung gerade etwas Nützliches leistet oder nicht!

Verbindungspools können so getunt werden, dass die Performance möglichst gut ist, während gleichtzeitig die Ressourcenauslastung immer unter dem Niveau gehalten wird, ab dem die Anwendung nicht nur langsamer läuft, sondern sogar abstürzen kann.

Zum Glück hat Sun das Verbindungspooling in JDBC in den JDBC-2.0 Optional-Schnittstellen standardisiert, und alle wichtigen Anwendungsserver verfügen über Implementierungen dieser APIs, die mit MySQL Connector/J gut harmonieren.

Generell richten Sie den Verbindungspool in den Konfigurationsdateien Ihres Anwendungsservers ein und greifen über das Java Naming and Directory Interface (JNDI) darauf zu. Der folgende Code zeigt, wie ein Verbindungspool mit einer Anwendung auf einem J2EE-Anwendungsserver genutzt werden könnte:

Beispiel 25.11. Verwendung eines Verbindungspools mit einem J2EE-Anwendungsserver

    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.Statement;

    import javax.naming.InitialContext;
    import javax.sql.DataSource;

    public class MyServletJspOrEjb {

        public void doSomething() throws Exception {
            /*
             * JNDI Initial-Kontext erstellen, um die
             *  DataSource nachschlagen zu können
             *
             * In Produktionscode sollte dieser als Objekt oder statische Variable
             * gespeichert werden, da die Erstellung eines
             * JNDI-Kontexts sehr aufwändig sein kann.
             *
             * Hinweis: Der Code funktioniert nur, wenn Sie Servlets
             * oder EJBs in einem J2EE-Anwendungsserver verwenden. Nutzen Sie
             * Verbindungspooling in Standalone-Java-Code, so
             * müssen sie die Datenquellen mit den Mitteln erstellen/konfigurieren,
             * die Ihre jeweilige Bibliothek für Verbindungspooling
             * zur Verfügung stellt.
             */

            InitialContext ctx = new InitialContext();

             /*
              * Nachschlageoperation auf der DataSource mit einem vom Anwendungsserver
              * bereitgestellten Pool im Rücken. DataSource-Objekte sollten ebenfalls
              * als Instanzvariablen zwischengespeichert werden,
              * da auch JNDI-Lookups aufwändig sind.
              */

            DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/MySQLDB");

            /*
             * Der folgende Code würde eigentlich in die 'service'-Methode Ihres
             * Servlets, JSPs oder EJBs gehören, dorthin, wo
             * sie mit einer JDBC-Verbindung arbeiten müssen.
             */

            Connection conn = null;
            Statement stmt = null;

            try {
                conn = ds.getConnection();

                /*
                 * Die weitere Arbeit mit MySQL wird mit normaler JDBC-Programmierung
                 * erledigt. Schließen sie jede Ressource, wenn Sie sie nicht mehr benötigen,
                 * damit die Verbindungspool-Ressourcen so rasch wie möglich
                 * wiederhergestellt werden
                 */

                stmt = conn.createStatement();
                stmt.execute("SOME SQL QUERY");

                stmt.close();
                stmt = null;

                conn.close();
                conn = null;
            } finally {
                /*
                 * Hier werden jdbc-Objekte abgeschlossen, die im normalen
                 * Code nicht explizit geschlossen worden sind. So
                 * entstehen keine Ressourcen-'Lecks'...
                 */

                if (stmt != null) {
                    try {
                        stmt.close();
                    } catch (sqlexception sqlex) {
                        // ignorieren -- da wir hier sowieso nichts daran tun können
                    }

                    stmt = null;
                }

                if (conn != null) {
                    try {
                        conn.close();
                    } catch (sqlexception sqlex) {
                         // ignorieren -- da wir hier sowieso nichts daran tun können
                    }

                    conn = null;
                }
            }
        }
    }

Wie das obige Beispiel zeigt, sieht der Rest des Codes, nachdem Sie den JNDI-InitialContext beschafft und die DataSource nachgeschlagen haben, für erfahrene JDBC-Programmierer schon vertrauter aus.

Das Wichtigste, was Sie sich merken müssen, wenn Sie mit Verbindungspooling arbeiten: Egal was in Ihrem Code passiert (Ausnahmen, Kontrollfluss usw.), sorgen Sie immer dafür, dass Verbindungen und alles, was mit ihnen angelegt wurde (Anweisungen, Ergebnismengen usw.) immer geschlossen werden. Sonst können sie nicht wiederverwendet werden und verlaufen im Sande. Im besten Fall bedeutet dies, dass die von ihnen belegten MySQL-Server-Ressourcen (Puffer, Sperren oder Sockets) für einige Zeit wegfallen, aber im schlimmsten Fall gehen sie für immer verloren.

Was ist die optimale Größe für meinen Verbindungspool?

Wie bei anderen Konfigurations-Faustregeln lautet auch hier die Antwort: Kommt drauf an. Zwar hängt die optimale Größe von der erwarteten Last und durchschnittlichen Datenbanktransaktionsdauer ab, aber die beste Größe für einen Verbindungspool kann kleiner sein als Sie erwarten. Wenn man die Java Petstore Blueprint-Anwendung von Sun als Beispiel nimmt, kann ein Pool von 15-20 Verbindungen für eine mäßige Last (600 Benutzer gleichzeitig) ausreichen. Mit MySQL und Tomcat wären die Reaktionszeiten in einem solchen Szenario annehmbar.

Um einen Verbindungspool für Ihre Anwendung angemessen zu dimensionieren, sollten Sie Belastungstestskripten mit Apache JMeter oder The Grinder erstellen und ausprobieren, wie sich Ihre Anwendung unter Last verhält.

Am einfachsten beginnen Sie wie folgt: Stellen Sie die Höchstzahl von Verbindungen für Ihren Pool auf unbegrenzt ein, lassen Sie einen Belastungstest laufen, und messen Sie, wie viele nebenläufige Verbindungen maximal gebraucht wurden. Von dort aus gehen sie einen Schritt zurück und schauen nach, welche Mindest- und Höchstzahlen an Pool-Verbindungen die beste Performance für Ihre Anwendung ergeben.

##### 25.3.5.2.2. Verwendung von Connector/J mit Tomcat

Die folgenden Hinweise beruhen auf den Anleitungen für Tomcat-5.x in http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html Dies ist zum Zeitpunkt der Erstellung dieses Dokuments die aktuelle Version.

Zuerst installieren Sie die mit Connector/J mitgelieferte .jar-Datei in `$CATALINA_HOME/common/lib`, sodass sie allen in dem Container installierten Anwendungen zur Verfügung steht.

Nun konfigurieren Sie die JNDI-DataSource, indem Sie `$CATALINA_HOME/conf/server.xml` in dem Kontext, der Ihre Webanwendung definiert, eine Ressourcendeklaration hinzufügen:

    <Context ....>

      ...

      <Resource name="jdbc/MySQLDB"
                   auth="Container"
                   type="javax.sql.DataSource"/>

      <!-- Muss _genau_  mit dem oben verwendeten Namen übereinstimmen!

           Der Verbindungspool wird mit dem Namen
           "java:/comp/env/jdbc/MySQLDB" in JNDI eingebunden
      -->

      <ResourceParams name="jdbc/MySQLDB">
        <parameter>
          <name>factory</name>
          <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
        </parameter>

        <!-- Stellen Sie diesen Wert nicht höher als max_connections auf Ihrem
             MySQL-Server ein. Normalerweise sollte er 10 oder einige Dutzend
             Verbindungen vorsehen, nicht hunderte oder tausende -->

        <parameter>
          <name>maxActive</name>
          <value>10</value>
        </parameter>

        <!-- Sie möchten nicht zu viele untätige Verbindungen unnötig offen lassen,
             nur ein paar, um mögliche Belastungsspitzen zu
             absorbieren -->

        <parameter>
          <name>maxIdle</name>
          <value>5</value>
        </parameter>

        <!-- Bitte verwenden Sie nicht autoReconnect=true, erstens wird es irgendwann abgeschafft
             und zweitens ist es ein Kreuz für ältere Verbindungspools, die
             keine Verbindungen testen konnten. Sie müssen entscheiden, ob Ihre Verbindung
             SQLExceptions beherrschen soll (Hinweis: das sollte sie!)  und wie viel
             Leistungseinbußen Sie hinnehmen wollen, um zu gewährleisten, dass
             die Verbindung "frisch" ist -->

        <parameter>
          <name>validationQuery</name>
          <value>SELECT 1</value>
        </parameter>

       <!-- Der konservativste Ansatz ist: Testen Sie Verbindungen, bevor
            Ihre Anwendung sie bekommt. Für die meisten Anwendungen ist das gut,
            außerdem ist die obige Anfrage ganz klein und belegt kaum Serverressourcen,
            abgesehen von der Zeit, die es braucht,
            sie im Netzwerk zu übermitteln.

            Wenn Sie eine Hochlast-Anwendung haben, werden Sie
            eine andere Lösung suchen müssen. -->

        <parameter>
          <name>testOnBorrow</name>
          <value>true</value>
        </parameter>

       <!-- Ansonsten, oder zusätzlich zu testOnBorrow, können Sie testen,
            während die Verbindung untätig ist  -->

        <parameter>
          <name>testWhileIdle</name>
          <value>true</value>
        </parameter>

        <!-- Diesen Wert müssen Sie einstellen, sonst wird
              der Idle-Evicter-Thread nie ausgeführt, selbst wenn Sie
             veranlasst haben, dass untätige Verbindungen getestet werden -->

        <parameter>
          <name>timeBetweenEvictionRunsMillis</name>
          <value>10000</value>
        </parameter>

        <!-- Verbindungen sollten nie zu lange untätig herumsitzen,
             jedenfalls nicht länger als wait_timeout in der Serverkonfiguration.
             Einige Minuten oder Minutenbruchteile sind hier
             manchmal akzeptabel, es hängt von Ihrer Anwendung
             und den Belastungsspitzen ab -->

        <parameter>
          <name>minEvictableIdleTimeMillis</name>
          <value>60000</value>
        </parameter>

        <!-- Benutzername und Passwort für die MySQL-Verbindung -->

        <parameter>
         <name>username</name>
         <value>someuser</value>
        </parameter>

        <parameter>
         <name>password</name>
         <value>somepass</value>
        </parameter>

        <!-- Klassenname für den Connector/J-Treiber -->

        <parameter>
           <name>driverClassName</name>
           <value>com.mysql.jdbc.Driver</value>
        </parameter>

        <!-- Der JDBC-Verbindungs-URL für MySQL. Wenn Sie andere
             MySQL-spezifische Parameter üübergeben möchten, müssen Sie
             dies hier im URL tun. Sie in den obigen Parameter-Tags
             einzustellen, hätte keine Wirkung. Außerdem müssen Sie
             &amp; als Trennzeichen zwischen die Parameterwerte setzen, da das
             Ampersand in XML ein reserviertes Zeichen ist. -->

        <parameter>
          <name>url</name>
          <value>jdbc:mysql://localhost:3306/test</value>
        </parameter>

      </ResourceParams>
    </Context>

Generell sollten Sie die Installationsanleitung zu Ihrer Tomcat-Version befolgen, da sich die Datenquellenkonfiguration in Tomcat von Zeit zu Zeit ändert. Leider wird, wenn Sie in Ihrer XML-Datei die verkehrte Syntax verwenden, eine Ausnahme wie diese angezeigt:

    Error: java.sql.SQLException: Cannot load JDBC driver class 'null ' SQL
    state: null

##### 25.3.5.2.3. Verwendung von Connector/J mit JBoss

Die folgenden Anleitungen beziehen sich auf JBoss-4.x. Um die Klassen des JDBC-Teibers dem Anwendungsserver zur Verfügung zu stellen, kopieren Sie die .jar-Datei von Connector/J in das `lib`-Verzeichnis für Ihre Server-Konfiguration (normalerweise heißt es `default`). Dann legen Sie in demselben Konfigurationsverzeichnis in einem Unterverzeichnis namens `deploy` eine Datenquellenkonfigurationsdatei an, die mit "-ds.xml" endet. Diese veranlasst JBoss, die betreffende Datei als JDBC-Datasource einzusetzen. Die Datei sollte folgendes enthalten:

    <datasources>
        <local-tx-datasource>
            <!-- Dieser Verbindungspool wird in JNDI unter dem Namen
                 "java:/MySQLDB" eingebunden -->

            <jndi-name>MySQLDB</jndi-name>
            <connection-url>jdbc:mysql://localhost:3306/dbname</connection-url>
            <driver-class>com.mysql.jdbc.Driver</driver-class>
            <user-name>user</user-name>
            <password>pass</password>

            <min-pool-size>5</min-pool-size>

              <!--  Stellen Sie diesen Wert nicht höher als max_connections auf Ihrem
              MySQL-Server ein. Normalerweise sollte er 10 oder einige Dutzend
              Verbindungen vorsehen, nicht hunderte oder tausende -->

            <max-pool-size>20</max-pool-size>

              <!-- Verbindungen sollten nie zu lange untätig herumsitzen,
              jedenfalls nicht länger als wait_timeout in der Serverkonfiguration.
              Einige Minuten oder Minutenbruchteile sind hier
              manchmal akzeptabel, es hängt von Ihrer Anwendung
              und den Belastungsspitzen ab -->

            <idle-timeout-minutes>5</idle-timeout-minutes>

            <!-- Wenn Sie Connector/J 3.1.8 oder höher benutzen, können Sie
                 unsere Implementierung verwenden, um die Stabilität
                 des Verbindungspools zu erhöhen. -->

            <exception-sorter-class-name>com.mysql.jdbc.integration.jboss.ExtendedMysqlExceptionSorter</exception-sorter-class-name>
            <valid-connection-checker-class-name>com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker</valid-connection-checker-class-name>

        </local-tx-datasource>
    </datasources>

#### 25.3.5.3. Häufige Probleme und Lösungen

Einige Probleme treten öfters mit MySQL Connector/J auf. Dieser Abschnitt beschreibt die Symtome und ihre Heilung.

Questions

- 26.3.5.3.1: Wenn ich mit MySQL Connector/J eine Datenbankverbindung aufbaue, wird folgende Ausnahme ausgelöst:

      SQLException: Server configuration denies access to data source
      SQLState: 08001
      VendorError: 0

  Was ist da los? Mit dem Kommandozeilen-Client von MySQL funktioniert die Verbindung einwandfrei.

- 26.3.5.3.2: Meine Anwendung löst die SQLException 'No Suitable Driver' aus. Warum?

- 26.3.5.3.3: Ich versuche, MySQL Connector/J in einem Applet oder einer Anwendung einzusetzen und bekomme einen Fehler wie diesen gemeldet:

      SQLException: Cannot connect to MySQL server on host:3306.
      Is there a MySQL server running on the machine/port you
      are trying to connect to?

      (java.security.AccessControlException)
      SQLState: 08S01
      VendorError: 0

- 26.3.5.3.4: Ich habe ein Servlet/Programm, das es einen Tag lang tut und dann über Nacht nicht mehr funktioniert

- 26.3.5.3.5: Ich versuche, aktualisierbare Ergebnismengen von JDBC-2.0 einzusetzen, und eine Fehlermeldung behauptet, meine Ergebnismenge sei gar nicht aktualisierbar.

Questions and Answers

26.3.5.3.1: Wenn ich mit MySQL Connector/J eine Datenbankverbindung aufbaue, wird folgende Ausnahme ausgelöst:

    SQLException: Server configuration denies access to data source
    SQLState: 08001
    VendorError: 0

Was ist da los? Mit dem Kommandozeilen-Client von MySQL funktioniert die Verbindung einwandfrei.

MySQL Connector/J muss für die Verbindung mit MySQL TCP/IP-Sockets einsetzen, da Java keine Unix Domain Sockets unterstützt. Der Sicherheitsmanager von MySQL schaut deshalb bei einem Verbindungsversuch mit MySQL Connector/J in seine Berechtigungstabellen, um festzustellen, ob die Verbindung zulässig ist.

Damit das funktionieren kann, müssen Sie dem MySQL-Server mithilfe der `GRANT` Anweisung die notwendigen Sicherheitszeugnisse vorweisen. Weitere Informationen siehe Abschnitt 13.5.1.3, „`GRANT` und `REVOKE`“.

Hinweis. Ein Verbindungstest mit dem Kommandozeilenclient mysql funktioniert nur, wenn Sie das Flag `--host` hinzufügen und als Host etwas anderes als `localhost` einsetzen. Der Kommandozeilenclient mysql wird Unix-Domain-Sockets verwenden, wen Sie den speziellen Hostnamen `localhost` benutzen. Um die Verbindung mit `localhost` zu testen, müssen Sie stattdessen `127.0.0.1` als Hostnamen einsetzen.

Warnung. Wenn Sie bei der Änderungen von Berechtigungen in MySQL Fehler machen, kann dies dazu führen, dass Ihre Serverinstallation keine optimalen Sicherheitseigenschaften mehr hat.

26.3.5.3.2: Meine Anwendung löst die SQLException 'No Suitable Driver' aus. Warum?

Für diesen Fehler gibt es drei mögliche Gründe:

- Der Connector/J-Treiber liegt nicht in Ihrem `CLASSPATH`, siehe auch Abschnitt 25.3.2, „Installation von Connector/J“.

- Der Verbindungs URL hat ein falsches Format oder Sie referenzieren den verkehrten JDBC-Treiber.

- Die Systemeigenschaft `jdbc.drivers` wurde bei Benutzung des DriverManager nicht auf das Verzeichnis des Connector/J-Treibers eingestellt.

26.3.5.3.3: Ich versuche, MySQL Connector/J in einem Applet oder einer Anwendung einzusetzen und bekomme einen Fehler wie diesen gemeldet:

    SQLException: Cannot connect to MySQL server on host:3306.
    Is there a MySQL server running on the machine/port you
    are trying to connect to?

    (java.security.AccessControlException)
    SQLState: 08S01
    VendorError: 0

Entweder führen Sie ein Applet aus, oder Ihr MySQL-Server wurde mit der Option "--skip-networking" installiert, oder Ihr MySQL-Server sitzt hinter einer Firewall.

Applets können Netzwerkverbindungen nur mit dem Computer aufnehmen, auf den der Webserver läuft, der die .class-Dateien des Applets liefert. Das bedeutet, dass MySQL ebenfalls auf demselben Computer laufen muss (es sei denn, Sie verwenden irgendeine Art von Port-Umleitung). Außerdem bedeutet es, dass Sie Applets nicht in Ihrem lokalen Dateisystem testen können, sondern immer erst auf einem Webserver installieren müssen.

MySQL Connector/J kann mit MySQL nur über TCP/IP kommunizieren, da Java keine Unix-Domain-Sockets unterstützt. Die TCP/IP-Kommunikation mit MySQL kann jedoch in Mitleidenschaft gezogen werden, wenn MySQL mit der Option "--skip-networking" gestartet wurde oder hinter einer Firewall sitzt.

Wenn MySQL mit der Option "--skip-networking" gestartet wurde (dies tut beispielsweise das Debian Linux-Package von MySQL Server), müssen Sie dies in der Datei /etc/mysql/my.cnf or /etc/my.cnf auskommentieren. Natürlich kann Ihre my.cnf-Datei auch im `data`-Verzeichnis Ihres MySQL-Servers oder irgendwo sonst liegen (je nachdem, wie MySQL für Ihr System kompiliert wurde). Binärversionen von MySQL AB schauen immer in /etc/my.cnf and [datadir]/my.cnf. Wenn Ihr MySQL-Server durch eine Firewall geschützt ist, müssen Sie diese so konfigurieren, dass sie TCP/IP-Verbindungen von dem Host, auf dem der Java-Code läuft, zu dem MySQL-Server auf dem Port zulässt, auf den MySQL lauscht (nach Voreinstellung 3306).

26.3.5.3.4: Ich habe ein Servlet/Programm, das es einen Tag lang tut und dann über Nacht nicht mehr funktioniert

MySQL schließt Verbindungen, die 8 Stunden lang inaktiv waren. Sie müssen entweder einen Verbindungspool, der alte Verbindungen behandelt, oder den "autoReconnect"-Parameter verwenden (siehe Abschnitt 25.3.4.1, „Driver/Datasource-Klassennamen, URL-Syntax und Konfigurationseigenschaften für Connector/J“).

Außerdem sollten Sie SQLExceptions in Ihrer Anwendung abfangen und behandeln, anstatt sie immer weiter durchzureichen, bis Ihre Anwendung abbricht; schon allein weil es guter Stil ist. MySQL Connector/J stellt den SQLState (siehe `java.sql.SQLException.getSQLState()` in Ihren APIDOCS) auf "08S01" ein, wenn es während der Verarbeitung einer Anfrage Netzwerkprobleme bekommt. Ihr Anwendungscode sollte dann versuchen, sich erneut mit MySQL zu verbinden.

Das folgende (vereinfachte) Beispiel zeigt, mit welchem Code man solche Ausnahmen behandeln könnte:

Beispiel 25.12. Beispiel einer Transaktion mit Retry-Logik

    public void doBusinessOp() throws SQLException {
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;

            //
            // Wie oft wollen Sie die Transaktion erneut versuchen
            // (oder wenigstens eine Verbindung zu bekommen)?
            //
            int retryCount = 5;

            boolean transactionCompleted = false;

            do {
                try {
                    conn = getConnection(); // wir setzen voraus, dass diese von einer
                                            // javax.sql.DataSource oder dem
                                            // java.sql.DriverManager geliefert wird

                    conn.setAutoCommit(false);

                    //
                    // An diesem Punkt hängt die 'Retry-Fähigkeit' der
                    // Transaktion von Ihrer Anwendungslogik ab und davon
                    // ob Sie Autocommit verwenden (in diesem Fall nicht)
                    // und ob Sie transaktionssichere Speicher-Engines
                    // einsetzen
                    //
                    // Für dieses Beispiel gehen wir davon aus, das es _nicht_ sicher ist,
                    // die gesamte Transaktion erneut zu versuchen, und setzen daher
                    // die Retry-Zahl auf 0
                    //
                    // Wenn Sie nur transaktionssichere Tabellen verwenden oder
                    // Ihre Anwendung sich davon erholen könnte, wenn eine Verbindung
                    // mitten in der Operation abstürzt, dann würden Sie hier am
                    // 'retryCount' nichts ändern und die Schleife einfach so lange durchlaufen,
                    // bis retryCount == 0.
                    //
                    retryCount = 0;

                    stmt = conn.createStatement();

                    String query = "SELECT foo FROM bar ORDER BY baz";

                    rs = stmt.executeQuery(query);

                    while (rs.next()) {
                    }

                    rs.close();
                    rs = null;

                    stmt.close();
                    stmt = null;

                    conn.commit();
                    conn.close();
                    conn = null;

                    transactionCompleted = true;
                } catch (SQLException sqlEx) {

                    //
                    // Die beiden 'Retry-fähigen' SQL-Zustände sind 08S01
                    // für einen Kommunikationsfehler und 40001 für Deadlock.
                    //
                    // Retry nur dann, wenn der Fehler wegen einer alten Verbindung,
                    // Kommunikationsproblemen oder einem Deadlock auftrat
                    //

                    String sqlState = sqlEx.getSQLState();

                    if ("08S01".equals(sqlState) || "40001".equals(sqlState)) {
                        retryCount--;
                    } else {
                        retryCount = 0;
                    }
                } finally {
                    if (rs != null) {
                        try {
                            rs.close();
                        } catch (SQLException sqlEx) {
                            // Das gehört ins Log. . .
                        }
                    }

                    if (stmt != null) {
                        try {
                            stmt.close();
                        } catch (SQLException sqlEx) {
                            // Das gehört ebenfalls ins Log. . .
                        }
                    }

                    if (conn != null) {
                        try {
                            //
                            // Wenn hier conn nicht Null ist, sollte die
                            // Transaktion zurückgerollt werden, da noch
                            // nicht alle Arbeit erledigt ist

                            try {
                                conn.rollback();
                            } finally {
                                conn.close();
                            }
                        } catch (SQLException sqlEx) {
                            //
                            // Wenn hier eine Ausnahme auftritt, ist es ernst.
                            // Daher reichen wir sie besser im
                            // Stapel nach oben anstatt sie nur
                            // zu protokollieren . . .

                            throw sqlEx;
                        }
                    }
                }
            } while (!transactionCompleted && (retryCount > 0));
        }

Hinweis. Die Option `autoReconnect` wird nicht empfohlen, da es keine sichere Methode einer Neuverbindung mit dem MySQL-Server ohne das Risiko von Schäden am Verbindungszustand oder den Datenbankzustandsinformationen gibt. Nutzen Sie stattdessen einen Verbindungspool, der Ihre Anwendung in die Lage versetzt, eine verfügbare Verbindung aus dem Pool zur Kontaktaufnahme mit dem MySQL-Server zu benutzen. Die `autoReconnect`-Facility ist veraltet und wird in einem zukünftigen Release wahrscheinlich abgeschafft werden.

26.3.5.3.5: Ich versuche, aktualisierbare Ergebnismengen von JDBC-2.0 einzusetzen, und eine Fehlermeldung behauptet, meine Ergebnismenge sei gar nicht aktualisierbar.

Da MySQL keine Zeilenbezeichner kennt, kann MySQL Connector/J Ergebnismengen nur dann aktualsieren, wenn sie von Anfragen auf Tabellen herrühren, die mindestens einen Primärschlüssel haben. Außerdem muss die Anfrage jeden Primärschlüssel auswählen und darf sich nur auf eine einzige Tabelle beziehen (also keine Joins). Dies ist in der JDBC-Spezifikation festgelegt.

### 25.3.6. Support für Connector/J

#### 25.3.6.1. Support von der Connector/J-Community

MySQL AB bietet der Benutzercommunity Unterstützung über Mailinglisten an. Bei Problemen mit Connector/J können Sie sich in der MySQL- und Java-Mailingliste Hilfe von erfahrenen Benutzern holen. Archive und Abonnementsinformationen stehen online unter http://lists.mysql.com/java zur Verfügung.

Wie Sie MySQL-Mailinglisten abonnieren oder die Listenarchive durchsuchen können, erfahren Sie unter http://lists.mysql.com/. Siehe Abschnitt 1.7.1, „Die MySQL-Mailinglisten“.

Community-Support von erfahrenen Benutzern erhalten Sie auch im JDBC Forum. Auch in den anderen MySQL-Foren unter http://forums.mysql.com wird Ihnen geholfen. Siehe auch Abschnitt 1.7.2, „MySQL-Community-Support in den MySQL-Foren“.

#### 25.3.6.2. Probleme und Fehler von Connector/J melden

Normalerweise melden Sie Bugs bei http://bugs.mysql.com/, unserer Fehlerdatenbank. Diese Datenbank ist öffentlich; jeder kann in ihr stöbern oder suchen. Wenn Sie sich beim System anmelden, können Sie auch neue Bugreports übermitteln.

Wenn Sie einen Sicherheitsbug in MySQL gefunden haben, schicken Sie eine E-Mail an security_at_mysql.com.

Zum Schreiben eines guten Bugreports gehört Geduld, doch wenn Sie es von Anfang an richtig machen, sparen Sie unsere und Ihre eigene Zeit. Wenn wir einen guten Bugreport mit einem vollständigen Testfall für den Bug bekommen, werden wir den Fehler höchstwahrscheinlich im nächsten Release beheben können.

Dieser Abschnitt hilft Ihnen, Ihren Bericht korrekt zu verfassen, damit Sie nicht Ihre Zeit verschwenden, um uns Dinge mitzuteilen, die uns kaum oder gar nicht weiterhelfen.

Wenn Sie einen reproduzierbaren Bug melden, schicken Sie Ihren Bericht bitte an die Fehlerdatenbank unter http://bugs.mysql.com/. Einen Fehler, den wir reproduzieren können, werden wir mit Sicherheit im nächsten MySQL-Release auch beheben können.

Um andere Probleme zu melden, nutzen Sie bitte eine der MySQL-Mailinglisten.

Mit einer zu ausführlichen Meldung können wir meist etwas anfangen, aber nicht mit einer, die zu wenig Informationen enthält. Oft lassen die Nutzer Einzelheiten weg, weil sie glauben, die Fehlerursache bereits zu kennen, und manche Details für bedeutungslos halten.

Halten Sie sich an das Prinzip: Wenn Sie im Zweifel sind, ob Sie ein Detail erwähnen sollen, tun Sie es. Ein paar Zeilen mehr in Ihrem Bericht kosten Sie wenig Zeit und Mühe. Das ist besser, als lange auf eine Antwort zu warten, weil wir Informationen, die im Bericht fehlten, nachträglich von Ihnen einholen müssen.

Die häufigsten Fehler in Bugreports sind (a) der Verfasser gibt die Versionsnummer von Connector/J oder MySQL nicht an, und (b) er beschreibt die Plattform auf der Connector/J installiert ist, nicht genau genug (einschließlich JVM-Version sowie Plattformtyp und -version, auf der MySQL selbst installiert ist).

Ohne diese ungeheuer wichtigen Informationen ist der Bugreport in 99 Prozent der Fälle nutzlos. Sehr oft werden uns Fragen gestellt wie: „Warum funktioniert das bei mir nicht?“ Dann stellen wir fest, dass das verlangte Feature in dieser MySQL-Version nicht implementiert war, oder dass ein Bug, der in einem Bericht beschrieben wird, in den neueren MySQL-Versionen bereits behoben wurde.

Manchmal ist der Fehler plattformunabhängig. In solchen Fällen ist es für uns nachgerade unmöglich, irgendetwas zu reparieren, ohne das Betriebssystem und die Versionsnummer der Plattform zu kennen.

Wenn es irgend möglich ist, erstellen Sie bitte einen reproduzierbaren, eigenständigen Testfall, der keine Klassen von Drittanbietern einbezieht.

Um dies zu vereinfachen, liefern wir eine Basisklasse namens '`com.mysql.jdbc.util.BaseBugReport`' für Testfälle mit Connector/J. Um mit dieser Klasse einen Testfall für Connector/J anzulegen, erstellen Sie eine eigene Klasse, die von `com.mysql.jdbc.util.BaseBugReport` erbt und die Methoden `setUp()`, `tearDown()` und `runTest()` überschreibt.

In der Methode `setUp()` legen Sie Ihre Tabellen an und laden die Daten hinein, die zum Demonstrieren des Fehlers erforderlich sind.

In die Methode `runTest()` schreiben Sie Code, der den Bug an den Tabellen und Daten, die mit `setUp` erstellt wurden, aufzeigt.

Mit der Methode `tearDown()` löschen Sie die mit `setUp()` erstellten Tabellen.

In einer dieser drei Methoden sollten Sie mit einer Variante der `getConnection()`-Methode eine JDBC-Verbindung mit MySQL aufbauen:

- `getConnection()` - Richtet eine Verbindung mit dem in `getUrl()` angegebenen JDBC URL ein. Wenn bereits eine Verbindung besteht, wird diese zurückgegeben, andernfalls wird eine neue Verbindung angelegt.

- `getNewConnection()` - Dies verwenden Sie, wenn sie eine neue Verbindung für Ihren Bugreport benötigen (d.h. wenn mehr als eine Verbindung beteiligt sind).

- `getConnection(String url)` - Gibt eine Verbindung mit dem angegebenen URL zurück.

- `getConnection(String url, Properties props)` - Gibt eine Verbindung mit diesem URL und diesen Eigenschaften zurück.

Wenn Sie einen anderen JDBC-URL als 'jdbc:mysql:///test' benutzen müssen, überschreiben Sie auch die Methode `getUrl()`.

Mit den Methoden `assertTrue(boolean expression)` und `assertTrue(String failureMessage, boolean expression)` erstellen Sie Bedingungen, die in Ihrem Testfall erfüllt sein müssen, um das erwartete Verhalten zu demonstrieren (im Gegensatz zu dem Verhalten, das Sie beobachten, und wegen dem Sie den Bugreport schreiben).

Zum Schluss schreiben Sie eine `main()`-Methode, die eine neue Instanz Ihres Testfalls erzeugt und die `run`-Methode aufruft:

    public static void main(String[] args) throws Exception {
          new MyBugReport().run();
     }

Wenn Sie mit Ihrem Testfall fertig sind und sich überzeugt haben, dass er den Fehler, den Sie melden, demonstriert, übermitteln Sie ihn mit Ihrem Bugreport an http://bugs.mysql.com/.

#### 25.3.6.3. Connector/J Change History

Die Connector/J Change History (Changelog) befindet sich im Haupt-Changelog für MySQL. Siehe Abschnitt D.3, „MySQL Connector/J Change History“.

## 25.4. MySQL Connector/MXJ

MySQL Connector/MXJ ist eine intelligente Lösung, um eine MySQL-Datenbank-Engine (`mysqld`) innerhalb eines Java-Packages zu installieren.

### 25.4.1. Einführung in Connector/MXJ

MySQL Connector/MXJ ist ein Java Utility-Package, mit dem Sie eine MySQL-Datenbank ganz einfach durch Angabe eines Zusatzparameters im JDBC-Verbindungs-URL einsetzen und managen können. Dieser Parameter sorgt dafür, dass die Datenbank beim ersten Verbindungsaufbau gestartet wird. Java-Entwickler können datenbankgestützte Anwendungen dadurch einfacher erstellen, da die Installationshindernisse für sie selbst und die Endanwender wegfallen.

MySQL Connector/MXJ lässt die MySQL-Datenbank wie eine Java-Komponente erscheinen, indem es ermittelt, auf welcher Plattform ein System läuft, die passende Binärversion heraussucht und die Installationsdatei startet. Optional wird sogar eine Anfangsdatenbank mit den vom Benutzer vorgegebenen Parametern eingerichtet.

In den folgenden Anleitungen wird MySQL Connector/MXJ mit einem JDBC-Treiber eingesetzt und als JMX MBean auf JBoss installiert.

Quell- und Binärdateien erhalten Sie bei: http://dev.mysql.com/downloads/connector/mxj/.

Da dies ein Beta-Release ist, freuen wir uns über Feedback von Ihrer Seite.

Bitte richten Sie Fragen oder Kommentare an die MySQL- und Java-Mailingliste.

#### 25.4.1.1. Versionen von Connector/MXJ

Connector/MX

- Connector/MXJ 5.x, zurzeit noch im Beta-Stadium, enthält `mysqld` in der Version 5.0.22 sowie Binärdateien für Linux x86, Mac OS X PPC, Windows XP/NT/2000 x86 und Solaris SPARC. Connector/MXJ 5.x erfordert das Connector/J 5.x-Package.

- Connector/MXJ 1.x umfasst `mysqld` in der Version 4.1.13 und Binärdateien für Linux x86, Windows XP/NT/2000 x86 und Solaris SPARC. Connector/MXJ 1.x erfordert das Connector/J 3.x-Package.

Diese Anleitung bezieht sich auf den Connector/MXJ 5.x-Release. Informationen über ältere Releases entnehmen Sie bitte der Dokumentation zu der jeweiligen Distribution.

#### 25.4.1.2. Überblick über Connector/MXJ

Connector/MXJ besteht aus einer Java-Klasse, einer Kopie der `mysqld`-Binary für eine bestimmte Liste von Plattformen sowie den zugehörigen Dateien und Support-Utilities. Die Java-Klasse steuert die Initialisierung einer Instanz der eingebetteten `mysqld`-Binary und die weitere Verwaltung des `mysqld`-Prozesses. Die gesamte Sequenz und Verwaltung kann mit den Java-Klassen von Connector/MXJ komplett in Java abgewickelt werden. Die nachfolgende Abbildung gibt einen Überblick über den Inhalt von Connector/MXJ.

Es ist wichtig zu wissen, dass Connector/MXJ keine eingebettete Version von MySQL ist und ebenso wenig eine MySQL-Version, die als Teil einer Java-Klasse geschrieben wurde. Connector/MXJ arbeitet mit einer eingebetteten, kompilierten Binärversion von `mysqld`, wie sie auch sonst bei einer normalen MySQL-Installation zum Einsatz kommen würde.

Es sind der Connector/MXJ-Wrapper sowie die unterstützenden Klassen und Tools, die Connector/MXJ wie eine MySQL-Instanz aussehen lassen.

Wenn Sie Connector/MXJ initialisieren, wird die `mysqld`-Binärdatei für die betreffende Plattform, zusammen mit einem vorkonfigurierten Data Directory, extrahiert. Beides ist in der JAR-Datei von Connector/MXJ enthalten. Die `mysqld`-Instanz wird dann mit den bei der Initialisierung angegebenen weiteren Optionen gestartet, und schon ist die MySQL-Datenbank zugänglich.

Da Connector/MXJ in Kombination mit Connector/J arbeitet, können Sie über eine JDBC-Verbindung auf die MySQL-Instanz zugreifen. Wenn Sie den Server nicht mehr benötigen, wird die Instanz abgeschlossen und die während der Session angelegten Daten werden nach Voreinstellung in dem temporären Verzeichnis bewahrt, das beim Hochfahren der Instanz angelegt worden ist.

Connector/MXJ und die eingebettete `mysqld` können in mehreren Umgebungen eingesetzt werden, in denen es unmöglich wäre, eine vorhandene Datenbank zu benutzen oder eine neue MySQL-Instanz zu installieren. Solche Umgebungen sind beispielsweise Embedded Datenbankanwendungen auf CD-ROM und vorübergehende Datenbankanforderungen einer Java-Anwendungsumgebung.

### 25.4.2. Installation von Connector/MXJ

Für Connector/MXJ gibt es keine Installationsanwendung oder -prozesse, doch die folgenden Schritte können die Installation und den Einsatz von Connector/MXJ erleichtern.

Folgende Grundvoraussetzungen müssen erfüllt sein:

- Java Runtime Environment (v1.4.0 oder höher), wenn Sie nur das Package einsetzen möchten.

- Java Development Kit (v1.4.0 oder höher), wenn Sie Connector/MXJ aus den Quelldateien erstellen wollen.

- Connector/J 5.0 oder höher.

Je nach der Installations-/Einsatzumgebung benötigen Sie vielleicht auch Folgendes:

- JBoss – 4.0rc1 oder höher

- Apache Tomcat – 5.0 oder höher

- JMX-Referenzimplementierung Version 1.2.1 von Sun (von http://java.sun.com/products/JavaManagement/)

#### 25.4.2.1. Unterstützte Plattformen

Connector/MXJ ist mit jeder Plattform kompatibel, die Java und MySQL unterstützt. Connector/MXJ enthält die `mysqld`-Binary für ausgewählte Plattformen bereits ab Werk:

- Linux, i386

- Windows NT, Windows 2000, Windows XP, x86

- Solaris 8, SPARC 32 (kompatibel mit Solaris 8, Solaris 9 und Solaris 10 auf SPARC mit 32 Bit und 64 Bit)

- Mac OS X, PowerPC

Mehr über die Integration Ihres eigenen Connector/MXJ in die verschiedenen Plattformen erfahren Sie unter Abschnitt 25.4.5.1, „Ein eigenes Connector/MXJ-Package anlegen“.

#### 25.4.2.2. Basisinstallation von Connector/MXJ

Da kein formaler Installationsprozess existiert, bleiben die Installationsmethode, das Installationsverzeichnis und die Zugriffsmethoden von Connector/MXJ vollständig Ihren persönlichen Bedürfnissen überlassen.

Für eine Basisinstallation suchen Sie ein Zielverzeichnis für die Dateien von Connector/MXJ aus. Auf Unix/Linux wäre dies so etwas wie `/usr/local/connector-mxj` und auf Windows so etwas wie `C:\Connector-MXJ` oder ein Unterverzeichnis von `Programmdateien`.

Die Dateien werden folgendermaßen installiert:

1. Sie laden das Connector/MXJ-Package entweder im Tar/Gzip-Format (ideal für Unix/Linux) oder im Zip-Format (Windows) herunter.

2. Sie extrahieren die Dateien, wodurch das Verzeichnis `connector-mxj` angelegt wird. Dieses können Sie an den gewünschten Speicherort kopieren und nach Wunsch umbenennen.

3. Am besten schreiben Sie das Verzeichnis von Connector/MXJ JAR (`connextor-mxj.jar`) auch in Ihre globale Variable `CLASSPATH`. Zusätzlich müssen Sie die AspectJ Runtime hinzufügen, die in `lib/aspectjrt.jar` liegt.

   Auf Unix/Linux können Sie dies entweder global tun, indem Sie das globale Shell-Profil entsprechend bearbeiten, oder auf Benutzerebene, indem Sie das jeweilige individuelle Shell-Profil ändern.

   Auf Windows 2000, Windows NT und Windows XP bearbeiten Sie den globalen `CLASSPATH`, indem Sie die `Umgebungsvariablen` in der Systemsteuerung für `System` ändern.

#### 25.4.2.3. Schnellstart mit Connector/MXJ

Sobald Sie die Komponenten von Connector/MXJ und Connector/J extrahiert haben, können Sie eine Beispielanwendung ausführen, die eine MySQL-Instanz erstellt. Testen können Sie die Installation mit `ConnectorMXJUrlTestExample`:

    java ConnectorMXJUrlTestExample
    jdbc:mysql:mxj://localhost:3336/test?server.basedir=/var/tmp/test-mxj
    [MysqldResource] launching mysqld (getOptions)
    [/var/tmp/test-mxj/bin/mysqld][--no-defaults][--pid-file=/var/tmp/test-mxj/data/MysqldResource.pid][--socket=mysql.sock][--datadir=/var/tmp/test-mxj/data][--port=3336][--basedir=/var/tmp/test-mxj]
    [MysqldResource] launching mysqld (driver_launched_mysqld_1)
    InnoDB: The first specified data file ./ibdata1 did not exist:
    InnoDB: a new database to be created!
    060726 15:40:42  InnoDB: Setting file ./ibdata1 size to 10 MB
    InnoDB: Database physically writes the file full: wait...
    060726 15:40:43  InnoDB: Log file ./ib_logfile0 did not exist: new to be created
    InnoDB: Setting log file ./ib_logfile0 size to 5 MB
    InnoDB: Database physically writes the file full: wait...
    060726 15:40:43  InnoDB: Log file ./ib_logfile1 did not exist: new to be created
    InnoDB: Setting log file ./ib_logfile1 size to 5 MB
    InnoDB: Database physically writes the file full: wait...
    InnoDB: Doublewrite buffer not found: creating new
    InnoDB: Doublewrite buffer created
    InnoDB: Creating foreign key constraint system tables
    InnoDB: Foreign key constraint system tables created
    060726 15:40:44  InnoDB: Started; log sequence number 0 0
    060726 15:40:44 [Note] /var/tmp/test-mxj/bin/mysqld: ready for connections.
    Version: '5.0.22-max'  socket: 'mysql.sock'  port: 3336  MySQL Community Edition - Experimental (GPL)
    [MysqldResource] mysqld running as process: 1210
    ------------------------

    5.0.22-max

    ------------------------
    [MysqldResource] stopping mysqld (process: 1210)
    060726 15:40:44 [Note] /var/tmp/test-mxj/bin/mysqld: Normal shutdown

    060726 15:40:45  InnoDB: Starting shutdown...
    060726 15:40:48  InnoDB: Shutdown completed; log sequence number 0 43655
    060726 15:40:48 [Note] /var/tmp/test-mxj/bin/mysqld: Shutdown complete

    [MysqldResource] clearing options
    [MysqldResource] shutdown complete

Diese Ausgabe zeigt, wie MySQL startet, die notwendigen Dateien (Logdateien, InnoDB-Datendateien) angelegt werden und die MySQL-Datenbank in den Betriebszustand geht. Dann wird die Instanz von Connector/MXJ heruntergefahren, bevor das Beispiel endet.

#### 25.4.2.4. Connector/MXJ mit dem Treiberstart installieren

Connector/MXJ und Connector/J arbeiten zusammen, damit Sie eine Instanz des `mysqld`-Servers einfach durch ein Schlüsselwort im JDBC-Verbindungs-String starten können. So lässt sich die Integration von Connector/MXJ in eine Java-Anwendung automatisieren und der Einsatz von Connector/MXJ wird ganz einfach:

1. Laden und extrahieren Sie Connector/MXJ und schreiben Sie `connector-mxj.jar` in den `CLASSPATH`.

2. Nehmen Sie in den JDBC-Verbindungs-String das Schlüsselwort `mxj` auf, wie hier gezeigt: `jdbc:mysql:mxj://localhost:`PORT`/`DBNAME``.

Mehr zum Thema erfahren Sie in Abschnitt 25.4.3, „Konfiguration von Connector/MXJ“.

#### 25.4.2.5. Connector/MXJ mit JBoss

Für den Einsatz in einer JBoss-Umgebung müssen Sie diese in den JDBC-Parametern so konfigurieren, dass sie die Connector/MXJ-Komponente benutzt:

1. Laden Sie Connector/MXJ und kopieren Sie die Datei `connector-mxj.jar` in das Verzeichnis `$JBOSS_HOME/server/default/lib`.

2. Laden Sie Connector/J und kopieren Sie die Datei `connector-mxj.jar` in das Verzeichnis `$JBOSS_HOME/server/default/lib`.

3. Erzeugen Sie eine MBean-Service-XML-Datei im Verzeichnis `$JBOSS_HOME/server/default/deploy`, wobei eventuell Attribute wie `datadir` und `autostart` eingestellt werden.

4. Stellen Sie die JDBC-Parameter Ihrer Webanwendung wie folgt ein:

       String driver = "com.mysql.jdbc.Driver";
       String url = "jdbc:mysql:///test?propertiesTransform="+
                    "com.mysql.management.jmx.ConnectorMXJPropertiesTransform";
       String user = "root";
       String password = "";
       Class.forName(driver);
       Connection conn = DriverManager.getConnection(url, user, password);

Am besten legen Sie für Benutzer und Datenbank separate Tablespaces an, anstatt "root und test" zu verwenden.

Außerdem sollten Sie unbedingt eine Backup-Prozedur einrichten, um die Datenbankdateien im `datadir` zu sichern.

#### 25.4.2.6. Installation mit JUnit überprüfen

Das beste Mittel, um sicherzustellen, dass Ihre Plattform unterstützt wird, sind die JUnit-Tests. Diese überprüfen die Connector/MXJ-Klassen und zugehörige Komponenten.

##### 25.4.2.6.1. JUnit-Testanforderungen

Zuerst müssen Sie sich vergewissern, dass die Komponenten auf Ihrer Plattform funktionieren. Da die Klasse `MysqldResource` in Wirklichkeit ein Wrapper für eine native MySQL-Version ist, werden nicht alle Plattformen unterstützt. Zu der Zeit, da dies geschrieben wird, funktioniert Linux auf der i386-Architektur ziemlich gut, ebenso wie OS X v10.3. Begrenzte Tests wurden auch bereits mit Windows und Solaris vorgenommen.

Anforderungen:

1. JDK-1.4 oder höher (oder die JRE, wenn Sie keine Quelldateien oder JSPs kompilieren).

2. MySQL Connector/J Version 5.0 oder höher (von http://dev.mysql.com/downloads/connector/j/) muss installiert und über den CLASSPATH zugänglich sein.

3. Die `javax.management`-Klassen für die JMX-Version 1.2.1, die in folgenden Anwendungsservern vorhanden sind:

   - JBoss – 4.0rc1 oder höher.

   - Apache Tomcat – 5.0 oder höher.

   - Die JMX-Referenzimplementierung Version 1.2.1 von Sun (von http://java.sun.com/products/JavaManagement/).

4. JUnit 3.8.1 (von http://www.junit.org/).

Wenn Sie von der Quelle kompilieren, gelten zusätzlich zu den obigen Anforderungen folgende:

1. Ant in der Version 1.5 oder höher (von http://ant.apache.org/).

##### 25.4.2.6.2. Durchführung der JUnit-Tests

1. Die Tests versuchen, MySQL auf Port 3336 zu starten. Wenn Sie MySQL bereits ausführen, kann dies Konflikte verursachen. Das ist jedoch recht unwahrscheinlich, da der Standardport für MySQL 3306 ist. Sie können allerdings die Java-Eigenschaft "c-mxj_test_port" auch auf einen anderen Port Ihrer Wahl einstellen. Alternativ können Sie auch beim Starten alle noch laufenden MySQL-Instanzen auf dem Zielrechner herunterfahren.

   Nach Voreinstellung unterdrücken die Tests die Konsolenausgabe. Wenn Sie ausführliche Meldungen haben möchten, setzen Sie die Java-Eigenschaft "c-mxj_test_silent" auf "false".

2. Um die JUnit-Testsuite auszuführen, muss der $CLASSPATH Folgendes enthalten:

   - JUnit

   - JMX

   - Connector/J

   - MySQL Connector/MXJ

3. Fehlt `connector-mxj.jar` in Ihrem Download, extrahieren Sie bitte das MySQL Connector/MXJ-Quellarchiv.

       cd mysqldjmx
       ant dist

   Dann fügen Sie dem CLASSPATH `$TEMP/cmxj/stage/connector-mxj/connector-mxj.jar` hinzu.

4. Wenn Sie `junit` haben, führen Sie die JUnit-Tests durch. Geben Sie hierzu auf der Kommandozeile Folgendes ein:

       java junit.textui.TestRunner com.mysql.management.AllTestsSuite

   Es müsste in etwa folgende Ausgabe erscheinen:

       .........................................
       .........................................
       ..........
       Time: 259.438

       OK (101 tests)

   Die Tests laufen gegen Ende etwas langsam, fassen Sie sich also in Geduld.

### 25.4.3. Konfiguration von Connector/MXJ

#### 25.4.3.1. Ausführung als Teil des JDBC-Treibers

Ein Feature des MySQL Connector/J-JDBC-Treibers ist seine Fähigkeit, eine Verbindung mit einer eingebetteten Connector/MXJ-Instanz durch das Schlüsselwort mxj im JDBC-Verbindungs-String einzurichten.

Das folgende Beispiel ist ein Programm, das eine Verbindung aufbaut, eine Anfrage ausführt und die Ergebnisse an System.out ausgibt. Die MySQL-Datenbank wird im Rahmen des Verbindungsprozesses gestartet und im finally-Block heruntergefahren.

Diese Datei liegt im Connector/MXJ-Package unter `src/ConnectorMXJUrlTestExample.java`.

    import java.io.File;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;

    import com.mysql.management.driverlaunched.ServerLauncherSocketFactory;

    public class ConnectorMXJUrlTestExample {
        public static String DRIVER = "com.mysql.jdbc.Driver";

        public static String JAVA_IO_TMPDIR = "java.io.tmpdir";

        public static void main(String[] args) throws Exception {
            File ourAppDir = new File(System.getProperty(JAVA_IO_TMPDIR));
            File databaseDir = new File(ourAppDir, "test-mxj");
            int port = 3336;

            String url = "jdbc:mysql:mxj://localhost:" + port + "/test" + "?"
                    + "server.basedir=" + databaseDir;

            System.out.println(url);

            String userName = "root";
            String password = "";

            Class.forName(DRIVER);
            Connection conn = null;
            try {
                conn = DriverManager.getConnection(url, userName, password);
                printQueryResults(conn, "SELECT VERSION()");
            } finally {
                try {
                    if (conn != null)
                        conn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                ServerLauncherSocketFactory.shutdown(databaseDir, null);
            }
        }

        public static void printQueryResults(Connection conn, String SQLquery)
                throws Exception {
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(SQLquery);
            int columns = rs.getMetaData().getColumnCount();
            System.out.println("------------------------");
            System.out.println();
            while (rs.next()) {
                for (int i = 1; i <= columns; i++) {
                    System.out.println(rs.getString(i));
                }
                System.out.println();
            }
            rs.close();
            stmt.close();
            System.out.println("------------------------");
            System.out.flush();
            Thread.sleep(100); // wait for System.out to finish flush
        }
    }

Um dieses Programm auszuführen, vergewissern Sie sich zuerst, dass connector-mxj.jar und Connector/J im CLASSPATH liegen, und geben dann Folgendes ein:

    java ConnectorMXJTestExample

#### 25.4.3.2. Ausführung in einem Java-Objekt

Wenn Sie eine Java-Anwendung haben und eine MySQL-Datenbank darin „einbetten“ möchten, benutzen Sie die Klasse com.mysql.management.MysqldResource. Diese Klasse instanziieren Sie entweder mit dem (parameterlosen) Standardkonstruktor oder, indem Sie ein java.io.File-Objekt übergeben, welches das Verzeichnis darstellt, in das Sie den Server "entpacken" möchten. Sie können sie auch mit Ausgabeströmen zu "stdout" und "stderr" für die Protokollierung instanziieren.

Sobald das Datenbankobjekt erzeugt ist, ist es in der Lage, eine java.util.Map mit den für die Plattform und verwendete MySQL-Version passenden Serveroptionen anzuzeigen.

Die MysqldResource versetzt Sie in die Lage, MySQL mit einer von Ihnen gelieferten java.util.Map von Serveroptionen zu "starten" und die Datenbank "herunterzufahren". Das folgende Beispiel zeigt in vereinfachter Form, wie MySQL mit reinen Java-Objekten in eine Anwendung eingebettet wird.

Diese Datei liegt im Connector/MXJ-Package unter dem Namen `src/ConnectorMXJObjectTestExample.java` vor.

    import java.io.File;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.HashMap;
    import java.util.Map;

    import com.mysql.management.MysqldResource;

    public class ConnectorMXJObjectTestExample {
        public static String DRIVER = "com.mysql.jdbc.Driver";

        public static String JAVA_IO_TMPDIR = "java.io.tmpdir";

        public static void main(String[] args) throws Exception {
            File ourAppDir = new File(System.getProperty(JAVA_IO_TMPDIR));
            File databaseDir = new File(ourAppDir, "mysql-mxj");
            int port = 3336;

            MysqldResource mysqldResource = startDatabase(databaseDir, port);

            String userName = "root";
            String password = "";

            Class.forName(DRIVER);
            Connection conn = null;
            try {
                String url = "jdbc:mysql://localhost:" + port + "/test";
                conn = DriverManager.getConnection(url, userName, password);
                printQueryResults(conn, "SELECT VERSION()");
            } finally {
                try {
                    if (conn != null) {
                        conn.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    mysqldResource.shutdown();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        public static MysqldResource startDatabase(File databaseDir, int port) {
            MysqldResource mysqldResource = new MysqldResource(databaseDir);

            Map database_options = new HashMap();
            database_options.put("port", Integer.toString(port));
            mysqldResource.start("test-mysqld-thread", database_options);

            if (!mysqldResource.isRunning()) {
                throw new RuntimeException("MySQL did not start.");
            }

            System.out.println("MySQL is running.");

            return mysqldResource;
        }

        public static void printQueryResults(Connection conn, String SQLquery)
                throws Exception {
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(SQLquery);
            int columns = rs.getMetaData().getColumnCount();
            System.out.println("------------------------");
            System.out.println();
            while (rs.next()) {
                for (int i = 1; i <= columns; i++) {
                    System.out.println(rs.getString(i));
                }
                System.out.println();
            }
            rs.close();
            stmt.close();
            System.out.println("------------------------");
            System.out.flush();
            Thread.sleep(100); // wait for System.out to finish flush
        }
    }

#### 25.4.3.3. Einstellung von Serveroptionen

Für eine MySQL-Datenbank sind natürlich viele Optionen einzustellen. Diese können Sie im JDBC-Verbindungs-String angeben, indem Sie einfach vor jede Serveroption das Präfix ''server.'' setzen. In den folgenden Beispielen setzen wir zwei Treiber- und zwei Serverparameter:

            String url = "jdbc:mysql://" + hostColonPort + "/"
                    + "?"
                    + "cacheServerConfiguration=true"
                    + "&"
                    + "useLocalSessionState=true"
                    + "&"
                    + "server.basedir=/opt/myapp/db"
                    + "&"
                    + "server.datadir=/mnt/bigdisk/myapp/data";

### 25.4.4. Referenz zu Connector/MXJ

#### 25.4.4.1. MysqldResource-API

##### 25.4.4.1.1. MysqldResource-Konstruktoren

Die Klasse `MysqldResource` kennt drei verschiedene Konstruktorformen:

- `public MysqldResource(File baseDir, File dataDir, String mysqlVersionString, PrintStream out, PrintStream err, Utils util)`

  Dieser detaillierteste Konstruktor stellt das Basisverzeichnis und das Data Directory ein, wählt einen Server anhand seines Versions-Strings aus und stellt die Standardausgabe, das Standardfehlerlog und die MySQL-Utilities-Klasse ein.

- `public MysqldResource(File baseDir, File dataDir, String mysqlVersionString, PrintStream out, PrintStream err)`

  Dieser Konstruktor stellt das Basisverzeichnis und das Data Directory ein, wählt einen Server anhand seines Versions-Strings aus und stellt die Standardausgabe und das Standardfehlerlog ein.

- `public MysqldResource(File baseDir, File dataDir, String mysqlVersionString)`

  Dieser Konstruktor stellt das Basisverzeichnis und das Data Directory ein und wählt einen Server anhand seines Versions-Strings aus. Die Standardausgabe und das Standardfehlerlog werden in System.out und System.err geschrieben.

- `public MysqldResource(File baseDir, File dataDir)`

  Dieser Konstruktor stellt das Basisverzeichnis und das Data Directory ein und wählt die Standard-MySQL-Version aus. Die Standardausgabe und das Standardfehlerlog werden in System.out und System.err geschrieben.

- `public MysqldResource(File baseDir);`

  Dieser Konstruktor erlaubt die Einstellung eines "basedir" für die MySQL-Dateien. Die Standardausgabe und das Standardfehlerlog werden in System.out und System.err geschrieben.

- `public MysqldResource();`

  Das Basisverzeichnis ist auf java.io.tempdir voreingestellt. Die Standardausgabe und das Standardfehlerlog werden in System.out und System.err geschrieben.

##### 25.4.4.1.2. MysqldResource-Methoden

Die MysqldResource-API kennt folgende Methoden:

- `void start(String threadName, Map mysqldArgs);`

  Lädt und startet MySQL. Der String "threadName" benennt den Thread, der die MySQL-Kommandozeile ausführt. Die Map enthält die an die Kommandozeile zu übergebenden Argumente und ihre Werte.

- `void shutdown();`

  Fährt die vom MysqldResource-Objekt verwaltete MySQL-Instanz herunter.

- `Map getServerOptions();`

  Gibt eine Map mit allen Optionen und ihren aktuellen Optionen zurück, die der MySQL-Datenbank zur Verfügung stehen (oder mit den Standardoptionen, wenn die Datenbank nicht läuft).

- `boolean isRunning();`

  Gibt true zurück, wenn die MySQL-Datenbank läuft.

- `boolean isReadyForConnections();`

  Gibt true zurück, wenn die Datenbank meldet, dass sie für Verbindungen zur Verfügung steht.

- `void setKillDelay(int millis);`

  Das Standard-„Kill Delay“ beträgt 30 Sekunden. Dies ist die Zeit, die zwischen der Shutdown-Anforderung und einem „force kill“ vergeht, wenn die Datenbank nicht selbst herunterfährt.

- `void addCompletionListenser(Runnable listener);`

  Ermöglicht es, Anwendungen zu benachrichtigen, wenn der Serverprozess fertig ist. Jeder ''Listener'' wird in seinem eigenen Thread abgeschlossen.

- `String getVersion();`

  Gibt die MySQL-Version zurück.

- `void setVersion(int MajorVersion, int minorVersion, int patchLevel);`

  In der Standarddistribution ist nur eine einzige MySQL-Version enthalten. Es ist jedoch auch möglich, mehrere Versionen beizufügen und anzugeben, welche davon benutzt werden soll.

### 25.4.5. Hinweise und Tipps zu Connector/MXJ

Dieser Abschnitt enthält Hinweise und Tipps zur Verwendung von Connector/MXJ in Ihren Anwendungen.

#### 25.4.5.1. Ein eigenes Connector/MXJ-Package anlegen

Wenn Sie ein eigenes Connector/MXJ-Package schnüren wollen, das eine bestimmte `mysqld`-Version oder Plattform enthält, dann müssen Sie die Datei `connector-mxj.jar` extrahieren und neu erstellen.

Als Erstes legen Sie ein neues Verzeichnis an, in welches Sie die `connector-mxj.jar`-Datei extrahieren:

    shell> mkdir custom-mxj
    shell> cd custom-mxj
    shell> jar -xf connector-mxj.jar
    shell> ls
    5-0-22/
    ConnectorMXJObjectTestExample.class
    ConnectorMXJUrlTestExample.class
    META-INF/
    TestDb.class
    com/
    kill.exe

Das MySQL-Versionsverzeichnis, im obigen Beispiel `5-0-22`, enthält alle Dateien, die notwendig sind, um bei der Ausführung von Connector/MXJ eine MySQL-Instanz zu erzeugen. Alle Dateien in diesem Verzeichnis sind für jede Version von MySQL notwendig, die Sie einbetten möchten. Achten Sie bitte auch auf das Format der Versionsnummer, das Bindestriche statt Punkte enthält, um die Einzelbestandteile der Versionsnummer abzugrenzen.

In dem versionsspezifischen Verzeichnis liegen plattformspezifische Verzeichnisse sowie die von MySQL für die diversen Plattformen benötigten Archive des `data`- und `share`-Verzeichnisses. Hier sehen Sie zum Beispiel das Listing des standardmäßigen Connector/MXJ-Packages:

    shell>> ls
    Linux-i386/
    META-INF/
    Mac_OS_X-ppc/
    SunOS-sparc/
    Win-x86/
    com/
    data_dir.jar
    share_dir.jar
    win_share_dir.jar

Plattformspezifische Verzeichnisse werden nach Betriebssystem und Plattform aufgeführt. So liegt zum Beispiel die `mysqld` für Mac OS X PowerPC im Verzeichnis `Mac_OS_X-ppc`. Sie können Verzeichnisse, die Sie nicht benötigen, löschen und neue Verzeichnisse für weitere Plattformen hinzufügen.

Um eine plattformspezifische `mysqld` hinzuzufügen, erstellen Sie ein neues Verzeichnis mit dem für Ihr Betriebssystem/Ihre Plattform passenden Namen. Sie könnten zum Beispiel für Mac OS X/Intel das Verzeichnis `Mac_OS_X-i386` einrichten.

Auf Unix-Systemen können Sie die Plattform mit `uname` ermitteln:

    shell> uname -p
    i386

Nun müssen Sie `mysqld` für die MySQL-Version und Plattform in das neue Verzeichnis kompilieren, die Sie in Ihr eigenes `connector-mxj.jar`-Package aufnehmen möchten.

Legen Sie in dem soeben erstellten BS/Plattform-Verzeichnis eine Datei namens `version.txt` an, die den Versions-String und Pfad der mysqld-Binary enthält, zum Beispiel:

    mysql-5.0.22-osx10.3-i386/bin/mysqld

Nun können Sie die Datei`connector-mxj.jar` mit der frisch hinzugefügten `mysqld`-Binary neu erstellen:

    shell> cd custom-mxj
    shell> jar -cf ../connector-mxj.jar *

Testen können Sie dieses Ppackage wie in Abschnitt 25.4.2.3, „Schnellstart mit Connector/MXJ“, beschrieben.

#### 25.4.5.2. Connector/MXJ mit einer vorkonfigurierten Datenbank einsetzen

Um eine vorkonfigurierte und mit Daten bevölkerte Datenbank in Ihre Connector/MXJ-JAR-Datei aufzunehmen, müssen Sie eine eigene `data_dir.jar`-Datei anlegen, wie sie in der Haupt-`connector-mxj.jar`-Datei enthalten ist:

1. Zuerst extrahieren Sie `connector-mxj.jar` wie im vorigen Abschnitt beschrieben (siehe Abschnitt 25.4.5.1, „Ein eigenes Connector/MXJ-Package anlegen“).

2. Erstellen Sie in einer vorhandenen MySQL-Instanz (einschließlich Connector/MXJ-Instanzen) Ihre Datenbank und laden Sie Daten hinein. Die Formate der Datendateien sind plattformunabhängig.

3. Fahren Sie die MySQL-Instanz herunter.

4. Erstellen Sie aus dem Data Directory und den Datenbanken, die Sie in Ihr Connector/MXJ-Package einbinden möchten, eine JAR-Datei. Diese sollte zusätzlich zu den spezifischen Datenbanken, die Sie aufnehmen möchten, auch die `mysql`-Datenbank mit den Daten zur Benutzerauthentifizierung enthalten. Folgender Befehl legt beispielsweise ein JAR mit den Datenbanken `mysql` und `mxjtest` an:

       shell> jar -cf ../data_dir.jar mysql mxjtest

5. Kopieren Sie die `data_dir.jar`-Datei in das extrahierte `connector-mxj.jar`-Verzeichnis und erstellen Sie dann ein Archiv für `connector-mxj.jar`.

Wenn Sie Datenbanken mit der InnoDB-Engine anlegen, müssen Sie die Dateien `ibdata.*` und `ib_logfile.*` in das `data_dir.jar`-Archiv aufnehmen.

#### 25.4.5.3. Ausführung mit (speziellem) JMX-Agent

Als JMX MBean erfordert MySQL Connector/MXJ einen JMX v1.2-konformen MBean-Container wie etwa JBoss in der Version 4. Die MBean stellt mithilfe der JMX-Management-APIs die für die gegebene Plattform geeigneten Parameter ein (und ermöglicht auch Ihnen, die Parameter zu setzen).

Wenn Sie nicht die SUN-Referenzimplementierung der JMX-Bibliotheken verwenden, sollten Sie diesen Abschnitt übergehen, und wenn Sie JBoss verwenden, überspringen Sie auch den nachfolgenden Abschnitt.

Betrachten wir nun die MysqldDynamicMBean in einem JMX-Agenten in Aktion. Im `com.mysql.management.jmx.sunri`-Package befindet sich ein speziell angepasster JMX-Agent mit zwei MBeans:

1. MysqldDynamicMBean und

2. einem com.sun.jdmk.comm.HtmlAdaptorServer, der eine Webschnittstelle zur Manipulation der Beans in einem JMX-Agent bereitstellt.

Wenn dieser sehr einfache Agent gestartet wird, kann eine MySQL-Datenbank über einen Webbrowser gestartet und angehalten werden.

1. Beenden Sie den Plattformtest wie oben.

   - Aktuelle Versionen von JDK, JUnit, Connector/J, MySQL Connector/MXJ

   - Dieser Abschnitt erfordert die SUN-Referenzimplementierung von JMX.

   - `PATH`, `JAVA_HOME`, `ANT_HOME`, `CLASSPATH`

2. Wenn Sie nicht von der Quelle installieren, gehen Sie zum nächsten Abschnitt weiter.

   Rebuild mit "sunri.present"

       ant -Dsunri.present=true dist
       re-run tests:
       java junit.textui.TestRunner com.mysql.management.AllTestsSuite

3. Starten Sie den Test-Agenten auf der Kommandozeile:

       java com.mysql.management.jmx.sunri.MysqldTestAgentSunHtmlAdaptor &

4. ... von einem Browser:

       http://localhost:9092/

5. ... unter MysqldAgent:

       select "name=mysqld"

6. Beobachten Sie die MBean-View.

7. Scrollen Sie den Bildschirm nach unten und klicken Sie auf startMysqld.

8. Klicken Sie auf `Back to MBean View`.

9. Scrollen Sie den Bildschirm nach unten und klicken Sie auf stopMysqld.

10. Halten Sie den Java-Prozess an, der den Test-Agent ausführt (jmx server).

#### 25.4.5.4. Einsatz in einer Standardumgebung von JMX Agent (JBoss)

Wenn Sie sich darauf verlassen können, dass MBean auf der Plattform funktioniert, können Sie die MBean in einem normalen JMX Agent einsetzen. Die folgenden Anleitungen beziehen sich auf eine Installation mit JBoss.

1. Achten Sie auf eine aktuelle Version des Java Development Kits (v1.4.x), siehe oben.

   - Vergewissern Sie sich, dass `JAVA_HOME` gesetzt ist (JBoss benötigt `JAVA_HOME`).

   - Sorgen Sie dafür, dass `JAVA_HOME/bin` im `PATH` liegt (Sie müssen NICHT den CLASSPATH einstellen und benötigen auch keines der JARs aus den vorherigen Tests).

2. Achten Sie auf eine aktuelle Version von JBoss (v4.0RC1 oder höher).

       http://www.jboss.org/index.html
       select "Downloads"
       select "jboss-4.0.zip"
       pick a mirror
       unzip ~/dload/jboss-4.0.zip
       create a JBOSS_HOME environment variable set to the unzipped directory
       unix only:
       cd $JBOSS_HOME/bin
       chmod +x *.sh

3. Kopieren Sie `connector-mxj.jar` in `$JBOSS_HOME/server/default/lib`.

4. Kopieren Sie `mysql-connector-java-3.1.4-beta-bin.jar` in `$JBOSS_HOME/server/default/lib`.

5. Legen Sie ein `mxjtest.war`-Verzeichnis in `$JBOSS_HOME/server/default/deploy` an.

6. Kopieren Sie `index.jsp` in `$JBOSS_HOME/server/default/deploy/mxjtest.war`.

7. Legen Sie eine `mysqld-service.xml`-Datei in `$JBOSS_HOME/server/default/deploy` an.

       <?xml version="1.0" encoding="UTF-8"?>
        <server>
         <mbean code="com.mysql.management.jmx.jboss.JBossMysqldDynamicMBean"
            name="mysql:type=service,name=mysqld">
         <attribute name="datadir">/tmp/xxx_data_xxx</attribute>
         <attribute name="autostart">true</attribute>
         </mbean>
        </server>

8. Starten Sie jboss:

   - auf Unix: $JBOSS_HOME/bin/run.sh

   - auf Windows: %JBOSS_HOME%\bin\run.bat

   Wappnen Sie sich: JBoss schickt jede Menge Ausgabe auf den Bildschirm.

9. Wenn JBoss keine Ausgabe mehr an den Bildschirm sendet, öffnen Sie einen Browser auf `http://localhost:8080/jmx-console`.

10. Scrollen Sie auf der Seite nach unten zum Abschnitt `mysql` und wählen Sie den `mysqld`-Link aus.

11. Schauen Sie auf die Seite JMX MBean View. MySQL müsste bereits laufen.

12. (Wenn "autostart=true" eingestellt ist, können Sie diesen Schritt übergehen.) Scrollen Sie auf dem Bildschirm nach unten. Sie können auf Invoke klicken, damit MySQL aufhört (oder anfängt), `Operation completed successfully without a return value` zu sagen. Klicken Sie auf `Back to MBean View`.

13. Um sich zu vergewissern, dass MySQL läuft, öffnen Sie einen Browser auf `http://localhost:8080/mxjtest/`. Sie müssten jetzt sehen können, dass

        SELECT 1

    folgendes Ergebnis zurückgegeben hat:

        1

14. Mit der Benutzerführung von `$JBOSS_HOME/server/default/deploy/mxjtest.war/index.jsp` können Sie MySQL in Ihrer Webanwendung einsetzen. Eine `test`-Datenbank und ein `root`-User (ohne Passwort) stehen bereits zum Herumexperimentieren bereit. Versuchen Sie, eine Tabelle anzulegen, einige Zeilen einzufügen und SELECT-Operationen darauf auszuführen.

15. Fahren Sie MySQL herunter. MySQL wird automatisch angehalten, wenn JBoss herunterfährt. Oder scrollen Sie im Browser die MBean View nach unten und klicken Sie auf den Button Invoke, um den Dienst anzuhalten. Es wird `Operation completed successfully without a return value` angezeigt. `ps` oder der `Taskmanager` werden Ihnen bestätigen, dass MySQL nicht mehr ausgeführt wird.

Seit der Beta-Version 1.0.6 kann die MBean die MySQL-Datenbank beim Hochfahren starten. Mithilfe der Life-Cycle-Erweiterungsmethoden von JBoss haben wir außerdem dafür gesorgt, dass MySQL mit JBoss gemeinsam herunterfährt.

### 25.4.6. Support für Connector/MXJ

Es gibt viele Möglichkeiten, Support für Connector/MXJ zu bekommen. Bitte fragen Sie die Connector/MXJ-Community um Hilfe, ehe Sie einen potenziellen Bug oder ein Problem melden. Siehe Abschnitt 25.4.6.1, „Support von der Connector/MXJ-Community“.

#### 25.4.6.1. Support von der Connector/MXJ-Community

MySQL AB unterstützt die Benutzer-Community mit mehreren Mailinglisten und Webforen.

Hilfe und Support finden Sie in der MySQL- und Java-Mailingliste.

Wie Sie MySQL-Mailinglisten abonnieren oder die Listenarchive durchsuchen können, erfahren Sie unter http://lists.mysql.com/. Siehe Abschnitt 1.7.1, „Die MySQL-Mailinglisten“.

Community-Support von erfahrenen Benutzern erhalten Sie auch im MyODBC-Forum . Auch in den anderen MySQL-Foren unter http://forums.mysql.com wird Ihnen geholfen. Siehe Abschnitt 1.7.2, „MySQL-Community-Support in den MySQL-Foren“.

#### 25.4.6.2. Probleme und Fehler von Connector/MXJ melden

Wenn Sie Probleme mit Connector/MXJ haben, wenden Sie sich bitte zuerst an die Connector/MXJ-Community, siehe Abschnitt 25.4.6.1, „Support von der Connector/MXJ-Community“.

Wenn Sie ein Problem melden, geben Sie uns bitte per E-Mail folgende Informationen:

- Betriebssystem und Version

- Connector/MXJ-Version

- MySQL Server-Version

- Kopien von Fehlermeldungen oder anderen unerwarteten Ausgaben

- einfaches, reproduzierbares Beispiel

`Achtung`: Je mehr Informationen Sie uns geben können, umso wahrscheinlicher ist es, dass wir das Problem beheben können.

Wenn Sie der Auffassung sind, dass es sich um einen Bug handelt, senden Sie uns einen Bugreport über http://bugs.mysql.com/.

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 24. APIs und Bibliotheken | Zum Anfang | Kapitel 26. MySQL erweitern