Inhaltsverzeichnis
Jython Scripting für die Oracle Datenbank mit SQLcl
Integration in SQLcl
Mehr zu SQLcl siehe SQLcl - Quo vadis SQL*Plus? - Das neue SQL*Plus in der Praxis - Der neue SQL Kommando Interpreter für die Oracle Datenbank
Um Jython einzubinden muss nur die Jar Datei in den Klassenpfad beim Aufruf von SQLcl aufgenommen werden.
- Download der Jar Datei jython-standalone-2.7.0.jar von http://www.jython.org/downloads.html
- Kopieren nach $SQLCL_HOME/lib
- Einbinden in den Klassen Pfad, über die Umgebung oder über die $SQLCL_HOME/bin/sql.bat bzw. sql
- Linux: export CLASSPATH=$CLASSPATH:/opt/oracle/products/sqlcl/lib/jython-standalone-2.7.0.jar
- Erstellen des ersten Jython scripts helloWorld.py
print "Hello World"
- Aufruf mit „SQL> script helloWorld.py“ ⇒ „Hello World“
D.h. die ScriptEngine erkennt über die Datei Endung, was für ein Interpreter verwandt werden soll!
Problem: console: Failed to install '': java.nio.charset.UnsupportedCharsetException: cp65001.
Leider führt der erste Test unter Windows gleich zu einem „console: Failed to install '': java.nio.charset.UnsupportedCharsetException: cp65001.“
Das lässt sich zwar über den Java Start Parameter „-Dpython.console.encoding=UTF-8“ bekämpfen, zeigt aber wieder auf, dass hier noch viel Arbeit für Oracle notwendig ist um das Konsolenwerkzeug unter Windows wirklich lauffähig zu bekommen.
Einsatz Beispiele
Auch innerhalb des Scopes des Scripts sind die “äußern” Objekte der SQLcl Umgebung erreichbar und können aufgerufen werden
Folgende Objekte können in Script (default Java Script Syntax ! ) direkt angesprochen werden:
- sqlcl - SQLCL selbst wie sqlcl.setStmt(„select * from dual“) und sqlcl.run() um das dann auszuführen
- Methods: setStmt(<String>) - Ein SQL Statment oder einen SQLcl Befehl in den Buffer schrieben
- Methods: run - Den Buffer ausführen
- ctx - Object vom Typ ScriptContext, kann direkt angesprochen werden - wie ctx.write(„String“)
- Methods: write(<String>) - Auf Standard Out schreiben
- Methods: getProperty(<String>) - Wert im Session Context setzen
- Methods: setProperty(<String>,<Object>) - Wert aus dem Session Context holen
- util - wie var user=util.executeReturnOneCol('select user from dual')
- Methods: execute(<string>,binds) executes whatever is passed in with a boolean return for success/failure
- Methods: executeReturnOneCol(<string>,binds) - executes and returns the first row , first column
- Methods: executeReturnListofList(<string>,binds) - executes and returns an array(rows) of arrays(row).
- Methods: executeReturnList(<string>,binds)- execute and returns and array ( rows ) of objects ( row )
Hier das erste Hello World Beispiel:
ctx.write("Hello Word\n");
Java Klassen einbinden
Um auf Java Klasssen dann wieder um in Jython zuzugreifen, können diese zuvor definiert werden
from java.lang import System as javaSystem # get the Java Enviroment Setting of this session # and use the Python str function inside the Java Part ! # javaSystem.out.println( "user.lang ::" + str(javaSystem.getProperty("user.lang"))); javaSystem.out.println( "user.country ::" + str(javaSystem.getProperty("user.country")));
sqlcl.setStmt in Jython verwenden
Mit der Objekt sqlcl kann direkt auf SQLcl referenziert werden.
Erst mit sqlcl.setStmt(„select * from dual“) den gewünschten Befehlt vorbereiten und dann mit sqlcl.run() auszuführen.
Alle gültigen Kommandos für SQLcl können so aufgerufen werden.
Beispiel ⇒ je nach User wird der Login Prompt anders gesetzt
dbUser = util.executeReturnOneCol('select user from dual'); command=" " if dbUser == 'SCOTT': command='set sqlprompt "@|green _USER>|@"' else: command='set sqlprompt "@|green _USER|@@@|red _CONNECT_IDENTIFIER|@>"' sqlcl.setStmt(command) sqlcl.run()
⇒ siehe auch die orginal JS Source unter ⇒ https://github.com/oracle/oracle-db-tools/blob/master/sqlcl/examples/sqlprompt.js
Script je nach Bedarf aufrufen:
x=1 if abfrage == 0: sqlcl.setStmt('@version.sql') else: sqlcl.setStmt('@database.sql') sqlcl.run()
SQL mit Bind Variable Absetzen
Um auf den Context von SQLcl zuzugreifen, können wir ja direkt die Java Instancen im Script verwenden. Wir müssen aber darauf achten die Pyhton Datentypen entsprechend zu erzeugen damit das zusammen spielt.
Mit „util.executeReturnListofList“ kann ein SQL Statement im aktuellen Session Kontext ausgeführt werden, Parameter für die SQL Abfrage werden aber als Hash Map erwartet. Um diese zu Erzeugen verwenden wir in Jython direkt das Java Objekt mit „from java.util import HashMap“ und erzeugen uns ein Objekt mit „bind=HashMap()“
Beispiel:
from java.util import HashMap # create object for the bind variable bind=HashMap() bind['EMPNO'] = '7369' # SQL statement with bind usage sql='select EMPNO,ENAME,SAL from emp where EMPNO=:EMPNO' # execute the statment and iterate over the result retVal = util.executeReturnListofList(sql,bind) # interate over the result for e in retVal: print e
Stand Alone Installation
Download des Installer Jars von http://www.jython.org/downloads.html
Installieren mit in der Console in der PowerShell:
java -jar .\jython-installer-2.7.0.jar --console Welcome to Jython ! You are about to install Jython version 2.7.0 (at any time, answer c to cancel the installation) For the installation process, the following languages are available: English, German Please select your language [E/g] >>> E Do you want to read the license agreement now ? [y/N] >>> N Do you accept the license agreement ? [Y/n] >>> Y The following installation types are available: 1. All (everything, including sources) 2. Standard (core, library modules, demos and examples, documentation) 3. Minimum (core) 9. Standalone (a single, executable .jar) Please select the installation type [ 1 /2/3/9] >>> 1 Do you want to exclude parts from the installation ? [y/N] >>> N Please enter the target directory >>> C:\Jython Unable to find directory C:\Jython, create it ? [Y/n] >>> Y Your java version to start Jython is: Oracle Corporation / 1.8.0_101 Your operating system version is: Windows 10 / 10.0 Summary: - mod: true - demo: true - doc: true - src: true - ensurepip: true - JRE: C:\Program Files\Java\jre1.8.0_101 Please confirm copying of files to directory C:\Jython [Y/n] >>> Y 10 % 20 % ... 70 % 80 % Generating start scripts ... Installing pip and setuptools 90 % Ignoring indexes: https://pypi.python.org/simple/ Downloading/unpacking setuptools Downloading/unpacking pip Installing collected packages: setuptools, pip Successfully installed setuptools pip Cleaning up... 100 % Do you want to show the contents of README ? [y/N] >>> N Congratulations! You successfully installed Jython 2.7.0 to directory C:\Jython.
siehe auch https://wiki.python.org/jython/InstallationInstructions
Aufrufen
Jython does not support code page 65001 (CP_UTF8).
PS C:\Jython\bin> .\jython.exe Jython does not support code page 65001 (CP_UTF8). Please try another code page by setting it with the chcp command.
Code Page alternativen siehe : Code Page Identifiers ⇒ https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
Wir können nun die Code Page mit „ chcp 850“ setzen, dann ist der Fehler zwar weg,aber Umlaut funktionieren auch nicht mehr!!!
PS C:\Jython\bin> chcp Active code page: 65001 # auf die 850 Code Page umsschalten: chcp 850 PS C:\Jython\bin> .\jython.exe Jython 2.7.0 (default:9987c746f838, Apr 29 2015, 02:25:11) >>> print "Dies ist ein Text mit õ÷³" Dies ist ein Text mit õ÷³
Ärgerlich, unter Windows funktioniert das nicht richtig…..
Quellen
Bücher und weitere gute Tutorials für den Einstieg:
Scripting in Java
- Diplomarbeit - PHP in Java - ein Experiment ⇒ http://nightspawn.com/files/tinkerings/thesis.pdf
Scripting JS