IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

PL/SQL et le HTML

14/05/2004

Par Helyos (helyos.developpez.com)
 


1. Introduction
2. Qu'est ce que c'est
3. Configuration de la passerelle PL/SQL
4. Ma première page HTML
5. Mon premier état
6. Mon premier formulaire
7. Mon premier formulaire à 1 argument mais plusieurs valeurs
8. Description des principales procédures.
8.1. OWA_UTIL
8.2. HTP
9. Remerciements


1. Introduction


Vous aviez toujours eu envie de générer vos états, formulaires et voir même un site web tournant sur une base Oracle. Et bien c'est possible car Oracle vous fournit des packages qui servent directement à générer vos pages HTML et cela grâce à du PL/SQL.

Comment, me direz vous? Et bien c'est ce que je vais vous expliquer.


2. Qu'est ce que c'est


Oracle et le PL/SQL, merveilleuse alliance qui va vous permettre de réaliser pratiquement tout ce dont vous avez envie. Pour ce faire dans cet article je vais vous expliquer les bases du développement Web avec Oracle et les packages HTP et OWA_UTIL afin de construire vos premières pages web.


3. Configuration de la passerelle PL/SQL


La première chose à faire est de configurer la passerelle mod_plsql qui va vous permettre de créer vos premières pages. La méthode est identiques pour Oracle 8i et Oracle 9i.

Première chose qu'il va falloir vérifier c'est l'installation de Oracle et de son serveur Apache.

Si tout est lancé, voici les étapes à suivre pour la configuration de la passerelle.

Ouvrir l'url http://127.0.0.1/pls/simpledad/admin_/gateway.htm


Ensuite cliquez sur Paramètres des DAD de la passerelle

Puis cliquez sur Ajout d'un descripteur par défaut

Voici les informations à saisir

Nom du descripteur d'accès à la base de données = web
Schema Name = scott
Nom d'utilisateur Oracle = scott
Mot de passe Oracle = tiger
Chaîne de connexion Oracle = <host string>
Voilà, nous venons de configurer notre passerelle PL/SQL qui nous permettra d'accéder à nos premières pages web.


4. Ma première page HTML


Alors, comment faire votre première page HTML en PL/SQL?

C'est très simple. La première étape va consister à construire une petite procédure qui affichera ce que l'on souhaite afficher.

Par exemple :

CONNECT scott/tiger@<chaine d'hôte> CREATE OR REPLACE PROCEDURE my_first_webpage IS BEGIN htp.print('HELLO WORLD'); END my_first_webpage; /
Voilà nous venons de créer une page web qui grâce à une procédure équivalente à DBMS_OUTPUT.PUT_LINE va nous générer un flux HTML.

Ensuite pour voir le résultat de votre première page

http://localhost/pls/web/my_first_webpage


5. Mon premier état


Maintenant que nous avons découvert comment afficher quelque chose sur notre page web voici 2 exemples donnant le même résultat: "L'affichage des n° et noms des employés d'un département particulier à partir de notre table EMP".

La première méthode est une construction manuelle de la page.

CREATE OR REPLACE PROCEDURE my_report(p_deptno NUMBER) IS CURSOR c1 IS SELECT empno, ename FROM emp WHERE deptno = p_deptno; BEGIN htp.print('<TABLE BORDER="1" WIDTH="100%">'); FOR rec IN c1 LOOP htp.print('<TR><TD>' || rec.empno || '</TD><TD>' || rec.ename || '</TD></TR>'); END LOOP; htp.print('</TABLE>'); END my_report;
Voici la deuxième méthode qui utilise directement les procédures du package HTP.

CREATE OR REPLACE PROCEDURE my_report(p_deptno NUMBER) IS CURSOR c1 IS SELECT empno, ename FROM emp WHERE deptno = p_deptno; BEGIN htp.tableopen(cborder => 'BORDER="1"', cattributes => 'WIDTH="100%"'); FOR rec IN c1 LOOP htp.tablerowopen; htp.tabledata(cvalue => rec.empno); htp.tabledata(cvalue => rec.ename); htp.tablerowclose; END LOOP; htp.tableclose; END my_report;
Une fois cette nouvelle procédure créée, nous allons tenter de visualiser notre résultat en ouvrant l'url suivante :

http://localhost/pls/web/my_report

Nous recevons une erreur 404. Cette erreur est due au fait que nous n'avons pas spécifié de département. Essayons maintenant avec un argument

http://localhost/pls/web/my_report?p_deptno=10

Voila nous venons de créer notre première procédure à argument. Si vous souhaitez changer de département il vous suffira de modifier la valeur de p_deptno.


6. Mon premier formulaire


Dans cet exemple nous allons voir comment créer un formulaire d'ajout dans une de nos table.

Voici la table d'exemple.

CREATE TABLE t_plhtml(id NUMBER, valeur VARCHAR2(50));
Voici donc les 2 méthodes qui vont vous permettre d'ajouter de nouveaux enregistrements dans cette table. Nous utiliserons ici des packages.

CREATE OR REPLACE PACKAGE my_own_package IS -- Etat du contenu de la table PROCEDURE report; -- Procédure d'insertion PROCEDURE add_row(p_id NUMBER, p_valeur VARCHAR2); -- Formulaire d'ajout PROCEDURE form; END my_own_package; / CREATE OR REPLACE PACKAGE BODY my_own_package IS PROCEDURE report IS CURSOR c1 IS SELECT * FROM t_plhtml; BEGIN htp.print('<TABLE BORDER="1" WIDTH="100%">'); FOR rec IN c1 LOOP htp.print('<TR><TD>' || rec.id || '</TD><TD>' || rec.valeur || '</TD></TR>'); END LOOP; htp.print('</TABLE>'); END; PROCEDURE add_row(p_id NUMBER, p_valeur VARCHAR2) IS BEGIN -- On ajoute la ligne INSERT INTO t_plhtml VALUES (p_id, p_valeur); COMMIT; -- On redirige vers l'état final owa_util.redirect_url(curl => 'my_own_package.report'); END; PROCEDURE form IS BEGIN htp.prn('<FORM ACTION="my_own_package.add_row" METHOD="POST">'); htp.prn('<TABLE BORDER="1">'); htp.prn('<TR><TD>Saisir un Id</TD><TD><INPUT TYPE="TEXT" name="p_id"></TD></TR>'); htp.prn('<TR><TD>Saisir un text</TD><TD><INPUT TYPE="TEXT" name="p_valeur"></TD></TR>'); htp.prn('</TABLE>'); htp.print('<INPUT TYPE="submit" VALUE="Submit">'); htp.print('</FORM>'); END; END my_own_package; /
CREATE OR REPLACE PACKAGE my_htp_package IS -- Etat du contenu de la table PROCEDURE report; -- Procédure d'insertion PROCEDURE add_row(p_id NUMBER, p_valeur VARCHAR2); -- Formulaire d'ajout PROCEDURE form; END my_htp_package; / CREATE OR REPLACE PACKAGE BODY my_htp_package IS PROCEDURE report IS CURSOR c1 IS SELECT * FROM t_plhtml; BEGIN htp.tableopen(cborder => 'BORDER="1"', cattributes => 'WIDTH="100%"'); FOR rec IN c1 LOOP htp.tablerowopen; htp.tabledata(rec.id); htp.tabledata(rec.valeur); htp.tablerowclose; END LOOP; htp.tableclose; END; PROCEDURE add_row(p_id NUMBER, p_valeur VARCHAR2) IS BEGIN -- On ajoute la ligne INSERT INTO t_plhtml VALUES (p_id, p_valeur); COMMIT; -- On redirige vers l'état final owa_util.redirect_url(curl => 'my_own_package.report'); END; PROCEDURE form IS BEGIN htp.formopen(curl => 'my_own_package.add_row', cmethod => 'POST'); htp.tableopen(cborder => 'BORDER="1"'); htp.tablerowopen; htp.tabledata(cvalue => 'Saisir un Id'); htp.print('<TD>'); htp.formtext(cname => 'p_id'); htp.print('<TD>'); htp.tablerowclose; htp.tablerowopen; htp.tabledata(cvalue => 'Saisir un text'); htp.print('<TD>'); htp.formtext(cname => 'p_valeur'); htp.print('<TD>'); htp.tablerowclose; htp.tableclose; htp.formsubmit; htp.formclose; END; END my_htp_package; /
Voici comment lancer les pages ensuite

http://localhost/pls/web/my_own_package.form ou

http://localhost/pls/web/my_htp_package.form

Une fois sur la page de formulaire entrer une valeur pour l'id et le texte. Un clic sur le bouton submit, le formulaire appelle alors automatiquement la procédure add_row en lui passant les 2 arguments du formulaire. Une fois l'insertion terminée, la procédure OWA_UTIL.REDIRECT_URL (qui permet de rediriger le browser vers une nouvelle page) va automatiquement rediriger vers la procédure report.


7. Mon premier formulaire à 1 argument mais plusieurs valeurs


Dans cette partie nous allons voir comment faire quand nous voulons passer plusieur fois le même argument mais avec des valeurs différentes.

Pour donner un exemple concret nous allons modifier notre report précédent afin de nous donner la possibilité de supprimer plusieurs lignes à la fois.

Voici le script à lancer au préalable.

DECLARE BEGIN DELETE t_plhtml; COMMIT; FOR i IN 1 .. 20 LOOP INSERT INTO t_plhtml VALUES (i, 'Texte ' || i); COMMIT; END LOOP; END; /
Afin de nous permettre de sélectionner les lignes qui nous intéressent nous allons rajouter une checkbox devant chaque ligne. Ce qui nous permettra d'envoyer X fois le même paramètre mais avec des valeurs différentes.

Le seul moyen de récuperer toutes les valeurs sera alors d'utiliser une table PL/SQL.

Voici le nouveau package (je n'ai mis ici que la version avec les procédures HTP), et la procédure REPORT qui s'appelera elle-même.

CREATE OR REPLACE PACKAGE my_htp_package IS TYPE type_id IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER; t_id_vide type_id; -- Etat du contenu de la table PROCEDURE report(p_id type_id DEFAULT t_id_vide); -- Procédure d'insertion PROCEDURE add_row(p_id NUMBER, p_valeur VARCHAR2); -- Formulaire d'ajout PROCEDURE form; END my_htp_package; / CREATE OR REPLACE PACKAGE BODY my_htp_package IS PROCEDURE report(p_id type_id DEFAULT t_id_vide) IS CURSOR c1 IS SELECT * FROM t_plhtml ORDER BY id; BEGIN IF p_id.COUNT != 0 THEN FOR i IN 1 .. p_id.COUNT LOOP DELETE t_plhtml WHERE id = p_id(i); COMMIT; END LOOP; END IF; htp.formopen(curl => 'my_htp_package.report', cmethod => 'get'); htp.tableopen(cborder => 'BORDER="1"', cattributes => 'WIDTH="100%"'); FOR rec IN c1 LOOP htp.tablerowopen; htp.tabledata('<INPUT TYPE="checkbox" NAME="p_id" VALUE="' || rec.id || '">'); htp.tabledata(rec.id); htp.tabledata(rec.valeur); htp.tablerowclose; END LOOP; htp.tableclose; htp.formsubmit; htp.formclose; END; PROCEDURE add_row(p_id NUMBER, p_valeur VARCHAR2) IS BEGIN -- On ajoute la ligne INSERT INTO t_plhtml VALUES (p_id, p_valeur); COMMIT; -- On redirige vers l'état final owa_util.redirect_url(curl => 'my_own_package.report'); END; PROCEDURE form IS BEGIN htp.formopen(curl => 'my_own_package.add_row', cmethod =< 'POST'); htp.tableopen(cborder => 'BORDER="1"'); htp.tablerowopen; htp.tabledata(cvalue => 'Saisir un Id'); htp.print('<TD>'); htp.formtext(cname => 'p_id'); htp.print('<TD>'); htp.tablerowclose; htp.tablerowopen; htp.tabledata(cvalue => 'Saisir un text'); htp.print('<TD>'); htp.formtext(cname => 'p_valeur'); htp.print('<TD>'); htp.tablerowclose; htp.tableclose; htp.formsubmit; htp.formclose; END; END my_htp_package; /
Donc pour tester la nouvelle procédure vous devrez appeler l'url

http://localhost/pls/web/my_own_package.report

Bien que n'ayant pas de paramètre la procédure s'executera sans problème car nous avons fourni une valeur par défaut à notre paramètre. Ensuite quand nous aurons sélectionné les lignes à effacer et cliqué sur le bouton submit, la procédure va s'appeler elle-même en se passant les arguments p_id. Une fois les différentes valeurs reçues dans la table PL/SQL, la procédure les effacera et affichera le nouveau contenu de notre table.


8. Description des principales procédures.


Je vais ici présenter les principales procédures du package HTP et du package OWA_UTIL.


8.1. OWA_UTIL


Le package SYS.OWA_UTIL est un package permettant de récupérer et d'agir sur le browser. Par exemple ce package vous permettra de récupérer les variables d'environnement du browser web du client. Mais il vous permettra aussi d'effectuer des redirections du browser vers une nouvelle page, d'afficher le contenu d'une table, d'une procédure ou d'un package en HTML.

Ce package ne fait pas partie de la documentation officielle le seul moyen de voir son contenu et d'obtenir la description de ses fonctions et procédures est donc de lancer la commande.

DESCRIBE owa_util;
Ce package dispose d'un synonyme public OWA_UTIL


8.2. HTP


Le package SYS.HTP est un package permettant la génération de la majeure partie des tags HTML. Ce package ne fait pas partie de la documentation officielle le seul moyen de voir son contenu et d'obtenir la description de ses fonctions et procédures est donc de lancer la commande.

DESCRIBE htp;
Ce package dispose d'un synonyme public HTP


9. Remerciements


Merci à toute l'équipe de développez. Merci à Maxence HUBICHE, Orafrance et SheikYerbouti pour leurs relectures et suggestions.