Historisch gesehen waren die Aufgaben dynamischer Berichte mit variabler Gruppierungsanzahl im SQL-Standard nicht vorgesehen — SQL ist für statisch beschriebene Abfragen mit klar definiertem Ergebnis-Schema ausgelegt. Mit dem Aufkommen von BI-Plattformen und interaktiven Dashboards suchten Programmierer nach Möglichkeiten, SQL-Abfragen "on-the-fly" zu konstruieren, um auf Benutzeranfragen komplexe multiple Datenschnitte zu erstellen.
Problem — SQL kann nicht mit normaler if/else-Logik innerhalb von SELECT programmiert werden — die Anzahl der Spalten, die Felder selbst und sogar GROUP BY werden nur zur Zeit der Kompilierung der Abfrage bestimmt. Wenn der Benutzer einen Schnitt von mehreren beliebigen Feldern wünscht, muss der Text der Abfrage dynamisch zusammengebaut und über EXECUTE/Dynamic SQL ausgeführt werden.
Lösung:
Man realisiert die Generierung von SQL-Code in einer externen Anwendung und ruft dies anschließend über EXEC/EXECUTE auf. In einigen Fällen verwendet man für einfache Aufgaben CASE und starre Vorlagen, für Flexibilität greift man jedoch immer auf dynamisches SQL zurück:
Beispielcode (Pseudocode):
-- Auf der Anwendungsseite (z. B. Python) groups = ['region', 'channel', 'month'] columns = [f'SUM({col}) AS {col}_sum' for col in selected_metrics] group_by = ', '.join(groups) selects = ', '.join(groups + columns) query = f'SELECT {selects} FROM sales GROUP BY {group_by}' -- Dann wird diese Abfrage über das application/sql-Interface gesendet
In einem DBMS, das EXECUTE unterstützt:
DECLARE @sql NVARCHAR(MAX); SET @sql = N'SELECT ' + @selects + ' FROM sales GROUP BY ' + @group_by + ';'; EXEC sp_executesql @sql;
Wichtige Merkmale:
Kann man eine dynamische Veränderung der Anzahl von Spalten (pivot/unpivot) nur über standard SQL ohne dynamisches SQL umsetzen?
Nein — nur zuvor bekannte Werte können über CASE/DECODE "entfaltet" werden, aber eine unbekannte Anzahl von Spalten wird nur dynamisch erreicht.
Garantiert Ihre Logik für dynamisches SQL Schutz vor Injektionen, wenn Sie String-Konkatenation verwenden?
Nein, manuelle String-Konkatenation ist ein ständiges Risiko für SQL Injection. Es ist unbedingt erforderlich, die Liste der Felder/Gruppierungen durch Whitelisting zu validieren, benutzerdefinierte Fragmente ohne Prüfung zu vermeiden und wo möglich, Parameter zu verwenden.
Kann GROUP BY eine Liste von Spalten über eine Variable akzeptieren?
Der Standard-SQL unterstützt nicht die Übergabe einer Liste von Feldern in GROUP BY über eine Variable/Parameter. Der Text der Abfrage muss dynamisch gebildet werden — man kann einfach keine Variable in der GROUP BY-Liste verwenden.
Ein BI-Ingenieur erlaubte dem Benutzer, direkt aus der Anwendungsschnittstelle Feldnamen für den Bericht zu übermitteln, ohne diese über Whitelisting zu filtern. Infolgedessen wurde bei einem Injektions-Test die Produktions-Tabelle durch eingefügten schädlichen Code im Feldnamen "heruntergefahren".
Vorteile:
Nachteile:
Ein Ingenieur implementierte eine strenge Validierung der Namen — der Benutzer konnte nur aus erlaubten Spalten (aus config/metadata) wählen, dynamisches SQL wurde nur über Whitelisting zusammengestellt, es gab keine Wege für Injektionen.
Vorteile:
Nachteile: