Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger

 << zurück
Linux-UNIX-Programmierung von Jürgen Wolf
Das umfassende Handbuch – 2., aktualisierte und erweiterte Auflage 2006
Buch: Linux-UNIX-Programmierung

Linux-UNIX-Programmierung
1216 S., mit CD, 49,90 Euro
Rheinwerk Computing
ISBN 3-89842-749-8
gp Kapitel 12 MySQL und PostgreSQL
  gp 12.1 Relationales Datenbanksystem
  gp 12.2 Relationaler Datenbankserver
  gp 12.3 SQL-Server im Überblick
  gp 12.4 MySQL
    gp 12.4.1 Anwendungsgebiete von MySQL
    gp 12.4.2 Schnittstellen von MySQL
    gp 12.4.3 Installation von MySQL
    gp 12.4.4 MySQL-Server starten und stoppen
    gp 12.4.5 Konfigurationsdatei my.cnf
    gp 12.4.6 Kommandozeilenwerkzeuge für und von mysql
    gp 12.4.7 Grafische Clients
    gp 12.4.8 MySQL-Crashkurs
    gp 12.4.9 Datentypen
    gp 12.4.10 Datenbank anlegen, verwenden und löschen
    gp 12.4.11 Tabelle anlegen
    gp 12.4.12 Schlüsselfelder (Tabellen anlegen)
    gp 12.4.13 Indizes
    gp 12.4.14 Tabellentypen (Tabellen anlegen)
    gp 12.4.15 Autowerte definieren
    gp 12.4.16 Tabellen umbenennen und ändern
    gp 12.4.17 Daten einfügen, ändern und löschen
    gp 12.4.18 Daten importieren
    gp 12.4.19 Datenausgabe
    gp 12.4.20 NULL ist 0 oder undefiniert?
    gp 12.4.21 Unscharfe Suche
  gp 12.5 MySQL C-API
    gp 12.5.1 Verbindung mit dem MySQL-Server aufbauen
    gp 12.5.2 Aufgetretene Fehler ermitteln – mysql_errno() und mysql_error()
    gp 12.5.3 Schließt die Verbindung zum Server – mysql_close()
    gp 12.5.4 Erstes Beispiel
    gp 12.5.5 Verschiedene Informationen ermitteln
    gp 12.5.6 Datenbanken, Tabellen und Felder ausgeben (MYSQL_RES)
    gp 12.5.7 Ergebnismenge zeilenweise bearbeiten (MYSQL_ROW)
    gp 12.5.8 Ergebnismenge spaltenweise einlesen (und ausgeben) (MYSQL_FIELD)
    gp 12.5.9 Ein Beispiel
    gp 12.5.10 Ergebnismenge – weitere Funktionen
    gp 12.5.11 Befehle an den Server – mysql_query() und mysql_real_query()
    gp 12.5.12 Weitere Funktionen
    gp 12.5.13 Veraltete Funktionen
    gp 12.5.14 Neue Funktionen ab Version 4.1.x
  gp 12.6 Beispiel eines Newssystems mit MySQL
    gp 12.6.1 Die Headerdatei my_cgi.h
    gp 12.6.2 (Pseudo-)Planung
    gp 12.6.3 Datenbank und Tabellen anlegen
    gp 12.6.4 MySQL-Clients mit GUI
    gp 12.6.5 Randnotiz
  gp 12.7 Neue SQL-Funktionen für die Shell – MySQL erweitern
  gp 12.8 MySQL-Funktionen mit der UDF-Schnittstelle entwerfen
    gp 12.8.1 UDF-Sequenzen
    gp 12.8.2 UDF_INIT-Struktur
    gp 12.8.3 UDF_ARGS-Struktur
    gp 12.8.4 Rückgabewert
    gp 12.8.5 Benutzerdefinierte Funktionen erstellen
    gp 12.8.6 Benutzerdefinierte Funktion kompilieren, installieren und ausführen
  gp 12.9 PostgreSQL – objektrelationales Datenbankverwaltungssystem
    gp 12.9.1 PostgreSQL im Vergleich zu MySQL
    gp 12.9.2 Unterschiede in der Syntax zwischen MySQL und PostgreSQL
    gp 12.9.3 PostgreSQL installieren
    gp 12.9.4 Konfigurationsdateien bei PostgreSQL – (postgresql.conf, pg_hba_conf)
    gp 12.9.5 CRASHKURS PostgreSQL
    gp 12.9.6 PostgreSQL C-API – libpg
    gp 12.9.7 Umgebungsvariablen und Passwortdatei
    gp 12.9.8 PostgreSQL und Threads
    gp 12.9.9 Ausblick


Rheinwerk Computing

12.8 MySQL-Funktionen mit der UDF-Schnittstelle entwerfen  downtop

Damit der MySQL-Server UDF-Funktionen verwenden kann, sollte mysqld mit dem Flag –with-mysqld-ldflags=-rdynamic konfiguriert sein, um auf alle Symbole von mysqld zugreifen zu können.

Der Grund liegt darin, dass Sie auf vielen Plattformen (inklusive Linux) eine dynamische Bibliothek (mit dlopen()) von einem statisch gelinkten Programm laden können, was Sie erhalten würden, wenn Sie --with-mysqld-ldflags=-all-static benutzen. Die Funktion dlopen() wird zu einem späteren Zeitpunkt im Buch behandelt.

Wenn Sie eine Funktion schreiben, die Sie für SQL-Statements verwenden wollen, sollten Sie einen entsprechenden C-Funktionsnamen wählen, den Sie auch für MySQL verwenden. Beim Schreiben einer Funktion mit der UDF-Schnittstelle wird Ihnen aber nicht absolut freie Hand gelassen, sondern Sie müssen einiges dabei beachten. Eine UDF-Funktion sieht demnach wie folgt aus:

rückgabetyp funktionsname()

Dies ist die Hauptfunktion (bitte nicht mit der main()-Hauptfunktion verwechseln), mit deren Namen auch das SQL-Statement aufgerufen wird. funktionsname() dient hier nur als Beispiel und kann durch jeden erlaubten Funktionsnamen ersetzt werden. Als Rückgabewert kommen hier im Zusammenhang mit den SQL-Datentypen für Ihre C/C++-Funktion(en) folgende in Frage:


Tabelle 12.10    Erlaubte Rückgabetypen mit der UDF-Schnittstelle

SQL-Typ C/C++-Typ
STRING char *
INTEGER long long
REAL double

Optional hingegen sind die Funktionen zum Initialisieren bzw. Deinitialisieren. Die Syntax einer Initialisierung sieht wie folgt aus (bezogen auf die Hauptfunktion funktionsname()):

funktionsname_init()

Die Initialisierungsfunktion kann für folgende Aufgaben verwendet werden:

gp  Die Anzahl von Argumenten überprüfen
gp  Die Datentypen überprüfen, die als Argumente übergeben werden. Sind die Argumente nicht vom erforderlichen Typ, müssen Sie dies MySQL mitteilen, um den Argumenttyp zu erzwingen, der für die Hauptfunktion benötigt wird.
gp  Speicher für die Hauptfunktion bereitstellen
gp  Maximale Länge des Rückgabewertes festlegen
gp  Maximale Anzahl von Dezimalstellen für den REAL-Typ (double) festlegen
gp  Festlegen, ob das Ergebnis NULL sein darf oder nicht

Die Funktion zum Deinitialisieren sieht in der Syntax so aus:

funktionsname_deinit() 

Dies ist die Deinitialisierungsfunktion für funktionsname(). Damit sollte jeglicher Speicher freigegeben (Deallokation) werden, der durch die Initialisierungsfunktion zugewiesen wurde.

Wie schon erwähnt, die Funktionen zum Deinitialisieren und zur Initialisierung sind optional und müssen nicht verwendet werden.

Angenommen Ihre Funktion ist bereits in MySQL implementiert und Sie rufen diese nun mit funktionsname() auf, dann ruft MySQL zuvor noch (vor der eigentlichen Hauptfunktion) die Initialisierungsfunktion funktionsname_init() auf, um alle notwendigen Einrichtungen, wie Argumente überprüfen oder die Speicherzuweisung übernehmen, vorzunehmen. Gibt funktionsname_init() einen Fehler zurück, wird das SQL-Statement mit einer entsprechenden Fehlermeldung abgebrochen. Demnach werden bei einem Fehler die Haupt- und Deinitialisierungsfunktion nicht mehr aufgerufen. Wenn alles glatt verlief, wird hingegen funktionsname() aufgerufen und ausgeführt. Wurde die Hauptfunktion ausgeführt, führt die Deinitialisierungsfunktion am Ende alle Aufräumarbeiten durch.


Hinweis   Sehr wichtig! Alle Funktionen müssen thread-sicher sein. Das heißt, dass Sie keinerlei globale oder statische Variablen zuweisen dürfen, die sich ändern! Wenn Sie Speicher brauchen, sollten Sie diesen in funktionsname_init() zuweisen und in funktionsname_deinit() freigeben.



Rheinwerk Computing

12.8.1 UDF-Sequenzedowntop

Die Hauptfunktion können Sie auch nicht angeben, wie es Ihnen gerade passt (abgesehen vom Funktionsnamen), sondern auch hierbei müssen Sie einiges beachten. Abhängig vom Rückgabetyp Ihrer Funktion müssen Sie nachfolgende Parameter verwenden, damit STRING, INTEGER oder REAL zurückgegeben werden – was das CREATE FUNCTION-Statement auch fordert:

Bei STRING-Funktionen:

char *funktionsname( UDF_INIT *initid, UDF_ARGS *args,
                     char *result, unsigned long *length,
                     char *is_null, char *error );

Bei INTEGER-Funktionen:

long long funktionsname( UDF_INIT *initid, UDF_ARGS *args,
                         char *is_null, char *error );

Bei REAL-Funktionen:

double funktionsname( UDF_INIT *initid, UDF_ARGS *args,
                      char *is_null, char *error );

Die Initialisierungs- und Deinitialisierungsfunktionen werden immer wie folgt deklariert:

my_bool funktionsname_init( UDF_INIT *initid,
                            UDF_ARGS *args, 
                            char *message);
void funktionsname_deinit( UDF_INIT *initid );

Rheinwerk Computing

12.8.2 UDF_INIT-Struktudowntop

Der initid-Parameter wird an alle Funktionen übergeben. Dieser verweist auf eine UDF_INIT-Struktur, die benutzt wird, um Informationen zwischen den Funktionen zu übergeben. Die Initialisierungsfunktion funktionsname_init() sollte alle Strukturvariablen verwenden, die verändert werden sollen. Die Variablen, die Sie nicht verändern wollen, können Sie auf deren Vorgabewert stehen lassen. Folgende UDF_INIT-Strukturvariablen sind dabei vorhanden:

gp  my_bool maybe_nullfunktionsname_init() sollte maybe_null auf 1 setzen, wenn funktionsname() NULL zurückgeben kann. Der Vorgabewert ist 1, wenn eines der Argumente als maybe_null deklariert ist.
gp  unsigned int decimals – Anzahl von Dezimalstellen. Der Vorgabewert ist die maximale Anzahl von Dezimalstellen in den Argumenten, die an die Hauptfunktion übergeben werden. (Wenn der Funktion beispielsweise die Argumente 1.34, 1.345 und 1.3 übergeben werden, wäre der Vorgabewert 3, weil 1.345 drei Dezimalstellen hat.)
gp  unsigned int max_length – Maximale Anzahl der Zeichen im String. Der Vorgabewert ist abhängig vom Ergebnistyp der Funktion. Bei String-Funktionen ist die Vorgabe die Länge des längsten Arguments. Bei Ganzzahl-Funktionen ist die Vorgabe 21 Ziffern. Bei REAL-Funktionen ist die Vorgabe 13 plus die Anzahl von Dezimalstellen, die von initid->decimals angezeigt werden. (Bei nummerischen Funktionen enthält die Länge jedes Vorzeichen- oder Dezimalpunkt-Zeichen.) Wenn Sie einen BLOB zurückgeben wollen, können Sie diesen auf 65 KB oder 16 MB setzen. Der Speicher wird nicht zugewiesen, aber dazu verwendet, um zu entscheiden, welcher Spaltentyp benutzt werden soll, falls es notwendig werden sollte, Daten temporär zu speichern.
gp  char *ptr – Ein Zeiger, der für eigene Zwecke verwendet werden kann. Beispielsweise können Funktionen initid->ptr benutzen, um Informationen über den zugewiesenen Speicher zwischen den Funktionen zu kommunizieren, beispielsweise um in funktionsname_init() Speicher zuzuweisen und ihm den folgenden Zeiger zuzuordnen: initid->ptr = reservierter_speicher; In funktionsname() können Sie diesen Speicher anschließend verwenden, und in funktionsname_deinit() wird dieser wieder freigegeben.

Rheinwerk Computing

12.8.3 UDF_ARGS-Struktudowntop

Den Parameter args beinhaltet bis auf funktionsname_deinit() ebenfalls alle Funktionen. Dabei handelt es sich um einen Zeiger auf die UDF_ARGS-Struktur, die mit folgenden Strukturvariablen bestückt ist:

gp  unsigned int arg_count – Hier befindet sich die Anzahl der Argumente. Gewöhnlich wird dieser Wert in der Initialisierungsfunktion funktionsname_init() überprüft, wenn Sie wollen, dass Ihre Funktion mit einer bestimmten Anzahl von Argumenten aufgerufen wird. Beispiel der Anwendung:
if (args->arg_count != 3) {
    strcpy(message,"funktionsname() benötigt 3 Argumente");
    return 1;
}
gp  enum Item_result *arg_type – Hier befindet sich der Typ für die Argumente. Die Typenwerte können Sie mit den Konstanten STRING_RESULT, INT_RESULT und REAL_RESULT folgendermaßen überprüfen:
if (args->arg_type[0] != REAL_RESUL ||
    args->arg_type[1] != INT_RESULT ||
    args->arg_type[2] != STRING_RESULT) {
    strcpy( message,
            "funktionsname() erfordert eine Gleitkommazahl, "
            " einen Integer und einen String");
    return 1;
}
    Als Alternative dazu, dass Ihre Funktionsargumente von bestimmten Typen sein müssen, können Sie die Initialisierungsfunktion benutzen, um die arg_type-Elemente auf die Typen zu setzen, die Sie wollen. Das veranlasst MySQL, die Typen der Argumente bei jedem Aufruf von funktionsname() zu erzwingen. Um beispielsweise zu erzwingen, dass die ersten zwei Argumente Zeichenkette und Ganzzahl sind, geben Sie in funktionsname_init() Folgendes ein:
       
args->arg_type[0] = args->arg_type[1] = STRING_RESULT;
args->arg_type[2] = INT_RESULT;
    In funktionsname_init() daher, weil diese Funktion noch vor der eigentlichen Hauptfunktion funktionsname() aufgerufen wird.
       
gp  char **args – Hierbei handelt es sich um die tatsächlichen Argumente, mit denen die Funktion aufgerufen wurde (ähnlich wie argv in der main()-Funktion). Ist das Argument x z. B. ein konstanter Wert, zeigt args->args[x] auf den Argumentwert. Ist der Wert hingegen nicht konstant, ist args->args[x] 0. Was ein konstanter Wert ist, muss ich Ihnen nicht mehr erzählen. Ein nicht –konstantes Argument hingegen ist ein Ausdruck, der auf Werte verweist, die sich von Zeile zu Zeile ändern können wie Spaltennamen oder Funktionen, die mit nicht –konstanten Argumenten aufgerufen werden. Nach jedem Aufruf der Funktion funktionsname() enthält args->args die tatsächlichen Argumente, die für die Zeile übergeben wurden und momentan überarbeitet werden.
    Um den Wert von Argument x zu erhalten, gehen Sie je nach Datentyp wie folgt vor:
       
STRING_RESULT – Wird als ein Zeiger auf einen String mit einer bestimmten Länge angegeben, womit die Handhabung von Binärdaten oder Daten beliebiger Länge erlaubt ist – dank Längenangabe. Die Zeichenketteninhalte sind als args->args[x] und die Zeichenkettenlänge als args->lengths[x] verfügbar. Man darf auch hier niemals davon ausgehen, dass der String terminiert ist. INT_RESULT – Wird als Argument ein INT_RESULT übergeben, müssen Sie args–>args[x] zu einem long long-Wert casten: long long int_val = *((long long*) args->args[x]); REAL_RESULT – Wird als Argument ein REAL_RESULT übergeben, müssen Sie args–>args[x] zu einem long double-Wert casten: long double real_val = *((long double*) args->args[x])
gp  unsigned long *lengths – Hier befindet sich die Länge des Strings, für jedes Argument. Bei Argumenten des Typs INT_RESULT oder REAL_RESULT enthält lengths immer noch die maximale Länge des Arguments (wie bei der Initialisierungsfunktion).

Rheinwerk Computing

12.8.4 Rückgabewerdowntop

Die Initialisierungsfunktion funktionsname_init() sollte, wenn alles glatt verlief, 0, ansonsten bei einem Fehler 1 zurückliefern. Als Fehlermeldung sollten Sie einen terminierten String mit max. MYSQL_ERRMSG_SIZE Länge in den message-Parameter von funktionsname_init() schreiben. Der Rückgabewert von funktionsname() sollte entsprechend der Deklaration dem Wert entsprechen, wie dies C-typisch ist. Bei long long wird eben ein entsprechender Wert zurückgegeben. Bei einem String sollte ein Zeiger auf den Anfang plus der Länge des Strings zurückgegeben werden, z. B.:

memcpy(result, "ein_string_als_rueckgabe", 24);
*length = 24;

Wenn die Zeichenkette die Länge von 255 Bytes nicht überschreitet, müssen Sie sich nicht um die Speicherzuweisung von result kümmern. Ist Ihr Ergebnis allerdings länger, müssen Sie eine dynamische Speicherzuweisung mit malloc() in den Funktionen funktionsname_init() oder funktionsname() vornehmen. Sie können den zugewiesenen Speicher im ptr-Slot in der UDF_INIT-Struktur für eine erneute Benutzung durch zukünftige funktionsname()-Aufrufe speichern.

Wollen Sie den Rückgabewert NULL anzeigen, müssen Sie den Parameter is_null auf 1 setzen. Ebenso auf 1 setzen müssen Sie den error-Parameter, wenn Sie eine Fehlerrückgabe der Hauptfunktion anzeigen wollen.


Rheinwerk Computing

12.8.5 Benutzerdefinierte Funktionen erstelledowntop

Damit Sie eine Vorstellung davon bekommen, wie Sie benutzerdefinierte Funktionen erstellen können, soll anhand zweier Beispiele, STRING_RESULT und INT_RESULT, jeweils eine einfache Funktion erstellt werden.

Zuerst ein Beispiel zu einer benutzerdefinierten Funktion für Strings. Die Funktion erwartet einen Parameter als String und dreht diesen String anschließend einfach um – und gibt dies an den MySQL-Server zurück.

/* reverse.c */
#include <mysql/mysql.h>
#include <string.h>
#define MAX 255
char *
reverse (UDF_INIT * initid, UDF_ARGS * args, char *result,
         unsigned long *length, char *is_null, char *error) {
  char name_buf[256];
  int i, j;
  char c;
  if (!args->args[0]) {
    /* Return NULL for NULL values */
    *is_null = 1;
    return 0;
  }
  length = args->lengths[0];
  strcpy (name_buf, args->args[0]);
  for (i = 0, j = strlen (name_buf) - 1; i < j; i++, j--) {
    c = name_buf[i];
    name_buf[i] = name_buf[j];
    name_buf[j] = c;
  }
  memcpy (result, name_buf, (int)length);
  result[(int)length] = 0;
  return result;
}
my_bool
reverse_init (UDF_INIT * initid,UDF_ARGS * args,char *message) {
  if (args->arg_count == 1)
    args->arg_type[0] = STRING_RESULT;
  else {
    strncpy (message, "UPPER() mit einem Argument aufrufen!",
             MYSQL_ERRMSG_SIZE);
    return 1;
  }
  initid->max_length = sizeof (args->args[0]);
  initid->maybe_null = 1;
  return 0;
}

Das zweite Beispiel, ein Beispiel mit einem Integer als Rückgabewert, übernimmt eine Reihe von Zahlen und rechnet diese zu einer Gesamtsumme zusammen und gibt diesen Wert an den MySQL-Server zurück.

/* summe.c */
#include <mysql/mysql.h>
#include <string.h>
#include <stdlib.h>
long long
summe( UDF_INIT * initid, UDF_ARGS * args, char *is_null,
       char *error ) {
  long long summe=0;
  unsigned int i;
  for(i = 0; i<args->arg_count; i++)
    summe += *((long long *) args->args[i]);
  return summe;
}
my_bool
summe_init (UDF_INIT * initid, UDF_ARGS * args, char *message) {
  unsigned int i;
  if (args->arg_count < 1) {
    strncpy (message,
             "SUMME(): Mindestens 1 Argument angeben!",
             MYSQL_ERRMSG_SIZE);
    return 1;
  }
  for (i = 0; i < args->arg_count; i++)
    if (args->arg_type[i] != INT_RESULT) {
      strncpy (message,
               "SUMME(): Nur eine Ganzzahl als Argument!",
               MYSQL_ERRMSG_SIZE);
      return 1;
    }
  initid->maybe_null = 0;
  return 0;
}

Hinweis   Wenn Sie weitere Beispiele suchen, sollten Sie sich die MySQLSource-Distribution herunterladen. Dabei finden Sie einige UDF-Beispiele mit dem Namen udf_example.cc – weitere Beispiele finden Sie unter der URL http://empyrean.lib.ndsu. nodak.edu/~nem/mysql/udf/



Rheinwerk Computing

12.8.6 Benutzerdefinierte Funktion kompilieren, installieren und ausführetoptop

Wollen Sie eine Datei dynamisch ladbar machen, sollte diese als gemeinsame nutzbare Objektdatei kompiliert werden. Dies können Sie mit folgendem Befehl (als Beispiel die Stringfunktion reverse.c):

$ gcc -shared -o reverse.so reverse.c

Das gemeinsame Objekt reverse.so müssen Sie nun mit MySQL bekannt machen. Dazu sollten Sie diese Datei erst in den Pfad kopieren, den auch der dynamische Linker ld-linux.so durchsucht. Dieser Pfad kann von System zu System variieren. Meistens ist dies der Pfad /usr/lib oder /usr/local/lib. Sie können diesen aber auch über die Umgebungsvariable LD_LIBRARY_PATH so setzen, dass auf ein Verzeichnis gezeigt wird, wo sich die UDF-Funktionsdateien befinden. Ein Blick in die Manual Pages von dlopen() oder in ein späteres Kapitel verrät Ihnen dazu mehr.

Noch ein anderer eleganter Weg unter Linux wäre (Pfad zum lib-Verzeichnis bitte entsprechend anpassen):

$  mkdir /usr/local/lib/my_mysql_funcs
$  cd /usr/local/lib/my_mysql_funcs
$  cp /path/to/new/func ./
$  echo "/usr/local/lib/my_mysql_funcs" >> /etc/ld.so.conf
$  ldconfig

Unter BSD kann man hier die Variablen in der rc.conf setzen – doch dies führt hier zu weit.

Nachdem Sie die Bibliothek kopiert haben, können Sie den MySQL-Server mit der neuen Funktion bekannt machen (auch hier: Pfad zum lib-Verzeichnis bitte entsprechend anpassen):

$ gcc -shared -o reverse.so reverse.c
$ su
Password:********
# cp reverse.so /usr/local/lib
# rcmysql start
Starting service MySQL                                        done
# exit
exit
$ mysql -uroot -hlocalhost -pk4p6m3o3
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 3.23.55-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> CREATE FUNCTION reverse
    -> RETURNS STRING SONAME "reverse.so";
...
mysql> SELECT reverse(»Das ist ein langer Text«);
+------------------------------------+
| reverse("Das ist ein langer Text") |
+------------------------------------+
| txeT regnal nie tsi saD            |
+------------------------------------+
1 row in set (0.00 sec)

Neue Funktionen werden also mit CREATE FUNCTION angemeldet. Hier die genaue Syntax zum Anmelden von Funktionen in MySQL:

CREATE FUNCTION <funktionsname> RETURNS (STRING | REAL | INTEGER) 
SONAME <name der shared library>;

Wichtig dabei ist auch, dass der Funktionsname der Hauptfunktion im Listing entsprechen muss. Bei RETURNS müssen Sie den (richtigen) Datentyp angeben, der von der Hauptfunktion zurückgegeben wird. Hinter SONAME geben Sie den Dateinamen der UDF-Datei an. Wie schon erwähnt, ist der Ort der Datei zweitrangig, solange ld-linux.so die Datei über einen Suchpfad findet.

Wollen Sie zum Beispiel die Funktion summe() zum Addieren mehrerer Ganzzahlwerte bei MySQL anmelden, können Sie dies folgendermaßen machen (natürlich muss auch hier entsprechend kompiliert und die Datei installiert werden, wie Sie es zuvor gesehen und (hoffentlich) gemacht haben):

mysql> CREATE FUNCTION summe RETURNS INTEGER SONAME "summe.so";
...
mysql> SELECT summe(5, 5, 5, 6);
+-------------------+
| summe(5, 5, 5, 6) |
+-------------------+
|                21 |
+-------------------+
1 row in set (0.32 sec)

Selbst erstellte UDF-Funktionen können mit dem SQL-Befehl DROP FUNCTION wieder gelöscht werden:

mysql> DROP FUNCTION reverse;
mysql> DROP FUNCTION summe;

Die benutzerdefinierten Funktionen werden dabei in der Verwaltungsdatenbank mysql in der Tabelle func gespeichert, weshalb Sie oder der Entwickler der benutzerdefinierten Funktion auch entsprechende Schreibrechte für CREATE FUNCTION und Löschrechte für DROP FUNCTION benötigen.

mysql> USE mysql;
Database changed
mysql> SELECT * FROM func;
+---------+-----+------------+----------+
| name    | ret | dl         | type     |
+---------+-----+------------+----------+
| reverse |   0 | reverse.so | function |
| summe   |   2 | summe.so   | function |
+---------+-----+------------+----------+
2 rows in set (0.00 sec)

Wollen Sie entgegen der standardmäßigen Einstellung, dass die benutzerdefinierten Funktionen nicht beim Start vom MySQL-Server mitgeladen werden, müssen Sie den Server mit dem Flag –skip-grant-tables starten.

 << zurück
  
  Zum Rheinwerk-Shop
Neuauflage: Linux-UNIX-Programmierung
Neuauflage:
Linux-UNIX-
Programmierung

bestellen
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: Linux-Server






 Linux-Server


Zum Rheinwerk-Shop: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Rheinwerk-Shop: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Rheinwerk-Shop: Shell-Programmierung






 Shell-
 Programmierung


Zum Rheinwerk-Shop: Linux Handbuch






 Linux Handbuch


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
Info





Copyright © Rheinwerk Verlag GmbH 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern