Oracle PL/SQL Server Pages (PSP)
© Prof. T. Kudraß, HTWK Leipzig
Grundidee: PSP
– Internet-Seiten mit dynamischer Präsentation von Inhalten durch Einsatz von PL/SQL-Anweisungen
– Server-Side Scripting (Generierung der Seiten im DB-Server - nicht im Webserver)
– Basiert auf PL/SQL Web Toolkit– Bestandteil von Oracle Application Server (OAS)
und Oracle WebDB– Einbindung dynamischer Inhalte durch PL/SQL-
Skripte, durch spezielle Tags gekennzeichnet
© Prof. T. Kudraß, HTWK Leipzig
Einordnung in Oracle Application Server
© Prof. T. Kudraß, HTWK Leipzig
Vorteile von PSP
Trennung von Anwendungs- und Präsentationslogik– HTML-Anweisungen und PL/SQL Code separat– Abgrenzung durch PL/SQL-spezifische Tags
Leichte Erlernbarkeit Einfacher Zugriff auf Daten der Datenbank Ausführung im Server Verbindung mit anderen Skriptsprachen möglich
– z.B. Javascript oder Visual Basic-Script (zur Prüfung von Benutzereingaben)
– nicht kombinierbar mit anderen serverseitigen Scripting-techniken
© Prof. T. Kudraß, HTWK Leipzig
Web Toolkit vs. PSP
CREATE OR REPLACE PROCEDURE home_page AS BEGIN
htp.htmlOpen; htp.headOpen;htp.title(‘My home page‘);htp.headClose;htp.bodyOpen;htp.print (‘This is the home page of ‘|| user ||‘generated on ‘ || sysdate || ‘.‘);htp.bodyClose;htp.htmlClose;
END;
CREATE OR REPLACE PROCEDURE home_page AS BEGIN
htp.htmlOpen; htp.headOpen;htp.title(‘My home page‘);htp.headClose;htp.bodyOpen;htp.print (‘This is the home page of ‘|| user ||‘generated on ‘ || sysdate || ‘.‘);htp.bodyClose;htp.htmlClose;
END;
© Prof. T. Kudraß, HTWK Leipzig
Entwicklung von PL/SQL Server Pages
1. Schreiben der PL/SQL Server Page Standard-Skripttag Spezielle Skripttags:
- Pages- Prozeduren- Parameter- Deklarationen- Expression Blocks- Include- Kommentare
2. Kompilieren der PSP-Datei als Stored Procedure3. Aufruf der PSP im Browser
© Prof. T. Kudraß, HTWK Leipzig
Standard-Skripttag
Funktion: Begrenzung von PL/SQL-Anweisungen
Inhalt: beliebige PL/SQL-Statements, z.B. Prozeduraufrufe
<% PL/SQL code %><% PL/SQL code %>Syntax
© Prof. T. Kudraß, HTWK Leipzig
Spezielle Tags:Page Direktive
Funktion: Charakterisierung der PSP Attribute:
– language: verwendete Skriptsprache (PL/SQL Standard)– contentType: Inhaltstyp der Seite; text/html Standard– errorPage: PSP-Seite, die auf auftretenden Fehlern aufgerufen
wird (Standard: keine Datei)
<% page [language=“PL/SQL“][contentType=“content type string“][errorPage=“file.psp“] %>
<% page [language=“PL/SQL“][contentType=“content type string“][errorPage=“file.psp“] %>
Syntax
© Prof. T. Kudraß, HTWK Leipzig
Spezielle Tags:Procedure & Parameter Direktive
Funktion: Spezifikation von Prozedur und Parameter (alles IN) Attribute:
– procedure: Name des Prozedur– parameter: Name des Parameters– type: Datentyp des Parameters; Standardwert varchar2 (ohne Länge)– default: Standardwert für Parameter
<% plsql procedure=“procedure name“ %><% plsql procedure=“procedure name“ %>Syntax
<% plsql parameter=“parameter name“ %>[type=“PL/SQL datatype“][default=“value“] %>
<% plsql parameter=“parameter name“ %>[type=“PL/SQL datatype“][default=“value“] %>
© Prof. T. Kudraß, HTWK Leipzig
Spezielle Tags:Declaration Direktive
Funktion: Deklaration von Variablen und Cursor auf der ganzen Seite
Beispiel:
<%! PL/SQL declaration;[PL/SQL declaration;] ... %>
<%! PL/SQL declaration;[PL/SQL declaration;] ... %>
Syntax
<%! cursor prod_cur is select * from products where price between minprice and´maxprice
vc_name varchar2(200):=‘Peter‘; %>
<%! cursor prod_cur is select * from products where price between minprice and´maxprice
vc_name varchar2(200):=‘Peter‘; %>
© Prof. T. Kudraß, HTWK Leipzig
Spezielle Tags: Expression Block / Print Direktive
Funktion: Ausgabe eines beliebigen PL/SQL-Ausdrucks (String, Zahl, Ergebnis eines Funktionsaufrufs)
Beispiel:
<%= PL/SQL expression %> <%= PL/SQL expression %> Syntax
<%= ‘The employee name is ‘|| emp_rec.ename %>oderThe employee name is <%= emp_rec.ename %>
<%= ‘The employee name is ‘|| emp_rec.ename %>oderThe employee name is <%= emp_rec.ename %>
© Prof. T. Kudraß, HTWK Leipzig
Spezielle Tags: Include Direktive
Funktion: Einbinden des Quelltexts anderer Dateien in die Seite
Beispiel:
<%@ include file =“path name“ %> <%@ include file =“path name“ %> Syntax
<%= include file=“header.inc“ %><%= include file=“header.inc“ %>
Anmerkungen:- Datei darf HTML- und PSP-Skriptelemente enthalten- Einbindung nur einmal zur Übersetzungszeit (mögliche
Alternative: Einbindung durch Prozeduraufruf)
© Prof. T. Kudraß, HTWK Leipzig
Spezielle Tags: Kommentare
Funktion: erscheint nicht in der generierten Prozedur bzw. in den daraus erstellten HTML-Seiten
<%-- Kommentar --%> <%-- Kommentar --%> Syntax
<%!-- Kommentar --%> <%!-- Kommentar --%> Syntax
Funktion: Kommentare, die in der HTML-Ausgabe erscheinen (normale HTML-Syntax)
-- einzeiliger Kommentar /* mehrzeiliger Kommentar */
-- einzeiliger Kommentar /* mehrzeiliger Kommentar */
Syntax
Funktion: Kommentare innerhalb eines PL/SQL-Blocks
© Prof. T. Kudraß, HTWK Leipzig
Kompilieren der PL/SQL Server Page
loadpsp [-replace] - user username/password[@connect_string] [include_file_name ...] [<page1> <page2> ... ]
loadpsp [-replace] - user username/password[@connect_string] [include_file_name ...] [<page1> <page2> ... ]
Syntax
Beispiel
loadpsp -replace - user name/passw@imnlehre timestamp.inc display_cust.psp
loadpsp -replace - user name/passw@imnlehre timestamp.inc display_cust.psp
Attribute:- replace: überschreibt Prozedur gleichen Namens- username/password@connect_string: Login-Information- include-file_name: Dateien, die mittels include eingebunden werden
- page1 ...: Name der PSP-Dateien, die kompiliert werden sollen
© Prof. T. Kudraß, HTWK Leipzig
Beispiel einer Generierung
© Prof. T. Kudraß, HTWK Leipzig
Verarbeitung des Aufrufs
© Prof. T. Kudraß, HTWK Leipzig
ParameterverarbeitungGET-Methode
Beispiel:
http://goliath.imn.htwk-leipzig.de:8080/WebDB/cust_order_items?ord_id=100&cust_id=100
http://goliath.imn.htwk-leipzig.de:8080/WebDB/cust_order_items?ord_id=100&cust_id=100
URL bei Submit:
...<form method=“GET“ action=“cust_order_items“><input type=“hidden“ name=“cust_id“ value=“<%=cust_id %“><input type=“text“ name=“ord_id“ size=“10“ value=“<%=order_id %“><input_type=“submit“ value = “Order Details“></form>...
...<form method=“GET“ action=“cust_order_items“><input type=“hidden“ name=“cust_id“ value=“<%=cust_id %“><input type=“text“ name=“ord_id“ size=“10“ value=“<%=order_id %“><input_type=“submit“ value = “Order Details“></form>...
© Prof. T. Kudraß, HTWK Leipzig
ParameterverarbeitungPOST-Methode
Beispiel:
http://goliath.imn.htwk-leipzig.de:8080/WebDB/cust_order_items
http://goliath.imn.htwk-leipzig.de:8080/WebDB/cust_order_items
URL bei Submit:
...<form method=“POST“ action=“cust_order_items“><input type=“hidden“ name=“cust_id“ value=“<%=cust_id %“><input type=“text“ name=“ord_id“ size=“10“ value=“<%=order_id %“><input_type=“submit“ value = “Order Details“></form>...
...<form method=“POST“ action=“cust_order_items“><input type=“hidden“ name=“cust_id“ value=“<%=cust_id %“><input type=“text“ name=“ord_id“ size=“10“ value=“<%=order_id %“><input_type=“submit“ value = “Order Details“></form>...
© Prof. T. Kudraß, HTWK Leipzig
Hinweise zur Verwendung von PSP
Trennung von Anwendungs- und Präsentationslogik– Berechnungen in eigenständiger Prozedur
Einbinden zusätzlicher Dateien– Procedure Invocation = direkter Prozeduraufruf
(bessere Berücksichtigung von Änderungen)
© Prof. T. Kudraß, HTWK Leipzig
Wiederverwendung von Seitenköpfen und -füßen
<%@ plsql procedure="page_header" %><!-- header: links to customer help page and search button --><CENTER><A HREF="/support/help.html">Customer Help</A><FORM ACTION="/product/search_prod"><INPUT NAME="item"><INPUT TYPE=SUBMIT></FORM><HR><!-- end of header -->
<%@ plsql procedure="page_header" %><!-- header: links to customer help page and search button --><CENTER><A HREF="/support/help.html">Customer Help</A><FORM ACTION="/product/search_prod"><INPUT NAME="item"><INPUT TYPE=SUBMIT></FORM><HR><!-- end of header -->
<%@ plsql procedure="page_footer" %><!-- footer: company contact info --><HR><CENTER>WebStore Inc. <BR>123 Main Street <BR>San Francisco, CA 94021 <BR>(415) 123-4567 <BR><A HREF="mailto:sales@webstore.<!-- end of footer -->
<%@ plsql procedure="page_footer" %><!-- footer: company contact info --><HR><CENTER>WebStore Inc. <BR>123 Main Street <BR>San Francisco, CA 94021 <BR>(415) 123-4567 <BR><A HREF="mailto:sales@webstore.<!-- end of footer -->
<HTML><TITLE>Page Title</TITLE><BODY><% page_header;%>... page body<% page_footer;%></BODY></HTML>
<HTML><TITLE>Page Title</TITLE><BODY><% page_header;%>... page body<% page_footer;%></BODY></HTML>
Aufruf der Prozeduren
© Prof. T. Kudraß, HTWK Leipzig
Fehlerbehandlung - Beispiel
create or replace procedure Show_Details( Prod_ID in Number, Name out varchar2, Price out Number ) as Prod_Name varchar2(30); Prod_Price Number;begin Select Name, Price Into Prod_name, Prod_Price From Products Where ID = Prod_id; ... Name := Prod_Name; Price := Prod_Price;end;
© Prof. T. Kudraß, HTWK Leipzig
Fehlerbehandlung - Verwendung von Errorpages
erwartete vs. unerwartete Fehler erwarteter Fehler: NO_DATA_FOUND unerwarteter Fehler: 2 Produkte mit der gleichen ID Verwendung von ErrorPage in Page-Direktive zur Behandlung
unerwarteter Fehler Nachteil: keine Parameterübergabe möglich (z.B.
Fehlerzeitpunkt, Eingabeparameter)
EXCEPTION WHEN OTHERS THENhtp.init;error; END; -- error: Name der Fehlerseite
© Prof. T. Kudraß, HTWK Leipzig
Benutzerdefinierte Ausnahmebehandlung (Exceptions)
<%@ page errorPage="Error_Page.psp" %> -- Angabe der Fehlerseite...l_exception EXCEPTION; -- Deklaration der Ausnahme l_exception...IF (TO_DATE(arrival_date,'YYYY-MM-DD') <= SYSDATE)THEN RAISE l_exception; -- Datum liegt vor dem aktuellem DatumEND IF;EXCEPTION WHEN l_exception THEN -- Test, ob es der vom Benutzer ausgelöste Fehler ist RAISE; -- Weiterleitung des Fehlers an übergeordnete Fehler- END; -- behandlung in Error_Page
...<% IF (SQLERRM = 'User-Defined Exception') THEN %> <% l_error_message := 'Date values should be greater than Current Date'; %> <%= l_error_message %> -- Ausgabe der Fehlermeldung<% ELSE %> <%= SQLERRM %> -- wenn anderer Fehler, Ausgabe der Fehlermeldung<% END IF; %>...
© Prof. T. Kudraß, HTWK Leipzig
Parameterübergabe<%@ plsql procedure “show errorPage="Error_Page.psp" %><%@ plsql parameter=“p_ID“ type=“number“ default=“0“%><%@ plsql parameter=“p_Text“ type=“varchar2“ default=“‘‘“%>
<SELECT NAME = “p_ID“ size=“1“><% for item in
(select ID, Name from Products order by Name) loop %><option value=“<%=item.ID %>“ ><%=item.Name %></option>
<% end loop; %></SELECT>
<SELECT NAME = “p_ID“ size=“1“><% for item in
(select ID, Name from Products order by Name) loop %><option value=“<%=item.ID %>“ ><%=item.Name %></option>
<% end loop; %></SELECT>
SELECT-Box wird durch Abfrage auf Tabelle Products mit Werten gefüllt, Zuordnung zum Parameter p_ID2. Eingabeparameter: p_Text als Input-Feld in HTML-Formular
<form method=“post“ action=“show_detail“> <p>Eingabe: <input type=text size=50 maxlength=50 name=“p_Name“> <SELECT NAME=“p_ID“ size=“1“> ... </SELECT> <input type=“submit“ value=“Abschicken“> </form>
<form method=“post“ action=“show_detail“> <p>Eingabe: <input type=text size=50 maxlength=50 name=“p_Name“> <SELECT NAME=“p_ID“ size=“1“> ... </SELECT> <input type=“submit“ value=“Abschicken“> </form>
© Prof. T. Kudraß, HTWK Leipzig
Benutzeridentifikation
<form method=“POST“ action=“Startseite“> <p><b>Kundennummer eingeben:</b>
<INPUT TYPE=“text“ name=“cust_id“ size=“5“> <input type=“submit“ value=“Login“></p> </form>
<form method=“POST“ action=“Startseite“> <p><b>Kundennummer eingeben:</b>
<INPUT TYPE=“text“ name=“cust_id“ size=“5“> <input type=“submit“ value=“Login“></p> </form>
Beispiel: Anmeldung mit Kunden-Nr
PSP der Startseite-Prozedur und alle nachfolgenden Prozeduren: Parameter fürKunden-Nr.
<%@ plsql parameter=“cust_id“ type=“number“ %><%@ plsql parameter=“cust_id“ type=“number“ %>
Speicherung der Kunden-Nr. in verstecktem Feld, ermöglicht Weitergabe beiAbschicken des Formulars (nicht günstig bei komplexeren Anwendungen!)
<input type=“hidden“ name=“cust_id“ value=<%= cust_id %“ > <input type=“hidden“ name=“cust_id“ value=<%= cust_id %“ >
© Prof. T. Kudraß, HTWK Leipzig
Verwendung von Javascript
keine Einschränkung gegenüber normalen HTML-Seiten
clientseitige Skriptsprache– Test von Benutzereingaben vor Abschicken in die Datenbank
Beispiel:– Prüfe bei Absenden des Formulars (onSubmit) durch Aufruf
einer Javascript-Funktion (chkFormular), die True oder False zurückliefert
– if TRUE Aufruf der PSP-Prozedur insertCheck– vergleiche Quellcode-Beispiel
© Prof. T. Kudraß, HTWK Leipzig
Anzeige von Master-Detail-Beziehungen (Beispiel)
<%@ plsql procedure=“main“ %><html><head><title>Master/Detail-Text</title></head><frameset rows=“40%,60%“> <frame src=“show_Master“ name=“Master“> <frame src=“show_Detail“ name=“Detail“></frameset></html>
<%@ plsql procedure=“main“ %><html><head><title>Master/Detail-Text</title></head><frameset rows=“40%,60%“> <frame src=“show_Master“ name=“Master“> <frame src=“show_Detail“ name=“Detail“></frameset></html>
Darstellung einer Master-Detail-Beziehung in FramesAnzeige der Master-Datensätze: show_MasterAnzeige der Detail-Datensätze: show_Detail
© Prof. T. Kudraß, HTWK Leipzig
PSP des Master-Frames
<%@ page language="PL/SQL" %> <%@ plsql procedure="show_Master" %> <html><head><title>Master-Datasets</title></head><body><form action="show_detail" target="Detail"><SELECT NAME="p_Cust_ID" size="1"><% for item in (select * from Customer order by Cust_name) loop %> <option value="<%= item.Cust_ID %>" ><%=item.Cust_Name %></option><% end loop; %> </select> <input type="submit" value="Bestellungen anzeigen"></form></body></html>
© Prof. T. Kudraß, HTWK Leipzig
PSP des Detail-Frames<%@ page language="PL/SQL" %> <%@ plsql procedure="show_detail" %> <%@ plsql parameter="p_Cust_ID" default="0"%><html><head><title> Detaildatensätze </title></head><body>
<form><table border="1" ><tr> <th align="center">Artikelname</td> <th align="center">Preis</td> <th align="center">Anzahl</td> <th align="center">Bestellnummer</td> <th align="center">Bestellstatus</td></tr><% for item in (SELECT Order_ID, Order_Number, Order_Sign, Stat_ID, Stat_Desc, Prod_Name, Prod_Price FROM CustOrders, Status, Products WHERE ORDER_CUST_ID=p_Cust_ID AND Stat_ID (+)=Order_Status AND Order_Prod_ID=Prod_ID ORDER BY Prod_Name ) loop
-- (+): Outer Join, um auch Bestellungen auszuwählen, die keinen Status haben%><tr> <td align="left"><%= item.Prod_Name %></td> <td align="left"><%= item.Prod_Price %></td> <td align="left"><%= item.Order_Number %></td> <td align="left"><%= item.Order_Sign %></td> <td align="left"><%= item.Stat_Desc %></td></tr><% end loop; %> </table></form></body></html>
PSP des Detail-Frames
© Prof. T. Kudraß, HTWK Leipzig
Ergebnis