Fonction Oracle à partir d'une procédure java

Voici un exercice mettant en oeuvre la compilation de code java pour l'utiliser au sein de fonction Oracle.
Cet exercice permet simplement de faire une transformation XSLT directement au sein de java, en ne stockant que le XML et sa XSL associée en base mais où le client récupèrera le HTML généré.

Initialiser son code Java


Créer sa classe Java de transformation XML vers HTML (fichier transformHTML.java) :


import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;

import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
public class transformHTML{

public static void trXmlHtml(String xml, String xsl, String html) throws Exception{

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder build = factory.newDocumentBuilder();
File ficXml = new File(xml);
Document doc = build.parse(ficXml);
Source source = new DOMSource(doc);

// Création du html
String html = new String();
File ficHtml = new File(html);
Result resultat = new StreamResult(ficHtml);

// Configuration du transformer
TransformerFactory transformFact = TransformerFactory.newInstance();
StreamSource fluxXsl = new StreamSource(xsl);
Transformer tr = transformFact.newTransformer(fluxXsl);
tr.setOutputProperty(OutputKeys.METHOD, "html");

// Transformation
tr.transform(source, resultat);
return html;
}
}



Compiler cette classe :
javac transformHTML.java


Le fichier transformHTML.class est ainsi créé.

Importer le java dans notre base Oracle


Définir le SID :
export ORACLE_SID=BDDEX

Charger la classe dans la base :
loadjava -u USEREX/PASSEX transformHTML.class

Définir une fonction sous Oracle prenant en compte ce code :

create or replace function trXmlHtml(txt1 VARCHAR2, txt2 VARCHAR2) return VARCHAR2
as language java
name 'transformHTML.trXmlHtml(String, String ) return String';



Créer ses tables T_XML, T_XSL et la table d'association permettant de générer les flux HTML A_HTML :
create table T_XML (id_xml number, val_xml VARCHAR2(4000));
create table T_XSL (id_xsl number, val_xsl VARCHAR2(4000));
create table A_HTML (id_html number, id_xml number, id_xsl number);


Alimenter ses tables :
INSERT INTO ...
sqlldr ...
imp ...


Générer à la volée le flux HTML ayant l'id_html à 4 :
select id_html, trXmlXsl(val_xml, val_xsl) from A_HTML inner join T_XML on T_XML.id_xml = A_HTML.id_xml
inner join T_XSL on T_XSL.id_xsl = A_HTML.id_xsl
where id_html = 4;



Quelques précautions particulières :
Vérifier que la taille du java_pool_size est taillée suffisamment pour accueillir la classe à charger afin d'éviter l'erreur ORA-04031 au moment du chargement avec loadjava.
Vérifier la cohérence des versions java, entre celle du compilateur et celle d'Oracle au risque d'avoir une erreur ORA-29541.
Vérifier d'attribuer les droits comme il faut aux procédures afin de ne pas être confronté à l'erreur ORA-29532.

Pour plus d'information il existe un package nommé dbms_java permettant la manipulation de code java ; ainsi il est directement possible d'écrire le code source dans une procédure stockée par exemple et d'utiliser le compilateur interne à Oracle :
CREATE AND COMPILE JAVA SOURCE NAMED "transformHTML" AS
[ . . . ]


Il est évidemment possible de créer des index sur ces fonctions (pour peu qu'elle soient deterministic), créer des vues utilisant ces fonctions ou même faire des jointures sur des colonnes de tables où sont appliqués des fonctions de ce type.

Enfin, à partir de 11g, il est possible de créer une colonne virtuelle retournant la valeur de la fonction pour chaque tuple.

Grâce à cette technique, on peut aisément utiliser la puissance et la souplesse du code java et de ses librairies associées tout en manipulant les données strictement nécessaires.

Voir également l'article sur le stockage de données XML.




Vous n'avez pas trouver réponse à votre question ? Préciser votre recherche :

Catégories