Laufzeitwerte in SQL (MySQL )
Das folgende Transkript zeigt die Ausgabe einer mehr oder weniger zufällig ausgewählten double-Zahl zwischen 0 (einschließlich) und 1 (ausschließlich) aus.
Konsole
SELECT RAND();
+--------------------+
| RAND() |
+--------------------+
| 0.3169153596432091 |
+--------------------+
Die zur Laufzeit stattfindende Auswertung eines Funktionsaufrufs ist ein Vorgang (Geschehen, Ablauf), während der Funktionsaufrufausdruck ein Teil des Quelltextes (also der Eingabe des Programmierers) ist.
Am Vorgang der Auswertung des Ausdrucks
- RAND()
ist noch besonders zu bemerken, daß es sich zwar um eine eindeutig bestimmte Funktion handelt, ihr Wert aber nicht bestimmt ist. Er kann bei jeder Ausführung der Funktion ein anderer sein. (Das heißt: Die Auswertung dieses Ausdrucks kann jedes Mal einen anderen Wert ergeben.)
Konsole
SELECT RAND();
+--------------------+
| RAND() |
+--------------------+
| 0.6655208418755986 |
+--------------------+SELECT RAND();
+--------------------+
| RAND() |
+--------------------+
| 0.9471301193787997 |
+--------------------+
Hierin unterscheidet sich das Programmieren von der Mathematik, wo ein Term wie ‹cos( 0 )› immer den gleichen Wert hat (also immer einen bereits durch diesen Term vollständig und eindeutig bestimmten Wert).
Man nennt Werte, die erst bei der Ausführung eines Programms (also einer SQL-Eingabe oder SQL-Abfrage) ermittelt werden, Laufzeitwerte. Das bedeutet, daß nicht schon der Aufrufausdruck den Wert festlegt, sondern erst der Aufrufvorgang (also die Auswertung). Derselbe Aufrufausdruck kann bei zwei verschiedenen Aufrufvorgängen (wie oben), also zur Laufzeit, zwei verschiedenen Werte haben. Der Aufrufausdruck steht im Quelltext für den Laufzeitwert, der sich bei jeweils einem Aufrufvorgang ergibt.
Der Aufrufausdruck »RAND()« bezieht sich immer auf dieselbe Funktion, aber diese Funktion kann bei verschiedenen Ausführungen, verschiedene Werte für den Aufrufausdruck liefern. Durch einen Aufrufausdruck kann also ein erst beim Programmablauf festgelegter Laufzeitwert angegeben werden, während ein Literal immer denselben Wert hat.
Da zwei Auswertungen desselben Ausdrucks unterschiedliche Werte liefern können, hängt der Wert von der Auswertung ab, nicht vom Ausdruck. Daher kann man nicht immer sagen, daß ein bestimmter Ausdruck einen bestimmten Wert hat, sondern nur, daß eine bestimmte Auswertung eines bestimmten Ausdrucks einen bestimmten Wert hat.
Der Wert eines Ausdrucks hingegen ist dynamisch. Es ist möglich, daß er erst zur Laufzeit festgelegt wird. Dadurch kann ein Programm flexibler an die Umstände während seiner Ausführung angepaßt werden. Andererseits ist es dadurch möglich, daß Fehler, die nur bei bestimmten Werten auftreten, vom Programmierer nicht bemerkt werden, weil dieser nicht alle möglichen Werte durchprobieren kann.
Verschiedene Werte in verschiedenen Abfragen
Verschiedene Werte des Ausdrucks »RAND()« in verschiedenen Abfragen haben wir schon gesehen.
- Konsole
SELECT RAND();
+---------------------+
| RAND() |
+---------------------+
| 0.16288185414195233 |
+---------------------+SELECT RAND();
+--------------------+
| RAND() |
+--------------------+
| 0.9462325600406458 |
+--------------------+
Verschiedene Werte in verschiedenen Spalten
Auch wenn ein Ausdruck mehrfach in derselben Abfrage vorkommt, wird er bei jedem einzelnen Vorkommen (für jede Spalte) neu ausgewertet. Daher kann derselbe Ausdruck in derselben Abfrage mehrere verschiedene Werte haben.
- Konsole
SELECT RAND(), RAND();
+--------------------+-------------------+
| RAND() | RAND() |
+--------------------+-------------------+
| 0.2425172685110171 | 0.373888693166793 |
+--------------------+-------------------+
Verschiedene Werte in verschiedenen Zeilen
Aber auch, wenn ein Ausdruck nur einmal ein einer einzigen Abfrage vorkommt, kann er mehrere verschiedene Werte haben, weil er für jede Zeile der zugrundeliegenden Basistabelle erneut ausgewertet wird!
- Konsole
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET SESSION sql_mode = 'ANSI,TRADITIONAL';
DROP SCHEMA S; CREATE SCHEMA S; USE S;CREATE TABLE FOUR ( COL VARCHAR ( 1 ));
INSERT INTO FOUR ( COL ) VALUES ( 'A' ),( 'B' ),( 'C' ),( 'D' );SELECT RAND() FROM FOUR;
+---------------------+
| RAND() |
+---------------------+
| 0.14189169103455887 |
| 0.5877924064060602 |
| 0.5132869896602695 |
| 0.8030577598168122 |
+---------------------+
Schließlich kann man auch Auswertungen eines Ausdrucks für mehrere Zeilen und mehrere Spalten vornehmen lassen.
- Konsole
SELECT RAND(), RAND(), RAND() FROM FOUR;
+---------------------+---------------------+--------------------+
| RAND() | RAND() | RAND() |
+---------------------+---------------------+--------------------+
| 0.4754278608368969 | 0.9679660554676932 | 0.4135467255614202 |
| 0.16383549213766632 | 0.5785373147377161 | 0.4011801280092263 |
| 0.2702887265666283 | 0.14790327953910762 | 0.9286502487292981 |
| 0.1995414357628128 | 0.21175646335981457 | 0.4601580402442795 |
+---------------------+---------------------+--------------------+