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 ]; then
echo "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 ROLLBACK
SET DEFINE OFF
SET SQLBLANKLINES ON
SET 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 ]; then echo "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 oben
if [ $? -ne 0 ]; then echo "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