Betrifft Externe Prozeduren unter Windows mit dem Freeware-Compiler MinGW Autor Jens-Uwe Petersen ([email protected]) Art der Info Technische Background Info (August 2003) Quellen http://www.mingw.org oder http://sourceforge.net/projects/mingw Oracle8 Externe Procedures aus PL/SQL (Urs Meier, Trivadis Publikation) Einleitung Es ist immer wieder ärgerlich, dass Microsoft seine Betriebssysteme im Gegensatz zu anderen Herstellern ohne Compiler ausliefert. Das separat von Microsoft zu erwerbende VisualStudio ist sicherlich ein sehr leistungsfähiges Produkt, aber auch sehr ressourcenintensiv (Preis, Einarbeitung, Plattenplatz). Für jemanden, der nur gelegentlich (und „g’schwind“ wie man im Schwäbischen sagt) ein paar Sourcen kompilieren möchte, ist das einfach zu aufwendig. Ursprünglich hatte ich für diese Zwecke den Compiler LCC-Win32 verwendet, der aber seit Anfang des Jahres nur noch für private Zwecke kostenlos ist. Auf der Suche nach einer Alternative bin ich dann recht schnell auf MinGW ("Minimalistic GNU for Windows") gestossen. MinGW basiert auf dem populären Gnu-Compiler GCC, erweitert um eine Reihe von Header- und Include-Dateien um native Windows-Applikationen erstellen zu können. Die folgenden Beispiele gehen davon aus, dass MinGW im Verzeichnis c:\programme\MinGW installiert wurde und ORACLE_HOME unter c:\oracle\9i liegt. Erstes Beispiel Als erstes versuchen wir, das mit der Datenbank mitgelieferte Beispiel im Verzeichnis %ORACLE_HOME%\rdbms\extproc zum Laufen zu bekommen, das das Maximum zweier Werte ermittelt. Fügen Sie das MinGW\bin-Verzeichnis dem Suchpfad hinzu. PATH=c:\programme\MinGW\bin;%PATH% Um die Datei zu kompilieren auf DOS-Ebene in das Verzeichnis wechseln und den Compiler starten. Durch den Parameter –shared wird gleich die DLL erzeugt. cd %ORACLE_HOME%\rdbms\extproc gcc -shared -o extern.dll extern.c Nun muss datenbankseitig noch die dazugehörige Wrapper-Funktion „UseIt“ angelegt werden. Dies geschieht mit dem Skript extern.sql aus dem gleichen Verzeichnis. Gleich nach dem Anlegen wird „UseIt“ auch ausgeführt, sodass als Ausgabe in etwa folgendes erscheinen sollte: sample@TVD9I> execute UseIt; The maximum of 1 and 2 is 2 PL/SQL-Prozedur wurde erfolgreich abgeschlossen. Unter Oracle 9i Release 2 kann es zur Fehlermeldung ORA-28595 "Extproc agent: Invalid DLL Path" kommen, da hier standardmäßig nur DLLs in %ORACLE_HOME%\bin (Windows) bzw. %ORACLE_HOME%\lib (Unix) ausgeführt werden. In diesem Falle müssen Sie die LISTENER.ORA entsprechend anpassen. Für die Testumgebung mag es evntl. angehen die Verwendung aller DLLs erlauben: (ENVS="EXTPROC_DLLS=ANY") In Produktionsumgebungen sollte man aber aus Sicherheitsgründen unbedingt nur die wirklich benötigten DLLs freigeben. Für unsere Beispiele wären dies: (ENVS="EXTPROC_DLLS= c:\oracle\9i\RDBMS\EXTPROC\extern.dll;c:\Programme\MinGW\Projects\callback") Für weitere Informationen dazu siehe Metalink Note 198523.1. Falls andere Fehler auftreten sollten, ist wahrscheinlich der Listener nicht richtig konfiguriert, dann siehe beispielsweise Metalink Note 68061.1, das im Beispielverzeichnis enthaltene Readme.doc oder Kapitel 10 im Application Developers Guide. Zweites Beispiel Als nächstes wollen wir uns einem etwas komplexeren Beispiel zuwenden, das die Callback Möglichkeiten demonstrieren soll und unter %ORACLE_HOME%/rdbms /plsql/demo zu finden ist. Die beiden Dateien, die uns hier interessieren, heißen extproc.sql und extproc.c Um die Sourcen übersichtlich an einem Ort zu haben, erstellen wir im Projektverzeichnis von MinGW ein neues Verzeichnis callback. cd c:\programme\MinGW\projects\ mkdir callback cd callback copy %ORACLE_HOME%\plsql\demo\extproc.* . Dieses Beispiel verwendet die Oracle-Library oci.dll. Da die Libraries von Microsoft nicht kompatibel zu denen von MinGW sind, muss die Library erst konvertiert werden. reimp c:\oracle\9i\oci\lib\msvc\oci.lib Die erzeugte Textdatei OCI.def enthält eine Liste der enthaltenen Funktionen (und wird nicht weiter benötigt), liboci.a ist die konvertierte Library, die am besten ins lib-Verzeichnis von MinGW kopiert wird. Jetzt noch schnell die DLL erzeugen: gcc -shared -o extproc.dll extproc.c -L. -loci -Ic:\oracle\9i\oci\include Dann in der Datenbank die Objekte anlegen: SQLPLUS SCOTT/TIGER CREATE OR REPLACE LIBRARY demolib IS 'c:\programme\MinGW\projects\callback\extproc.dll'; / @c:\programme\MinGW\projects\callback\extproc.sql Und zu guter Letzt kann nun das Ergebnis validiert werden: scott@TVD9I> set serveroutput on; scott@TVD9I> execute demopack.demo_procedure; ENAME : ALLEN JOB : SALESMAN SALARY : 1600 COMMISSION : 300 Percent Commission : 18,75 ENAME : MARTIN JOB : SALESMAN SALARY : 1250 COMMISSION : 1400 Percent Commission : 112 Return value from CheckEmpName : 0 old_ename value on return : ANIL ENAME : 7369 HIREDATE : 17.12.1980 Employee Experience Test Passed. *************************************** Zusammenfassung Es wurde gezeigt, dass es auch unter Windows ohne großen Aufwand möglich ist, DLLs zu erzeugen und als externe Prozeduren einzusetzen. Was es für Schwierigkeiten mit windowseigenen Libraries wie z.B. kernel32.dll geben kann und wie ‚Native Compilation’ mit MinGW eingesetzt wird, wird in weiteren Artikeln erklärt werden. Und damit wünsche ich Ihnen fehlerfreie Kompilate und erfolgreiches „Outsourcen“ von Prozeduren.... Jens-Uwe Petersen Trivadis GmbH Jens-Uwe Petersen Max-Lang-Strasse 56 70771 Leinfelden-Echterdingen Mail: [email protected] Tel: +49 711 903 63 230 Fax: +49 711 903 63 259 Internet: http://www.trivadis.com