MySQL-Variablen für Spaltennamen (und andere Identifier) verwenden

Variablen lassen sich in MySQL hervorragend für Strings, Zahlenwerte oder auch binäre Daten verwenden. Möchte man diese Variablen jedoch zum Adressieren von Spalten, Tabellen oder Datenbanken verwenden, dann erfordert dies ein etwas anderes Vorgehen. Dieser Artikel gibt eine kurze Zusammenfassung, wie man MySQL-Variablen in Abfragen einsetzt.

Variablen für Daten (Grundsyntax)

Zunächst einmal die allgemeine VerwendungFolgendes Beispiel zeigt eine einfachste Verwendung von Variablen:

SET @t1=1, @t2=2, @t3:=4;
-- Query OK, 0 rows affected (0.00 sec)
SELECT @t1, @t2, @t3, @t4 := @t1+@t2+@t3;
-- +------+------+------+--------------------+
-- | @t1  | @t2  | @t3  | @t4 := @t1+@t2+@t3 |
-- +------+------+------+--------------------+
-- |    1 |    2 |    4 |                  7 | 
-- +------+------+------+--------------------+
-- 1 row in set (0.00 sec)

Nutzt man Variablen, um Spaltennamen dynamisch anzusprechen, dann ist dies mit der einfachen Variablen-Syntax jedoch nicht möglich, wie folgendes Beispiel zeigt:

SET @col = "c1";
-- Query OK, 0 rows affected (0.00 sec)
SELECT @col FROM t;
-- +------+
-- | @col |
-- +------+
-- | c1   |
-- +------+
-- 1 row in set (0.00 sec)
SELECT `@col` FROM t;
-- ERROR 1054 (42S22): Unknown column '@col' in 'field list'

Hierbei wird c1 ebenfalls als String interpretiert und dabei nicht auf die Daten der eigentlichen Spalte zugegriffen. Die Ausgabe liefert nur den Inhalt ‘c1’ der Variablen zurück.

Variablen für Spaltennamen (Identifier) verwenden

Um Variablen auch für Spaltennamen bzw. Identifier verwenden zu können, muss man etwas weiter ausholen. Das Prinzip ist folgendes: man erstellt sich einen String, welcher der Abfrage entspricht und führt diese anschließend aus. Diese Methode erlaubt das Adressieren jeglicher Identifier (Spalten, Tabellen, Datenbanken, …) in MySQL. Nachfolgendes Beispiel soll dieses Vorgehen genauer erläutern.

Zunächst setzt man wie gewohnt die Inhalte der Variablen:

SET @c = "c1";
-- Query OK, 0 rows affected (0.00 sec)

Anschließend erstellt man einen String (ebenfalls in einer Variablen), welche die SQL-Abfrage enthält:

SET @s = CONCAT("SELECT ", @c, " FROM t");
-- Query OK, 0 rows affected (0.00 sec)

… bereitet die Abfrage vor:

PREPARE stmt FROM @s;
-- Query OK, 0 rows affected (0.04 sec)
-- Statement prepared

… und führt sie aus:

EXECUTE stmt;
-- +----+
-- | c1 |
-- +----+
-- |  0 |
-- +----+
-- |  1 |
-- +----+
-- 2 rows in set (0.00 sec)

Über DEALLOCATE PREPARE wird die erstellte Abfrage wieder freigegeben:

DEALLOCATE PREPARE stmt;
-- Query OK, 0 rows affected (0.00 sec)

Die Syntax von PREPARE, EXECUTE und DEALLOCATE PREPARE wird unter 12.5. SQL Syntax for Prepared Statements des MySQL-Manuals genauer erläutert.

5 comments on “MySQL-Variablen für Spaltennamen (und andere Identifier) verwenden

  1. Wirklich sehr schön erklärt, danke! Genau was ich gesucht habe und was natürlich in der MySQL Doku nicht sauber dokumentiert wurde.

    Hätte ich auch selbst drauf kommen können (im Nachhinein) 😉

    Viele Grüße!

  2. hallo;
    was habe ich denn hier falsch gemacht ? Ich bekomme für $anz nichts angezeigt.
    Vielen Dank;
    Michael Saxer

    $db->query("SET @a1 = 'test'");
    $db->query("SET @a2 = CONCAT('SELECT * FROM ', @a1)"); 
    $db->query("PREPARE a3 FROM @a2");
    $erg = $db->query("EXECUTE a3");
    $anz = $erg->num_rows;
    echo $anz;
    1. Hallo Michael,

      die 4 Abfragen habe ich lokal getestet und nacheinander ausgeführt. Diese sind so korrekt und bringen das gewünschte Ergebnis.

      Lass dir mal die letzten MySQL-Fehler anzeigen. Existiert die Datenbank ‘test’ auch? Welches PHP-System/Framework oder welche Klasse nutzt du im Hintergrund für die Verbindung zu MySQL?

      Grüße,
      Mathias

Leave a Reply to Wolfgang Cancel reply

Your email address will not be published. Required fields are marked *