Funktionsaufrufe in SQL (Funktionsaufrufe in SQL), Lektion, Seite 722398
https://www.purl.org/stefan_ram/pub/funktionsaufrufe_sql_de (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
SQL-Kurs

Funktionsaufrufe in MySQL 

Einführendes Beispiel

Die folgende Eingabe gibt eine mehr oder weniger zufällig ausgewählte DOUBLE-Zahl zwischen 0 (einschließlich) und 1 (ausschließlich) aus.

Eingabe
SELECT RAND();
Ausgabe
+-------------------+
| RAND() |
+-------------------+
| 0.901730651875707 |
+-------------------+

Bei der Auswertung des Ausdrucks »RAND()« wird das Programm »RAND« gestartet. Dieses legt für den Aufrufausdruck »RAND()« dann einen Wert zwischen 0 und 1 fest.

Anders gesagt: Immer wenn MySQL den Wert des Ausdrucks »RAND()« erfahren will, ruft es das Programm »RAND« auf, welches den Wert dann mitteilt.

Die Schreibweise von Aufrufen

Ein Ausdruck kann mit einem Namen geschrieben werden, dem ein Paar runder Klammern »(« »)« folgt.

Syntax eines Aufrufs »()«
Ausdruck
.------. .-. .-.
--->| Name |--->· ( ·-->· ) ·-->
'------' '-' '-'

Es handelt sich hierbei um insgesamt drei  lexikalischen Einheiten: Einen Namen, eine runde Klammer auf »(« und eine runde Klammer zu »)«.

Neue, erweiterte Syntax (vereinfacht)
Ausdruck
.----------.
---.----------->| Literal |---------------------------.---->
| '----------' |
| .----------. |
'----------->| Name |---------------------------'
| '----------' |
| .----------. .-. .-. |
'----------->| Name |--->( ( )--->( ) )---------'
| '----------' '-' '-' |
| .-. .----------. |
'--->( - )-->| Ausdruck |---------------------------'
| '-' '----------' |
| .-. .----------. |
'--->( + )-->| Ausdruck |---------------------------'
| '-' '----------' |
| .-. .----------. .-. |
'--->( ( )-->| Ausdruck |-->( ) )-------------------'
| '-' '----------' '-' |
| .----------. .-. .----------. |
'----------->| Ausdruck |-->( * )-->| Ausdruck |----'
| '----------' '-' '----------' |
| .----------. .-. .----------. |
'----------->| Ausdruck |-->( / )-->| Ausdruck |----'
| '----------' '-' '----------' |
| .----------. .---. .----------. |
'----------->| Ausdruck |->( DIV )->| Ausdruck |----'
| '----------' '---' '----------' |
| .----------. .-. .----------. |
'----------->| Ausdruck |-->( + )-->| Ausdruck |----'
| '----------' '-' '----------' |
| .----------. .-. .----------. |
'----------->| Ausdruck |-->( - )-->| Ausdruck |----'
'----------' '-' '----------'

Im Falle dieser hier neu vorgestellten Schreibweise nennen wir die runden Klammern auch Aufrufklammern  und den damit geschrieben Ausdruck einen Aufrufausdruck.

Vergleich mit dem Zirkumfixoperator »(« »)«

Die hier neu vorgestellte Schreibweise von Aufrufen mit Klammern »(« »)« ist nicht  mit dem früher eingeführten Zirkumfixoperator »(« »)« zu verwechseln, dessen Klammern wir auch als „Ausdruckklammern“ bezeichnet hatten.

Syntax des schon früher behandelten Zirkumfixoperators »(« »)«
Ausdruck
.-. .----------. .-.
--->· ( ·--->| Ausdruck |--->· ) ·-->
'-' '----------' '-'

Die hier neu behandelten Aufrufklammern  stehen immer direkt hinter einem Funktionsnamen, wie beispielsweise in »RAND()« und bilden mit ihm zusammen einen Ausdruck, während die früher behandelten Ausdruckklammern um einen Ausdruck herum  geschrieben werden und mit diesem einen neuen Ausdruck, wie beispielsweise »(65)«, bilden.

(Wir sagen, daß Klammern leer  seien und direkt  hinter einen Namen stehen, auch wenn die Klammern noch Leerraum enthalten oder von dem voranstehenden Namen durch Leeraum getrennt sind, da Leerraum hier keine Rolle spielt.)

Funktionsnamen

Die Groß- und Kleinschreibung von Funktionsnamen nicht  signifikant (das heißt: die Groß- und Kleinschreibung von Funktionsnamen ist egal.)

Der eben neu eingeführte Aufrufausdruck  beginnt mit einem Namen, allerdings sind nur bestimmte Namen erlaubt. Wir zeigen hier zunächst ein Beispiel mit dem Namen »RAND«.

Eingabe
SELECT RAND();
Ausgabe (gekürzt)
0.5630878568955987

(Eine mögliche Aussprache von “random ” ist /ˈˈrænd/.)

Der Name »RAND« steht für ein Programm, welches zur Laufzeit bei der Auswertung des Aufrufsausdrucks »RAND« gestartet wird.

Solch ein Programm, das von einem anderen Programm aus aufgerufen wird, wird auch als Unterprogramm  bezeichnet. Insbesondere in SQL  nennt man solch ein Unterprogramm manchmal eine Funktion. »RAND« ist eine Funktion.

Als Name im Aufrufausdruck sind nur Namen erlaubt, die auch eine Funktion bezeichnen. Solche Namen bezeichnen wir als Funktionsnamen.

Die Schreibweise eines Ausdrucks mit einem Funktionsnamen und einem folgenden Paar runder Klammern nennen wir einen Funktionsaufrufausdruck  oder – kurz – einen Aufrufausdruck.

Funktionsnamen sind im allgemeinen keine  Ausdrücke, sie haben also im allgemeinen keinen Wert! Während also beispielsweise der Spaltenname »VORNAME« ein Ausdruck ist, ist »RAND« alleine kein  Ausdruck. Man kann »RAND« lediglich als einen Namen  oder als eine Angabe  bezeichnen.

Das folgende Beispiel zeigt, daß es in MySQL  im allgemeinen erlaubt ist, eine Spalte mit dem Namen einer Funktion anzulegen.

Konsole
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET sql_mode = '';
DROP SCHEMA IF EXISTS S; CREATE SCHEMA S; USE S;
CREATE TABLE A ( RAND VARCHAR( 255 ) );
INSERT INTO A ( RAND ) VALUES ( 'alpha' );

In älteren Versionen von MySQL  mußte man darauf achten, daß bei einem Funktionsaufruf die runde Klammern auf »(« immer direkt auf den Funktionsnamen folgt. Umgekehrt sollte auf Namen, die keinen Funktionsnamen sein sollen, nie direkt einee runden Klammer auf »(« folgen; sie sollte beispielsweise mit einem Leerzeichen abgetrennt sein. In neueren Versionen von MySQL  ist diese Unterscheidung für viele Funktionen nicht mehr so wichtig, aber es gibt immer noch einige Funktionen, bei denen sie beachtet werden muß.

Das folgenden Beispiel zeigt, daß im Falle des Namens »RAND« das Leerzeichen keine Rolle spielt. Wenn dem Name keine Klammern folgen, so steht er für die Spalte »RAND«, wenn ihm Klammern folgen, so steht er für die Funktion »RAND«. Trotzdem sollten Funktionsaufrufe immer ohne  Leerzeichen zwischen Funktionsnamen und der Runden Klammer auf »(« geschrieben werden und alle anderen Fälle mit  (wie beispielsweise oben »TABLE A («).

Konsole

SET sql_mode = '';

SELECT RAND, RAND(), RAND () FROM A;

+-------+--------------------+--------------------+
| RAND | RAND() | RAND () |
+-------+--------------------+--------------------+
| alpha | 0.3467589452366894 | 0.5823355238720174 |
+-------+--------------------+--------------------+

Die Einstellung »IGNORE_SPACE« ändert das Verhalten von MySQL  in Zusammenhang mit dem angesprochenen Leerzeichen etwas ab. Aber dies betrifft nur wenige kritische Funktionsnamen. Im Falle der Funktion »RAND« ändert sich durch dieses Einstellung nichts.

Konsole

SET sql_mode = 'IGNORE_SPACE';

SELECT RAND, RAND(), RAND () FROM A;

+-------+--------------------+---------------------+
| RAND | RAND() | RAND () |
+-------+--------------------+---------------------+
| alpha | 0.5241132690795821 | 0.38381974434835814 |
+-------+--------------------+---------------------+

Ohne  »IGNORE_SPACE« wird ein Name mit einer folgenden runden Klammern auf »(« immer  als Funktionsname angesehen.

Mit  »IGNORE_SPACE« darf in vielen Fällen auch Leerraum zwischen Funktionsnamen und einer folgenden runden Klammer auf »(« eingefügt werden. Dadurch können einige Funktionsnamen aber nicht mehr als Namen für andere Zwecke verwendet werden, da sie dann dort nicht mehr durch ein folgendes Leerzeichen als Name für andere Zweck gekennzeichnet werden können. (Allerdings könnten solche Namen durch Zitieren doch noch für andere Zwecke verwendet werden.) »IGNORE_SPACE« wird auch durch »ANSI« aktiviert.

In einem Funktionsaufruf sollte die runde Klammer auf »(« direkt hinter dem Funktionsnamen stehen.

In allen anderen Fällen sollte zwischen einem Wort und einer runden Klammer auf »(« ein Leerzeichen stehen.

Weitere Quellen zu diesem Thema *

http://dev.mysql.com/doc/en/function-resolution.html

http://dev.mysql.com/doc/en/sql-mode.html

http://en.wikibooks.org/wiki/MySQL/Language/Functions

Die Auswertung von Aufrufausdrücken

Die Funktion »RAND« legt – wie gesagt – beim Ablauf des obenstehenden Programms den Wert des Aufrufausdrucks »RAND()« fest. Jener Wert wird dann von unserem Aufrufrahmen ausgegeben.

»RAND()« bedeutet: „Der Wert dieses Ausdrucks soll von dem Programm »RAND« festgelegt werden.“

Bei der Auswertung eines Aufrufausdrucks wird also das von dem Funktionsnamen angegebene Programm (die Funktion) gestartet (den nur dann kann jenes Programm den Wert des Aufrufausdrucks festlegen). Den Start und die Ausführung jenes Programms nennt man auch Aufrufvorgang.

Die Auswertung eines Aufrufausdrucks  der Eingabe bewirkt den Aufrufvorgang  bei der Abarbeitung der Eingabe.

Wenn es dem Zusammenhang entnommen werden kann, ob ein Aufrufausdruck  oder ein Aufrufvorgang  gemeint ist oder wenn die Unterscheidung nicht wichtig ist, spricht man einfach nur von einem Aufruf.

Startet man dasselbe Programm ein zweites  Mal, so kann ein anderer  Wert erscheinen:

Eingabe
SELECT RAND();
Ausgabe
0.522884334994247
Eingabe
SELECT RAND();
Ausgabe
0.8528461445615125

Der Wert des Aufrufausdrucks »RAND()« ist ein double-Wert, der bei jeder seiner Auswertungen (bei jeder Programmausführung) zwischen 0 (einschließlich) und ‹ 1−2⁻⁵³ › (also 0,99999999999999988897769753748434595763683319091796875) (einschließlich) liegt; man sagt auch, er liege zwischen 0 (einschließlich) und 1 (ausschließlich). Mehrere Auswertungen ergeben mehr oder weniger zufällige  Werte, die gleichmäßig über diesen Bereich verteilt sind, die sogenannten Pseudozufallszahlen.

Sortieren nach Zufallszahlen

Im folgenden Beispiel wird eine zufällige Zeile aus einer Tabelle ausgewählt, indem die Tabelle zunächst nach Zufallszahlen sortiert wird (»ORDER BY RAND()« wertet »RAND()« für jede Zeile neu aus) und dann die oberste Zeile ausgewählt wird.

main.sql

WARNINGS; SET sql_mode = 'ANSI,TRADITIONAL';
DROP SCHEMA IF EXISTS S; CREATE SCHEMA S; USE S;

CREATE TABLE KUNDE ( KUNDE INT PRIMARY KEY, VORNAME VARCHAR( 255 ), NACHNAME VARCHAR( 255 ));
INSERT INTO KUNDE( KUNDE, VORNAME, NACHNAME )VALUES( 23, 'Friederike', 'Nordbeck' );
INSERT INTO KUNDE( KUNDE, VORNAME, NACHNAME )VALUES( 2, 'Michael', 'Rosowski' );
INSERT INTO KUNDE( KUNDE, VORNAME, NACHNAME )VALUES( 14, 'Birgit', 'Rosowski' );
INSERT INTO KUNDE( KUNDE, VORNAME, NACHNAME )VALUES( 9, 'Bodo', 'Rosowski' );
INSERT INTO KUNDE( KUNDE, VORNAME, NACHNAME )VALUES( 6, 'Simon', 'Rosowski' );
INSERT INTO KUNDE( KUNDE, VORNAME, NACHNAME )VALUES( 5, 'Frank', 'Aldegeerds' );
INSERT INTO KUNDE( KUNDE, VORNAME, NACHNAME )VALUES( 1, 'Eelco', 'Fischbach' );

SELECT VORNAME, NACHNAME FROM KUNDE ORDER BY RAND() LIMIT 1;

Protokoll
+---------+-----------+
| VORNAME | NACHNAME |
+---------+-----------+
| Eelco | Fischbach |
+---------+-----------+
Protokoll (Erneutes Ausführen derselben SELECT-Abfrage)
+---------+----------+
| VORNAME | NACHNAME |
+---------+----------+
| Simon | Rosowski |
+---------+----------+

Weitere nützliche Funktionen

Anzeige des Namens der mit »USE« eingestellten Datenbank

SELECT DATABASE();
SELECT SCHEMA();

Anzeige der Version des Datenbanksystems

SELECT VERSION();

Die Kreiszahl

SELECT PI();

Der Benutzer, wie er sich ausgab

SELECT USER();
SELECT SESSION_USER();
SELECT SYSTEM_USER();

Der vom Server zugeteilte Benutzer

SELECT CURRENT_USER();

Kennung der aktuellen Datenbankverbindung

SELECT CONNECTION_ID();

Anzahl der durch das letzte Einfügekommando veränderten Zeilen

SELECT ROW_COUNT();

Mehr Erklärungen dazu

http://dev.mysql.com/doc/en/information-functions.html

Übungsfragen

?   Lexikalische Einheiten zählen

Wie viele lexikalische Einheiten  enthält der Aufrufausdruck »RAND()«?

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram722398 stefan_ram:722398 Funktionsaufrufe in SQL Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd722398, slrprddef722398, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/funktionsaufrufe_sql_de