In dem letzten Artikel wurden die Views SYSRPOGRAMSTAT und SYSPROGRAMSTMTSTAT mit embedded SQL ermittelt und statische SQL-Abfragen innerhalb der Programme lokalisiert. Mit diesen Funktionen können die SQL-Statements jedoch nicht analysiert werden. Dies kann allerdings mit der Tabellen-Funktion PARSE_STATEMENT, die in diesem Artikel vorgestellt wird, erfolgen.
Mit Hilfe der Tabellen-Funktion PARSE_STATEMENT können in Text-Form übergebene SQL-Statements analysiert werden. Das Ergebnis ist eine Liste von Datenbank-Objekten und Spalten-Namen, die in dem übergebenen SQL-Statement verwendet werden.
Die Tabellen-Funktion PARSE_STATEMENT wird mit den folgenden Parametern aufgerufen:
- SQL_STATEMENT
In diesem Parameter wird das zu analysierende SQL-Statement komplett aufbereitet angegeben. Dabei ist zu berücksichtigen, dass alle einfachen Hochkommata verdoppelt werden müssen. Das übergebene Statement selbst kann bis zu 2 MB groß sein.
Bei den zu analysierenden SQL-Statements kann es sich um alle Arten von Statements handeln, also z. B. SELECT, UPDATE, INSERT, DELETE, aber auch z. B. Erstellungsbefehle für Tabellen, Views, Stored Procedures etc. oder Aufruf-Befehle für Stored Procedures. - NAMING
Bei diesem Parameter wird angegeben, ob für das übergebene SQL-Statement System- oder SQL Naming Conventions verwendet werden. Zulässige Werte sind:- *SYS – System-Naming Conventions (Default)
unqualifiziert angegebene Objekte werden in der Bibliotheksliste gesucht, jedoch leider nicht bei der Analyse durch PARSE_STATEMENT.
Bei unqualifiziert angegebenen Objekten wird das zugehörige Schema nicht ermittelt und stattdessen ein NULL-Wert ausgegeben. - *SQL – SQL-Naming Conventions
unqualifiziert angegebene Tabellen, View werden in dem Default-Schema gesucht. SQL Routines (Stored Procedures, User Defined Functions …) werden in dem SQL Path gesucht.
- *SYS – System-Naming Conventions (Default)
Anmerkung:
Vor Release 7.1 TR 5 musste beim System-Naming zwischen Schema und Objekt das Trennzeichen Slash (/) und beim SQL-Naming das Trennzeichen Punkt (.) verwendet werden.
Diese Regel wurde für das System-Naming aufgehoben, d. h. es kann sowohl er Punkt als auch der Slash als Trennzeichen zwischen Schema und Objekt verwendet werden.
Beim SQL-Naming ist jedoch weiterhin nur der Punkt zulässig.
- DECIMAL_POINT
Bei diesem Parameter wird angegeben welches Dezimal-Trennzeichen übergeben wird. Zulässige Werte sind:- *PERIOD oder . (Punkt) à Default
- *COMMA oder , (Komma)
Wird innerhalb des SQL-Strings das Dezimal-Trennzeichen Komma verwendet, muss dieser Parameter-Werte angegeben werden.
Anderenfalls wird das Komma (in Zahlen) als SQL-Trennzeichen interpretiert, was zu falschen Ergebnissen führen kann.
Anmerkung:
Wird mit Dezimal-Trennzeichen Komma gearbeitet, sollte nach jedem SQL-Trennzeichen (Komma) ein Blank angegeben werden.
Ansonsten kann es, insbesondere an Stellen, an denen Zahlen durch Trennzeichen getrennt werden, zu Fehlinterpretationen und damit zu Fehlern kommen. Wird bei Dezimal-Trennzeichen Komma z. B. DEC(11,2) angegeben, so wird 11,2 als eine einzige Zahl interpretiert. Die Funktion DEC() benötigt jedoch zwei Parameter. Dadurch wird ein Fehler festgestellt.
- SQL_STRING_DELIMITER
Bei diesem Parameter wird angegeben welche Begrenzung um alphanumerische Werte verwendet wird.- *APOSTSQL oder ‘ (einzelnes Hochkomma) à Default
- *QUOTESQL oder ” (Anführungszeichen)
Anmerkung:
Einzelne Hochkommata müssen in einem String verdoppelt werden.
In der Ausgabe wird pro Objekt eine Zeile ausgegeben. Die Objekte und Spalten werden genau in der Reihenfolge, in der sie in dem zu analysierenden SQL-Statement hinterlegt sind, aufgelistet.
Bei unqualifiziert angegebenen Objekten wird das zugehörige Schema weder unter der Verwendung von System-Naming-Conventions noch unter SQL-Naming-Conventions ermittelt.
Werden in einem SELECT-Statement mehrere Tabellen verknüpft, wird für Spalten die Tabelle nur dann ermittelt, wenn der Spalten-Name qualifiziert wurde, also entweder mit der Tabelle oder einem entsprechenden Kürzel, das in der FROM-Anweisung definiert wurde, angegeben wurde.
Werden in einem SELECT-Statement durch die Angabe von * alle Spalten ausgewählt, werden durch den PARSE_STATEMENT-Service die einzelnen Spalten nicht aufgelistet. Es werden nur die Tabellen und die verknüpften Spalten ausgegeben.
In dem folgenden Beispiel werden die Tabellen ORDERHDRX und ADDRESSX miteinander verknüpft und alle Spalten, durch die Angabe SELECT * ausgewählt. Das Ergebnis der Tabellen-Funktion PARSE_STATEMENT zeigt lediglich die beiden Tabellen sowie die beiden Spalten CUSTNO (einmal aus der Tabelle ADDRESSX und einmal aus der Tabelle ORDERHDRX), über die beide Tabellen verknüpft werden, an.

In dem folgenden Beispiel werden wiederum die Tabellen ADDRESSX und ORDERHDRX miteinander verknüpft. Dieses Mal werden jedoch die einzelnen Spalten aufgelistet, wobei an dieser Stelle lediglich die Spalten, die in beiden Tabellen vorhanden sind, qualifiziert werden.
Bei den Spalten, die qualifiziert angegeben wurden, wird im Ergebnis die Tabelle, aus der die Spalten sind, angezeigt. Bei den Spalten, die nicht qualifiziert wurden, da sie nur in einer Tabelle vorhanden sind, wird der Tabellen-Name nicht ermittelt, sondern stattdessen ein NULL-Wert ausgegeben.

In den beiden vorhergehenden Beispielen waren die Tabellen unqualifiziert (ohne Bibliothek) angegeben. Aus diesem Grund wurden in der Spalte Schema lediglich NULL-Werte ausgegeben, d. h. es wird weder die Bibliotheksliste (beim System-Naming) noch das CURRENT SCHEMA (beim SQL-Naming) durchsucht.
Sofern auch die Bibliothek ausgegeben werden soll, müssen die Tabellen so wie in dem folgenden Beispiel qualifiziert werden, in dem für alle Spalten die Tabellen-Namen und auch die Bibliotheken, in denen sich die Tabellen befinden, angezeigt werden.

In dem folgenden Beispiel wird gezeigt, dass das PARSE_STATEMENT keineswegs nur auf SELECT-Statements beschränkt ist.
In diesem Fall wird ein CREATE OR REPLACE TABLE Statement analysiert. Das Ergebnis zeigt Spalten, die in dem CREATE OR REPLACE TABLE Statement definiert werden.
Details über die Spalten in der Tabelle können, nachdem die Tabelle erstellt wurde, aus der Catalog-View SYSCOLUMNS in der Bibliothek QSYS2 ermittelt werden.

Wenn wir jetzt die View SYSPROGRAMSTAT und SYSPROGRAMSTMTSTAT mit der Tabellen-Funktion PARSE_STATEMENT kombinieren, sind wir in der Lage die statischen SQL-Statements in (Service-)Programm-Objekten und/oder SQL-Routinen zu durchsuchen.
Damit ist es z. B. möglich zu ermitteln, in welchen (Service-)Programmen eine bestimmte physische Datei, Tabelle oder View in statischen SQL-Statements verwendet wird.
In dem folgenden Beispiel werden die statischen SQL-Statements in (Service-)Programm-Objekte in der Bibliothek DIRWEB dahingehend untersucht, ob sie auf die DWSQLLV01 zugreifen.
Zunächst werden in einer Common-Table-Expression (PROGRAM_STATEMENTS) die beiden Views SYSPROGRAMSTAT und SYSPROGRAMSTMTSTAT miteinander verknüpft und nur die benötigten Spalten aufgelistet. Es werden außerdem nur alle (Service-)Programme ausgewählt, die mindestens ein SQL-Statement beinhalten und die sich in der Bibliothek DIRWEB befinden.
Die Common-Table-Expression wird im endgültigen SELECT mit der Tabellen-Funktion PARSE_STATEMENT verknüpft bzw. die Tabellen-Funktion PARSE_STATEMENT wird für jedes aus der View SYSPROGRAMSTMTSTAT selektierte (Service-)Programm ausgeführt.
Durch die WHERE-Bedingung werden nur die Abfragen ausgewählt, in denen die Tabelle DWSQLLV01 verwendet wird.
In diesem Fall werden zwei Service-Programme gefunden, die SELECT-Statements enthalten, in denen die Tabelle DWSQLLV01 verwendet wird. Das entsprechende SQL-Statement (aus der View SYSPROGRAMSTMTSTAT) wird ebenfalls ausgegeben.

Durch entsprechende Anpassungen in den WHERE-Bedingungen, kann u. a. ebenfalls ermittelt werden, wo eine bestimmte Spalte verwendet wird.
Damit es möglich (Service-)Programm-Objekte nach statischen SQL-Statements zu durchsuchen, ohne dass die zugehörigen Quellen durchforstet werden müssten.
Die Analyse von dynamischen SQL-Statements in Programmen ist nicht möglich, da die endgültigen dynamischen SQL-Statement erst zur Laufzeit bekannt sind.
Soweit zu den Views und Services zur Analyse von SQL-Statements.
Und nun viel Spaß beim Ausprobieren!
Birgitta Hauser ist IBM Champion und Spezialistin für SQL- sowie RPG-Programmierung.
Frau Hauser gibt regelmäßig Workshops im Rahmen der MIDRANGE ACADEMY.
Sie schreibt regelmäßig für MIDRANGE und den TechKnowLetter. Hier erhalten Sie brandneue, tiefe Informationen zu SQL, RPG und vielem mehr.
Der TechKnowLetter erscheint monatlich. Sechs Ausgaben erhalten Sie für 88 Euro hier.