Tworzenie aplikacji WWW za pomoca narzędzi PL/SQL Web Toolkit Aplikacja WWW napisana w języku PL/SQL składa się ze zbioru programów składowanych (procedur, funkcji), często zebranych w formie pakietu. Komunikacja z przeglądarką WWW odbywa z użyciem protokołu HTTP. Procedury PL/SQL generują dynamiczne strony HTML, tworzące interfejs użytkownika. W tym celu wykorzystuje się PL/SQL Web Toolkit, będący zbiorem wbudowanych pakietów Oracle a służących do tworzenia procedur PL/SQL generujących w sposób dynamiczny strony HTML, pobierające i zapisujące dane do bazy.
Wybrane pakiety wchodzace w skład PL/SQL Web Toolkit Pakiet HTP HTF OWA_CACHE OWA_COOKIE OWA_PATTERN OWA_SEC OWA_UTIL Opis generuje tagi HTML pozwala generować tagi HTML jako funkcje buforuje strony dla poprawy wydajności pozwala zarządzać ciasteczkami umożliwia porównywanie, manipulację łańcuchami znaków zarządzanie bezpieczeństwem dynamiczne generowanie kodu HTML, przekierowania do innych stron WWW
Pakiet HTP Procedura htp.print(tekst); htp.htmlopen; htp.headopen; htp.title( Tytuł ); htp.headclose; htp.bodyopen; htp.paragraph; htp.bodyclose; htp.htmlclose; Wynik HTML Wypisuje tekst <HTML> <HEAD> <TITLE> Tytuł </TITLE> </HEAD> <BODY> <P> </BODY> </HTML>
CREATE OR REPLACE PROCEDURE hello as BEGIN Htp.htmlOpen; Htp.bodyOpen; Htp.print( hello ); Htp.bodyClose; Htp.htmlClose; END; Wywołanie: http://host:port/apex/user.pakiet.nazwa_procedury np. http://localhost:8080/apex/ania.hello Uwaga. Należy nadać uprawnienie EXECUTE do procedury na PUBLIC. Wygodnie jest też stworzyć synonim publiczny.
Pakiet HTP.. htp.header(1, Nagłówek ); htp.line; htp.br; htp.centeropen; htp.centerclose; htp.bold( Tekst ); htp.anchor( url, nazwa, tekst ); htp.img( url, align, alt ); <H1> Nagłówek </H1> <HR> <BR> <CENTER> </CENTER> <B>Tekst</B> <A HREF="url" NAME="nazwa"> tekst </A> <IMG SRC="url" ALIGN="align" ALT="alt">
Pakiet HTP.. Tabele i listy htp.tableopen; <TABLE> htp.tablecaption( Podpis ); <CAPTION>Podpis</CAPTION> htp.tablerowopen; <TR> htp.tableheader( Nagłówek ); <TH>Nagłówek</TH> htp.tabledata( dane ); <TD>dane</TD> htp.tablerowclose; </TR> htp.tableclose; </TABLE> htp.listopen; htp.listitem( tekst ); htp.listclose; <UL> <LI>tekst </UL>
Znaczniki formularzy htp.formopen( url, method ); htp.formclose; htp.formtext( nazwa, rozmiar ); htp.formcheckbox( nazwa, wartość ); htp.formradio( nazwa, wartość ); htp.formselectopen( nazwa ); htp.formselectclose; htp.formselectoption( wartość ); htp.formsubmit( nazwa, wartość ); htp.formreset( wartość ); <FORM ACTION="url" METHOD="method"> </FORM> <INPUT TYPE="text" NAME="nazwa" SIZE="rozmiar"> <INPUT TYPE="checkbox" NAME="nazwa" VALUE="wartość"> <INPUT TYPE="radio" NAME="nazwa" VALUE="wartość"> <SELECT NAME="nazwa"> </SELECT> <OPTION>wartość <INPUT TYPE="submit" NAME="nazwa" VALUE="wartość"> <INPUT TYPE="reset" VALUE="wartość">
Formularze HTML: http://www.kurshtml.edu.pl/html/formularze.html Specyfikacja pakietu htp: http://docs.oracle.com/cd/e23943_01/portal.1111/e12042/pshtp.htm
Przekazywanie parametrów Główne metody przekazywania parametrów: Za pomocą tagów HTML. Użytkownik wypełnia pola formularza na stronie WWW, a następnie wszystkie podane dane oraz informacje o wyborach użytkownika są przekazywane do procedury zapamiętanej za pomocą przycisku Submit formularza. Za pomocą adresów URL. Kiedy użytkownik klika na link, zbiór parametrów zostaje przekazany do procedury zapamiętanej. Zazwyczaj, na jednej stronie umieszcza się oddzielne odnośniki dla każdej możliwej operacji, jaką użytkownik może wykonać.
Wykorzystanie formularzy HTML do przesyłania danych Jako wartość atrybutu ACTION podajemy nazwę procedury składowanej. Do procedury są przekazywane dane z pól formularza HTML. Uwaga. Tylko wartości z pól, które mają nazwy, są przekazywane. Jeżeli pole jest zablokowane (ma status disabled), nie jest dołączane do listy parametrów formularza. Uwaga. Procedura składowana wywołana przez formularz musi mieć odpowiedni zestaw parametrów wejściowych musi mieć parametr IN odpowiadający każdemu nazwanemu polu formularza. Parametry te muszą mieć dokładnie takie same nazwy, jak odpowiednie pola formularza oraz zgodny typ danych. Uwaga. Do przekazania danych pomiędzy procedurami składowanymi można użyć ukrytych pól formularza: <input type="hidden" name="nazwa" value="wartość" />
Tworzenie aplikacji WWW za pomoca mechanizmu PSP Drugim sposobem tworzenia procedur składowanych generujących strony WWW (najczęściej w języku HTML) jest przygotowywanie ich w postaci skryptów PL/SQL Server Pages (PSP). Skrypt PSP ma najczęściej postać dokumentu HTML, w którym za pomocą specjalnych znaczników zagnieżdżone są fragmenty kodu w PL/SQL generujące dynamiczne części dokumentu w oparciu o dane pobrane z bazy danych. Idea zagnieżdżania kodu programu w statycznych dokumentach została zaczerpnięta z ASP (Active Server Pages Microsoft-u), wykorzystywana składnia jest zbliżona do JSP (Java Server Pages). Zaletą stosowania mechanizmu PSP jest możliwość najpierw utworzenia strony WWW (w dowolnym edytorze tekstowym lub wykorzystując narzędzia do projektowania HTML), a następnie umieszczenie wewnątrz kodu HTML bloków PL/SQL-a. Skrypt zapisujemy z rozszerzeniem.psp. Dokument PSP musi zostać załadowany do bazy danych pod postacią procedury składowanej w PL/SQL narzędziem loadpsp.
Tworzenie aplikacji WWW za pomoca mechanizmu PSP Skrypt psp może zawierać tekst, tagi html, instrukcje PSP. Skrypt może mieć jedną z form: - najprostsza sytuacja - jest to tylko plik html, który generuje statyczną stronę www (dokładniej - utworzona procedura PL/SQL generuje dokładnie taki sam plik html); - typowa sytuacja: zawartość jest mieszana - zarówno kod HTML (odpowiadający za statyczne elementy strony), jak i kod PL/SQL (generujący zawartość w sposób dynamiczny); - najbardziej skomplikowana sytuacja - mamy tylko kod PL/SQL, który odpowiada za wygenerowanie wszystkich elementów wynikowej strony www (łącznie z tagami typu <html>, <head>, <meta>, <body>, itp.)
Ładowanie PSP do bazy Kompilacja i załadowanie do bazy przygotowanego skryptu PSP odbywa się z użyciem narzędzia wiersza poleceń loadpsp. Skrócona składnia polecenia: loadpsp -replace -user user_name/password file_name.psp loadpsp na podstawie skryptu PSP tworzy i zapisuje w schemacie danego użytkownika w bazie procedurę PL/SQL o nazwie podanej w skrypcie PSP. Opcja replace - jeżeli w danym schemacie użytkownika była procedura o tej nazwie, to ją usuwa i zastępuje nową. Uwaga. Do wdrożenia utworzonej strony wykorzystuje się moduł mod_plsql (będący częścią Oracle HTTP Server) lub wbudowaną bramkę PL/SQL (nie wymaga użycia komponentu Oracle HTTP Server) i korzysta się z pakietów PL/SQL Web Toolkit.
Przykładowy skrypt PSP (zapisany w pliku hello1.psp) <%@ plsql language="pl/sql" %> <%@ plsql procedure="helloworld1"%> <HTML> <HEAD> <TITLE>First PSP - HelloWorld1</TITLE> </HEAD> <BODY> <! Wypisanie samego tekstu. > Hello World! <BR><BR> <! Wypisanie tekstu za pomocą Web Toolkit > <% htp.print( Hello World! ); %> </BODY> </HTML> Załadowanie skryptu hello1.psp do bazy za pomocą narzędzia loadpsp (nazwa procedury to HelloWorld1, w schemacie użytkownika hr): loadpsp -replace -user hr/password hello1.psp
Procedura utworzona w bazie create or replace PROCEDURE HelloWorld1 AS BEGIN NULL; htp.prn( ); /(generuje tekst, nie dodaje znaku końca linii /n) htp.prn( <HTML> <HEAD> <TITLE>First PSP - HelloWorld1</TITLE> </HEAD> <BODY> <! Wypisanie samego tekstu. > Hello World! <BR><BR> <! Wypisanie tekstu za pomocą Web Toolkit. > ); htp.print( Hello World! ); htp.prn( </BODY> </HTML> ); END;
Wynikowy kod HTML utworzonej strony WWW <HTML> <HEAD> <TITLE>First PSP - HelloWorld1</TITLE> </HEAD> <BODY> <! Wypisanie samego tekstu. > Hello World! <BR><BR> <! Wypisanie tekstu za pomocą Web Toolkit. > Hello World! </BODY> </HTML>
Tworzenie stron za pomoca PSP Narzędzie loadpsp tworzy i zapisuje w bazie procedurę PL/SQL. Dodaje odpowiedni kod - umieszcza kod procedury w bloku BEGIN.. END, każdy tag HTML jest obudowany przy użyciu odpowiedniej procedury z pakietu HTP. Po utworzeniu procedury w bazie (i nadaniu odpowiednich uprawnień za pomocą instrukcji GRANT), dostęp do procedury można uzyskać za pomocą przeglądarki internetowej. Przy założeniu, że korzystamy z APEX-a na lokalnym serwerze na porcie 8080, a procedura ma nazwę HelloWorld1 w schemacie hr, wygenerowana strona będzie pod adresem: http://127.0.0.1:8080/apex/hr.helloworld1
Dyrektywy PSP kontrolujace zachowanie strony page - dyrektywa strony - określa język skryptowy (w naszym przypadku PL/SQL), rodzaj dokumentu wynikowego, stronę kodową i kod, jaki ma być wykonany w przypadku wystąpienia błędu (do obsługi błędów wykonania, może to być np. dokument HTML zawierający odpowiedni komunikat, zapisany z rozszerzeniem.psp) Składnia: <%@ page language="pl/sql" contenttype="content type string"/opcjonalnie charset="encoding" errorpage="file.psp" >/opcjonalnie np. <%@ page language="pl/sql" %> <%@ page contenttype="text/html" %> Uwaga. Nazwy atrybutów contenttype i errorpage są case-sensitive.
Parametry parameter - dyrektywa parametrów- określa nazwę i opcjonalnie typ i wartość domyślną każdego z parametrów wejściowych procedury PL/SQL. Składnia: <%@ plsql parameter="parameter name" type="pl/sql type"/opcjonalnie default="value" %>/opcjonalnie np. <%@ plsql parameter="emp_id" type="number" %> <%@ plsql parameter="dzial_id" type="number" default="null" %> <%@ plsql parameter="dzial" type="char" default=" 000 " %> Uwaga. Domyślnie, każdy parametr jest typu VARCHAR2, jeżeli chcemy podać inny typ, należy użyć atrybutu type. Jako wartość domyślną można podawać stałe (stałe znakowe muszą być podane w apostrofach), można też użyć wartości specjalnych, np. NULL, SYSDATE.
Dla przykładu, niech procedura wypiszprac ma wypisywać listę pracowników działu o podanym oznaczeniu (przekazanym jako parametr wejściowy). Początek skryptu w pliku wypiszprac.psp może mieć postać: <%@ page language="pl/sql" %> <%@ plsql parameter="dzial" type="char" default=" 000 " %> <%! cursor cemp(nr char) is select last_name, first_name, to_char(hire_date, dd-mm-yyyy ) as h_date from employee where dept_no=nr order by 1; %> W odwołaniu do tej strony (z wykorzystaniem metody GET) parametry podajemy po znaku zapytania? jako pary nazwa=wartość, oddzielone znakiem &, np.: http://127.0.0.1:8080/apex/hr.wypiszprac?dzial=600
Określanie nazwy procedury plsql procedure - dyrektywa procedury- określa nazwę procedury PL/SQL, jaka ma zostać utworzona. Składnia: <%@ plsql procedure="procname" %> np. <%@ plsql procedure="helloworld1" %> <%@ plsql procedure="show_employees" %> Uwaga. Jeżeli nie użyjemy tej instrukcji, to domyślnie nazwą procedury będzie nazwa pliku zawierającego skrypt PSP, czyli np. jeżeli plik ma nazwę hello1.psp, to zostanie utworzona procedura o nazwie hello1.
Deklarowanie zmiennych procedury Dyrektywa bloku deklaracji <%!... %> - umożliwia stworzenie sekcji deklaracji procedury PL/SQL. W jednej instrukcji można zadeklarować wiele zmiennych czy kursorów, poszczególne deklaracje oddzielamy średnikiem. W jednym skrypcie psp może być kilka takich instrukcji, zostaną one przetworzone na jedną sekcję deklaracji procedury. Składnia: <%! PL/SQL declaration; PL/SQL declaration;... %> np. <%! CURSOR emp_cursor IS SELECT last_name, first_name FROM hr.employees ORDER BY last_name; %> Uwaga. Najwygodniej jest umieszczać wszystkie dyrektywy i bloki deklaracji razem, na początku skryptu.
Dodawanie kodu wykonywalnego Dyrektywa bloku wykonywalnego <%... %> - umożliwia wstawienie instrukcji PL/SQL w postaci całego bloku lub poszczególnych instrukcji, pomiędzy które można wstawiać tagi HTML lub inne dyrektywy. Składnia: <% PL/SQL statement; PL/SQL statement;... %> np. <table border="1" width="60%" align="center"> <tr> <th>imię</th> <th>nazwisko</th> <th>data zatrudnienia</th> </tr> <% for emp in cemp(dzial) loop %> <tr> <td> <%=emp.last_name %> </td> <td> <%=emp.first_name %> </td> <td> <%=emp.h_date %> </td> </tr> <% end loop; %> </table>
Fragment utworzonej procedury PL/SQL htp.prn( <table border="1" width="60%" align="center"> <tr> <th>imię</th> <th>nazwisko</th> <th>data zatrudnienia</th> </tr> ); for emp in cemp(dzial) loop htp.prn( <tr> <td> ); htp.prn(emp.last_name ); htp.prn( </td> <td> ); htp.prn(emp.first_name ); htp.prn( </td> <td> ); htp.prn(emp.h_date ); htp.prn( </td> </tr> ); end loop; htp.prn( </table> </body>
Dyrektywa wyrażenia Dyrektywa wyrażenia zwraca pojedyncze wyrażenie PL/SQL, takie jak string, wyrażenie arytmetyczne, wywołanie funkcji. Wynik jest podstawiany jako string w danym miejscu strony HTML. Wyrażenie wynikowe musi to być albo string, albo wyrażenie, które można zrzutować na string. Dla tych typów, które nie mogą być zrzutowane w sposób niejawny, np. DATE, wykorzystuje się funkcję TO_CHAR. Składnia: <%= expression %> np. <%= emp.last_name %> <%= Nazwisko pracownika to emp.last_name %> <%= to_char(data, dd-mm-yyyy ) %> Uwaga. Nie ma znaku średnika na końcu. Można używać operatora łączenia napisów.
Komentarze, wstawianie danych tekstowych Wstawienie komentarza w skrypcie psp (który nie pojawi się w kodzie HTML ani w kodzie procedury PL/SQL): <%- - PSP comment text - -%> Komentarz widoczny w HTML: <!- - HTML comment text - -> Komentarz widoczny w kodzie PL/SQL, ale nie w HTML: <% - - Comment in PL/SQL code %> Jeżeli chcemy wstawić jakiś tekst, który ma być po skompilowaniu procedury w pojedynczych apostrofach, np. wartość domyślną parametru, to otaczamy tekst apostrofami, a następnie bierzemy w cudzysłów, np. <%@ plsql parameter="in_players" default=" Babe Ruth " %>
Porównanie procedur składowanych PL/SQL i PSP Procedury PL/SQL Długi kod PL/SQL, generujący sformatowany wynik. Tworzenie za pomocą narzędzi Oracle. Wymaga tworzenia kodu HTML linia po linii. Migracja ze statycznych stron WWW. PSP Długi kod z użyciem dynamicznego HTML-a, generujący stronę WWW. Tworzenie w dowolnym edytorze HTML-a. Umożliwia użycie JavaScript. Ułatwiona migracja z JSP (Java Server Pages), ponieważ używają tej samej składni.