Benutzer-Werkzeuge

Webseiten-Werkzeuge


python:jython_scripting_database

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.

  1. Download der Jar Datei jython-standalone-2.7.0.jar von http://www.jython.org/downloads.html
  2. Kopieren nach $SQLCL_HOME/lib
  3. Einbinden in den Klassen Pfad, über die Umgebung oder über die $SQLCL_HOME/bin/sql.bat bzw. sql
    1. Linux: export CLASSPATH=$CLASSPATH:/opt/oracle/products/sqlcl/lib/jython-standalone-2.7.0.jar
  4. Erstellen des ersten Jython scripts helloWorld.py
    print "Hello World" 
  5. 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!

NUR SQL Scripte werden in SQLcl mit @ aufgerufen, js und py Scripte immer mit „script“ !
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

Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
"Autor: Gunther Pipperr"
python/jython_scripting_database.txt · Zuletzt geändert: 2016/11/15 19:59 von gpipperr