Announcement

Collapse
No announcement yet.

Spaltenname aus einer FUNCTION beziehen?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spaltenname aus einer FUNCTION beziehen?

    Hallo Forum,

    ich muss immer wieder aus einer Tabelle mit ziemlich vielen Spalten Daten abrufen. Die Spalten haben irgendwelche kryptischen Namen (IDs). D.h. ich muss erstmal für die Klarnamen die Spalten heraus suchen und dann via Alias benennen, damit es handhabbar wird.
    [highlight=sql]
    SELECT `ID123456` AS `Datum`,
    `ID654321` AS `Benutzer`
    etc. pp.
    FROM `Tabelle`;
    [/highlight]
    Jetzt würde ich gerne mithilfe einer FUNCTION diese ID ermitteln und dann damit den Spaltenhinhalt abrufen. Quasi so:
    [highlight=sql]
    SELECT getColumnname('Datum') AS `Datum`
    getColumnname('Benutzer') AS `Benutzer`
    etc. pp.
    FROM `Tabelle`;
    [/highlight]
    In der Funktion getColumnname wird dann für den Klarnamen der zugehörige echte Spaltenname ermittelt und zurück geliefert. Diese Funktion habe ich schon. Das Problem ist jetzt, dass ich nicht den Inhalt des Datensatzes zurück bekomme, sondern nur den Namen der Spalte.

    Gibt es irgendeine Möglichkeit, die Rückantwort der Funktion als "echten Spaltennamen" statt nur eines Strings zu deklarieren und damit den jeweiligen Wert des Datensatzes zu bekommen statt nur den Spaltennamen?
    Zuletzt editiert von Wursel; 28.07.2017, 15:21.

  • #2
    Du könntest Dir das SQL Statement als String zusammenbauen und dann so wie hier beschrieben, das Statement ausführen. Allerdings solltest Du dann bei den Spaltennamen aufpassen, dass Du keine SQL Injection bekommst. Parameterisiert wird es vermutlich nicht gehen.

    Comment


    • #3
      Alles klar vielen Dank. Es funktioniert korrekt, wenn ich mit der Funktion einen String aufbaue und dann mit einem PREPARE / EXECUTE ausführe. Der Hinweis zur Sicherheit ist gut - da muss man echt aufpassen.

      Noch eine Frage: Verhält sich das PREPARE anders als eine direkte Abfrage? Ich habe manche Queries, die damit Fehler werfen. Mache ich die Abfrage 1:1 mit einem Direktaufruf, dann funktioniert es. D.h. da scheint es Unterschiede im Funktionsumfang zu geben? Oder das ist ein Bug in MariaDB 10.2. Ein Beispiel (macht nichts sinnvolles, ist nur eine aufs minimale reduzierte Query, um den Fehler sichtbar zu machen):
      [highlight=sql]
      SET @sql_query = "

      CREATE OR REPLACE VIEW `test` AS

      SELECT * FROM (
      SELECT CASE WHEN 1 IN (SELECT max(1)) THEN TRUE END AS `TestCase`
      ) queryout

      ";

      PREPARE stmt FROM @sql_query;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;
      [/HIGHLIGHT]
      Wirft unter MariaDB 10.2 einen Fehler:

      Code:
      SQL Fehler (1064): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '<in_optimizer>(1,<exists>(select max(1))) then 1 end AS `TestCase`) `queryout`' at line 1
      Führe ich CREATE VIEW direkt aus (ohne PREPARE), dann geht es. Und wenn ich o.g. PREPARE unter MySQL 5.7 ausführe, dann geht das auch. Es geht sogar unter MariaDB mit dem o.g. Code, wenn ich z.B. statt "max(1)" ein "ceil(1)" schreibe. Irgendwie seltsam! In der Meldung steht was von "optimizer". Ob der auf die Nase fällt?

      Comment


      • #4
        Als Update antworte ich mal auf mich selbst: Bezüglich meiner Frage zu PREPARE und etwaigen Unterschieden zum normalen "nicht PREPARE" Ausführen:

        1. Diese Fehlermeldung: Das ist definitiv ein Bug in MariaDB! Ich habe noch mal weitere Queries mit MariaDB 10.2.7 vs MySQL 8.0.2 getestet und bei ersterer gibt es seltsame Fehlermeldungen in bestimmten Konstellationen, während MySQL einwandfrei läuft und das richtige Ergebnis anzeigt.
        2. Bei einer anderen Query (CTE mit multiplen Subqueries), bei der ich dachte es gäbe noch Unterschiede, geht es sowohl als auch (MariaDB & MySQL) - ich musste nur etwas umstellen/beachten, damit das geschluckt wurde.

        D.h. unter MySQL 8.0.2 (und höher) könnte ich nun tatsächlich, wie von fanderlf vorgeschlagen, den String zusammen bauen und mit PREPARE / EXECUTE zur Verfügung stellen => genial! Leider ist die MySQL 8 noch im Alpha Status und daher nicht so wirklich für Produktiveinsatz zu empfehlen... Und MariaDB läuft nicht richtig. Was tun? Vielleicht probiere ich mal einen Bug-Report bei denen zu erstellen. Wenn ich Glück habe, dann wird das gefixed und wandert in die nächste stabile Version. Mal schauen.

        Comment


        • #5
          Oracle database hat sehr ausgefeilte Methoden (Packages) für dynamisches SQL.
          Ich könnte mir vorstellen, dass Postgres ähnliches zu bieten hat. (Siehe auch anderer Thread von Dir)
          Gruß, defo

          Comment

          Working...
          X