Bazy danych w aplikacjach internetowych
Transkrypt
Bazy danych w aplikacjach internetowych
Tworzenie aplikacji WWW za pomoca˛ narz˛edzi PL/SQL Web Toolkit • Aplikacja WWW napisana w j˛ezyku PL/SQL składa si˛e ze zbioru programów składowanych (procedur, funkcji), cz˛esto zebranych w formie pakietu. • Komunikacja z przegladark ˛ a˛ WWW odbywa z użyciem protokołu HTTP. • Procedury PL/SQL generuja˛ dynamiczne strony HTML, tworzace ˛ interfejs użytkownika. • W tym celu wykorzystuje si˛e PL/SQL Web Toolkit, b˛edacy ˛ zbiorem wbudowanych pakietów Oracle’a służacych ˛ do tworzenia procedur PL/SQL generujacych ˛ w sposób dynamiczny strony HTML, pobierajace ˛ i zapisujace ˛ 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 zarzadzać ˛ ciasteczkami umożliwia porównywanie, manipulacj˛e łańcuchami znaków zarzadzanie ˛ 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> <TR> htp.tableRowOpen; htp.tableHeader(’Nagłówek’); <TH>Nagłówek</TH> <TD>dane</TD> htp.tableData(’dane’); 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: I Za pomoca˛ tagów HTML. Użytkownik wypełnia pola formularza na stronie WWW, a nast˛epnie wszystkie podane dane oraz informacje o wyborach użytkownika sa˛ przekazywane do procedury zapami˛etanej za pomoca˛ przycisku Submit formularza. I Za pomoca˛ adresów URL. Kiedy użytkownik klika na link, zbiór parametrów zostaje przekazany do procedury zapami˛etanej. Zazwyczaj, na jednej stronie umieszcza si˛e oddzielne odnośniki dla każdej możliwej operacji, jaka˛ użytkownik może wykonać. Wykorzystanie formularzy HTML do przesyłania danych Jako wartość atrybutu ACTION podajemy nazw˛e procedury składowanej. Do procedury sa˛ przekazywane dane z pól formularza HTML. Uwaga. Tylko wartości z pól, które maja˛ nazwy, sa˛ przekazywane. Jeżeli pole jest zablokowane (ma status disabled), nie jest dołaczane ˛ 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 odpowiadajacy ˛ każdemu nazwanemu polu formularza. Parametry te musza˛ mieć dokładnie takie same nazwy, jak odpowiednie pola formularza oraz zgodny typ danych. Uwaga. Do przekazania danych pomi˛edzy 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 generujacych ˛ strony WWW (najcz˛eściej w j˛ezyku HTML) jest przygotowywanie ich w postaci skryptów PL/SQL Server Pages (PSP). Skrypt PSP ma najcz˛eściej postać dokumentu HTML, w którym za pomoca˛ specjalnych znaczników zagnieżdżone sa˛ fragmenty kodu w PL/SQL generujace ˛ dynamiczne cz˛eści dokumentu w oparciu o dane pobrane z bazy danych. Idea zagnieżdżania kodu programu w „statycznych” dokumentach została zaczerpni˛eta z ASP (Active Server Pages Microsoft-u), wykorzystywana składnia jest zbliżona do JSP (Java Server Pages). Zaleta˛ stosowania mechanizmu PSP jest możliwość najpierw utworzenia strony WWW (w dowolnym edytorze tekstowym lub wykorzystujac ˛ narz˛edzia do projektowania HTML), a nast˛epnie umieszczenie wewnatrz ˛ kodu HTML bloków PL/SQL-a. Skrypt zapisujemy z rozszerzeniem .psp. Dokument PSP musi zostać załadowany do bazy danych pod postacia˛ procedury składowanej w PL/SQL narz˛edziem loadpsp. Tworzenie aplikacji WWW za pomoca˛ mechanizmu PSP Skrypt psp może zawierać tekst, tagi html, instrukcje PSP. Skrypt może mieć jedna˛ z form: - najprostsza sytuacja - jest to tylko plik html, który generuje statyczna˛ stron˛e www (dokładniej - utworzona procedura PL/SQL generuje dokładnie taki sam plik html); - typowa sytuacja: zawartość jest mieszana - zarówno kod HTML (odpowiadajacy ˛ za statyczne elementy strony), jak i kod PL/SQL (generujacy ˛ zawartość w sposób dynamiczny); - najbardziej skomplikowana sytuacja - mamy tylko kod PL/SQL, który odpowiada za wygenerowanie wszystkich elementów wynikowej strony www (łacznie ˛ z tagami typu <html>, <head>, <meta>, <body>, itp.) Ładowanie PSP do bazy Kompilacja i załadowanie do bazy przygotowanego skryptu PSP odbywa si˛e z użyciem narz˛edzia 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˛e PL/SQL o nazwie podanej w skrypcie PSP. Opcja replace - jeżeli w danym schemacie użytkownika była procedura o tej nazwie, to ja˛ usuwa i zast˛epuje nowa.˛ Uwaga. Do wdrożenia utworzonej strony wykorzystuje si˛e moduł mod_plsql (b˛edacy ˛ cz˛eścia˛ Oracle HTTP Server) lub wbudowana˛ bramk˛e PL/SQL (nie wymaga użycia komponentu Oracle HTTP Server) i korzysta si˛e 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 pomoca˛ Web Toolkit > <% htp.print(’Hello World!’); %> </BODY> </HTML> Załadowanie skryptu hello1.psp do bazy za pomoca˛ narz˛edzia 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 pomoca˛ 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 pomoca˛ Web Toolkit. > Hello World! </BODY> </HTML> Tworzenie stron za pomoca˛ PSP Narz˛edzie loadpsp tworzy i zapisuje w bazie procedur˛e 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 pomoca˛ instrukcji GRANT), dost˛ep do procedury można uzyskać za pomoca˛ przegladarki ˛ internetowej. Przy założeniu, że korzystamy z APEX-a na lokalnym serwerze na porcie 8080, a procedura ma nazw˛e HelloWorld1 w schemacie hr, wygenerowana strona b˛edzie pod adresem: http://127.0.0.1:8080/apex/hr.HelloWorld1 Dyrektywy PSP kontrolujace ˛ zachowanie strony page - dyrektywa strony - określa j˛ezyk skryptowy (w naszym przypadku PL/SQL), rodzaj dokumentu wynikowego, stron˛e kodowa˛ i kod, jaki ma być wykonany w przypadku wystapienia ˛ bł˛edu (do obsługi bł˛edów wykonania, może to być np. dokument HTML zawierajacy ˛ 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 sa˛ case-sensitive. Parametry parameter - dyrektywa parametrów- określa nazw˛e i opcjonalnie typ i wartość domyślna˛ 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ślna˛ można podawać stałe (stałe znakowe musza˛ być podane w apostrofach), można też użyć wartości specjalnych, np. NULL, SYSDATE. Dla przykładu, niech procedura wypiszPrac ma wypisywać list˛e pracowników działu o podanym oznaczeniu (przekazanym jako parametr wejściowy). Poczatek ˛ 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˛e 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 nazwa˛ procedury b˛edzie nazwa pliku zawierajacego ˛ skrypt PSP, czyli np. jeżeli plik ma nazw˛e 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, zostana˛ one przetworzone na jedna˛ sekcj˛e 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 poczatku ˛ skryptu. Dodawanie kodu wykonywalnego Dyrektywa bloku wykonywalnego <% ... %> - umożliwia wstawienie instrukcji PL/SQL w postaci całego bloku lub poszczególnych instrukcji, pomi˛edzy 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˛ e</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˛ e</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 moga˛ być zrzutowane w sposób niejawny, np. DATE, wykorzystuje si˛e funkcj˛e 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 łaczenia ˛ napisów ||. Komentarze, wstawianie danych tekstowych Wstawienie komentarza w skrypcie psp (który nie pojawi si˛e 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ślna˛ parametru, to otaczamy tekst apostrofami, a nast˛epnie bierzemy w cudzysłów, np. <%@ plsql parameter="in_players" default="’Babe Ruth’" %> Porównanie procedur składowanych PL/SQL i PSP Procedury PL/SQL PSP Długi kod PL/SQL, generujacy ˛ sformatowany wynik. Długi kod z użyciem dynamicznego HTML-a, generujacy ˛ stron˛e WWW. Tworzenie za pomoca˛ narz˛edzi Oracle. Wymaga tworzenia kodu HTML linia po linii. Migracja ze statycznych stron WWW. Tworzenie w dowolnym edytorze HTML-a. Umożliwia użycie JavaScript. Ułatwiona migracja z JSP (Java Server Pages), ponieważ używaja˛ tej samej składni.