Statische Analyse von Oracle SQL-Skripten auf SQLPlus-Kompatibilität.
Viele Skripte funktionieren problemlos in SQL Developer oder Toad, scheitern aber beim Deployment über SQLPlus auf dem Linux-Server. Dieses Tool prüft Skripte rein statisch (ohne Datenbankverbindung) auf die häufigsten Fehlerquellen.
cd python-sqlplus-checker
uv sync
uv lock --upgradeMit uv run python main.py ausführbar.
sqlplus-checker <PFAD> [OPTIONEN]
| Argument | Beschreibung |
|---|---|
PFAD | Datei oder Verzeichnis — Verzeichnisse werden rekursiv durchsucht |
| Option | Kurzform | Beschreibung |
|---|---|---|
--ext EXT | -e EXT | Kommagetrennte Dateiendungen (Standard: .sql,.pls,.pks,.pkb,.prc,.fnc,.trg,.vw,.tps,.tpb) |
--no-warnings | -W | Nur Fehler ausgeben, Warnungen unterdrücken |
--summary-only | -s | Nur die Zusammenfassung ausgeben, keine Einzelmeldungen |
| Code | Bedeutung |
|---|---|
0 | Keine Fehler gefunden (Warnungen möglich) |
1 | Mindestens ein Fehler gefunden |
2 | Ungültige Aufrufargumente |
Einzelne Datei prüfen:
sqlplus-checker deploy.sqlKomplettes Verzeichnis rekursiv prüfen:
sqlplus-checker ./scripts/Nur Fehler anzeigen (keine Warnungen), z. B. für CI/CD-Pipeline:
sqlplus-checker ./scripts/ --no-warningsNur die Zusammenfassung anzeigen:
sqlplus-checker ./scripts/ --summary-onlyAndere Dateiendungen einschließen:
sqlplus-checker ./scripts/ --ext .sql,.ddl,.dmlIn CI/CD-Pipelines (Exit-Code auswerten):
sqlplus-checker ./scripts/ --no-warnings
if [ $?-ne 0 ];thenecho"SQL-Prüfung fehlgeschlagen — Deployment abgebrochen"exit 1
fi| Regel | Beschreibung |
|---|---|
| UTF-8-Kodierung | Datei muss gültiges UTF-8 ohne BOM sein |
| Windows-Zeilenenden (CRLF) | SQLPlus unter Linux erwartet LF |
Fehlendes / nach PL/SQL-Block | PROCEDURE, FUNCTION, PACKAGE, TRIGGER, TYPE und BEGIN/END-Blöcke brauchen / in einer eigenen Zeile |
| Leerzeile in PL/SQL-Block | Ohne SET SQLBLANKLINES ON bricht SQLPlus den Block bei einer Leerzeile ab |
Fehlendes ; bei SQL-Statements | SELECT, INSERT, UPDATE, DELETE, ALTER, CREATE TABLE usw. müssen mit ; enden |
& ohne SET DEFINE OFF | SQLPlus fragt sonst interaktiv nach dem Substitutionswert |
| Regel | Beschreibung |
|---|---|
Fehlendes WHENEVER SQLERROR EXIT FAILURE | Ohne diese Einstellung läuft das Skript bei einem Fehler einfach weiter |
Fehlendes SET DEFINE OFF | & im Code wird als Substitutionsvariable interpretiert |
Fehlendes SET SQLBLANKLINES ON | Leerzeilen in PL/SQL-Blöcken brechen den Block ab |
Fehlendes SET SERVEROUTPUT ON | DBMS_OUTPUT-Ausgaben sind unsichtbar |
Fehlendes SPOOL | Kein Log-File für den Betrieb |
Fehlendes EXIT; | SQLPlus gibt die Shell-Kontrolle nicht zurück |
DML ohne COMMIT/ROLLBACK | INSERT/UPDATE/DELETE/MERGE ohne abschließende Transaktion |
Absoluter Pfad in @-Aufruf | Absolute Pfade sind umgebungsabhängig — relative Pfade verwenden |
| Nicht-ASCII in Kommentaren | Umlaute können bei NLS_LANG-Mismatch zwischen Client und Server Probleme verursachen |
| Reserviertes Keyword als Alias | Oracle-Keywords (z. B. DATE, TABLE) unquotiert nach AS |
Jedes Deployment-Skript sollte mit folgendem Header beginnen:
WHENEVER SQLERROR EXIT FAILURE ROLLBACKSET DEFINE OFF
SET SQLBLANKLINES ONSET SERVEROUTPUT ON
SPOOL /pfad/zum/logfile.log-- ... Skript-Inhalt ...
SPOOL OFF
EXIT;sqlplus-checker prüft statisch ohne Datenbankverbindung — SQLcl kennt hingegen
den vollständigen Oracle-SQL/PL/SQL-Parser und findet echte Syntaxfehler, die
kein statisches Tool erkennen kann.
Empfohlenes Vorgehen (zweistufig):
| Stufe | Tool | Was wird geprüft |
|---|---|---|
| 1 | sqlplus-checker | SQLPlus-Kompatibilität, Encoding, Header, Slash-Logik |
| 2 | SQLcl (Docker) | Echter Oracle-Syntaxparser, PL/SQL-Semantik |
SQLcl steht als offizielles Oracle Docker-Image zur Verfügung — keine lokale Installation nötig. Das folgende Kommando prüft alle SQL-Dateien rekursiv im angegebenen Verzeichnis:
ORACLE_RESTDATA_PWD=geheim docker run --rm \
--entrypoint /bin/bash \
-e ORACLE_RESTDATA_PWD \
-v ./scripts:/scripts \
container-registry.oracle.com/database/sqlcl:latest \
-c ' errors=0; checked=0 while IFS= read -r -d "" f; do rel="${f#/scripts/}" printf "Prüfe: %s ... " "$rel" checked=$((checked + 1)) output=$(printf "WHENEVER SQLERROR EXIT FAILURE\nSET FEEDBACK OFF\nSET TERMOUT OFF\nSET HEADING OFF\n@%s\nEXIT\n" "$f" \ | /opt/oracle/sqlcl/bin/sql -S -noupdates "restdata/${ORACLE_RESTDATA_PWD}@gmk:1521/XEPDB1" 2>&1) rc=$? if [ $rc -ne 0 ]; then echo "FEHLER" echo "$output" | sed "s/^/ /" errors=$((errors + 1)) else echo "OK" fi done < <(find /scripts \ \( -name "*.sql" -o -name "*.pls" -o -name "*.pks" -o -name "*.pkb" \ -o -name "*.prc" -o -name "*.fnc" -o -name "*.trg" \) \ -print0 | sort -z) echo "" echo "Ergebnis: $checked Dateien geprüft, $errors mit Syntaxfehler" exit $([ "$errors" -eq 0 ] && echo 0 || echo 1)'| Option / Befehl | Bedeutung |
|---|---|
-S | Silent-Modus — keine Verbindungsbanner |
-noupdates | Deaktiviert automatische Update-Prüfung |
restdata/$PWD@gmk:1521/XEPDB1 | Verbindung zur Oracle-Datenbank (kompiliert PL/SQL wirklich) |
WHENEVER SQLERROR EXIT FAILURE | Bricht bei erstem Fehler ab, Exit-Code 1 |
SET FEEDBACK OFF | Unterdrückt "1 row created." u. ä. |
SET TERMOUT OFF | Unterdrückt Script-Output |
SET HEADING OFF | Unterdrückt Spaltenüberschriften bei SELECT |
# Stufe 1: SQLPlus-Kompatibilität
sqlplus-checker ./scripts/ --no-warnings
if [ $?-ne 0 ];thenecho"sqlplus-checker fehlgeschlagen";exit 1;fi# Stufe 2: Oracle-Syntaxprüfung
ORACLE_RESTDATA_PWD=geheim docker run --rm \
--entrypoint /bin/bash \
-e ORACLE_RESTDATA_PWD \
-v "$(pwd)/scripts":/scripts \
container-registry.oracle.com/database/sqlcl:latest \
-c '...'# Kommando von obenif [ $?-ne 0 ];thenecho"SQLcl-Syntaxprüfung fehlgeschlagen";exit 1;fiHinweis: SQLcl mit echter Datenbankverbindung kompiliert PL/SQL-Blöcke vollständig und kann auch Objektreferenzen (Tabellen, Typen) auflösen. Das Passwort wird über die Umgebungsvariable
ORACLE_RESTDATA_PWDübergeben.
uv run pytest test_main.py -v