Procedury składowane w PostgreSQL/Język PLpgSQL/Deklaracja zmiennych
Deklaracja zmiennej ma składnię:
nazwa [ CONSTANT ] typ [NOT NULL] [ { DEFAULT | := } wartość domyślna ];
Nazwa nie może zaczynać się cyfrą i musi składać się z dużych i małych liter łacińskich, cyfr i znaku podkreślenia.
Jeśli nie zostanie podana wartość domyślna, wartość zmiennej jest inicjowana na NULL.
Jeśli zmienna zostanie zadeklarowana jako NOT NULL musi mieć wartość domyślną. Jednocześnie przypisanie wartości NULL tej zmiennej w ciele procedury skutkować będzie błędem czasu wykonania.
Jeśli zostanie użyte słowo kluczowe CONSTANT, nazwa reprezentuje wartość stałą i musi zostać zainicjowana.
Przykład
[edytuj]CREATE OR REPLACE FUNCTION deklaracje(a integer) RETURNS void AS $$
DECLARE
x integer DEFAULT 1; -- wartość początkowa
y integer := 5; -- wartość początkowa
z integer := a; -- wartość początkowa z argumentu
w integer NOT NULL := a;
k CONSTANT integer := 9;
BEGIN
w := NULL; -- błąd czasu wykonywania! 'w' nie może być NULL
k := 8; -- błąd kompilacji! 'k' oznaczone jako wartość stała
END;
$$ LANGUAGE 'plpgsql';
Kopiowanie typów
[edytuj]Najprostszym sposobem podania typu zmiennej jest podanie jego pełnej nazwy:
k integer; -- zmienna x typu całkowitego
predkosc real; -- zmienna predkosc typu rzeczywistego
Czasem o wiele wygodniej użyć takiego typu, jak wcześniej zdefiniowany obiekt, szczególnie w procedurach generycznych:
- tabela,
- kolumna tabeli,
- wcześniej zadeklarowana zmienna.
Służą do tego operatory %TYPE dla typów skalarnych i zmiennych oraz %ROWTYPE dla relacji. UWAGA! Nie można zadeklarować tablicy z użyciem operatora %TYPE.
CREATE TABLE pracownicy (imie text, nazwisko text, wiek integer);
CREATE OR REPLACE FUNCTION funkcja(wspolczynnik real) RETURNS void AS $$
DECLARE
napis pracownicy.imie%TYPE; -- typ text
w wspolczynnik%TYPE; -- typ real
r1 pracownicy; -- typ pracownicy
r2 pracownicy%ROWTYPE; -- typ pracownicy
r3 w%TYPE; -- typ real
BEGIN
RAISE NOTICE 'typ zmiennej: napis=%, w=%, r1=%, r2=%, r3=%',
pg_typeof(napis),
pg_typeof(w),
pg_typeof(r1),
pg_typeof(r2),
pg_typeof(r3)
;
END;
$$ LANGUAGE 'plpgsql';
SELECT funkcja(0.5);
Zakres widoczności
[edytuj]W blokach zagnieżdżonych widoczne są zmienne z bloków nadrzędnych, natomiast w przypadku powtórzenia nazwy są przesłaniane.
Możliwy jest dostęp do zmiennych z bloków zewnętrznych przez ich etykiety, tzn. podanie pełnej nazwy etykieta.nazwa_zmiennej. W identyczny sposób można odwoływać się do zmiennych z etykietowanych pętli iterujących po liczbach.
Przykład 1
[edytuj]CREATE OR REPLACE FUNCTION zakresy() RETURNS void AS $$
<<blok>>
DECLARE
tekst text := 'tekst';
liczba integer := 123;
BEGIN
RAISE NOTICE 'tekst=%, liczba=%', tekst, liczba;
<<blok_zagniezdzony>>
DECLARE
tekst text := 'zagnieżdżony'; -- przesłanienie
liczba2 integer := liczba; -- inicjalizacja zmienną
BEGIN
RAISE NOTICE 'blok.tekst=%, tekst=%, liczba=%, liczba2=%',
blok.tekst, tekst, liczba, liczba2;
END;
RAISE NOTICE 'tekst=%, liczba=%', tekst, liczba;
END
$$ LANGUAGE 'plpgsql';
$ SELECT zakresy(); NOTICE: tekst=tekst, liczba=123 NOTICE: blok.tekst=tekst, tekst=zagnieżdżony, liczba=123, liczba2=123 NOTICE: tekst=tekst, liczba=123
Przykład 2 - pętla FOR
[edytuj]CREATE OR REPLACE FUNCTION forfor() RETURNS VOID AS $$
BEGIN
<<petla_1>>
FOR i IN 1 .. 5 LOOP
<<petla_2>>
FOR i IN 6 .. 7 LOOP
RAISE NOTICE 'i=%, i=%', petla_1.i, petla_2.i;
END LOOP;
END LOOP;
END;
$$ LANGUAGE 'plpgsql';
$ SELECT forfor(); NOTICE: i=1, i=6 NOTICE: i=1, i=7 NOTICE: i=2, i=6 NOTICE: i=2, i=7 NOTICE: i=3, i=6 NOTICE: i=3, i=7 NOTICE: i=4, i=6 NOTICE: i=4, i=7 NOTICE: i=5, i=6 NOTICE: i=5, i=7
Aliasy
[edytuj]W bloku deklaracji można również tworzyć aliasy, alternatywne nazwy dla zadeklarowanych zmiennych i argumentów funkcji oraz innych aliasów.
Przede wszystkim może to mieć zastosowanie do nazywania nienazwanych argumentów (we wcześniejszych wersjach PostgreSQL było to konieczne, ponieważ nazwanych argumentów nie było), jak również do wprowadzania krótszych nazw.
Nie można utworzyć aliasu do wyrażeń, np. do konkretnego elementu tablicy.
Składnia:
nowa_nazwa ALIAS FOR istniejaca_nazwa;
Przykład
[edytuj]CREATE OR REPLACE FUNCTION test(text, integer) RETURNS void AS $$
DECLARE
napis1 text := 'zmienna';
napis2 ALIAS FOR $1; -- parametr
liczba ALIAS FOR $2; -- parametr
napis3 ALIAS FOR napis1; -- zmienna
napis4 ALIAS FOR napis2; -- inny alias
BEGIN
NULL;
END;
$$ LANGUAGE 'plpgsql';
Kursory
[edytuj]Składnia deklaracji kursora:
nazwa REFCURSOR; nazwa CURSOR [ ( argumenty ) ] FOR zapytanie;
Kursory są zawsze typu REFCURSOR jednak w zależności od deklaracji, mogą nieograniczone (ang. unbounded), tj. takie, dla których zapytanie zostanie określone dopiero podczas otwieranie kursora, oraz ograniczone (ang. bounded) z zapytaniem podanym w deklaracji.
Jedynie kursorów ograniczonych można używać w pętlach FOR.
Przykłady
[edytuj]DECLARE
kursor1 REFCURSOR;
kursor2 CURSOR FOR SELECT kolumna FROM tabela;
kursor3 CURSOR(id integer) FOR SELECT kolumna FROM tabela WHERE tabela.id = id;
BEGIN
...