czwartek, 9 stycznia 2014

Klauzula NOCOPY w PL/SQL

Klauzulę NOCOPY możemy stosować przy parametrach OUT oraz IN OUT . Sprawia ona że wartość przekazana przez parametr nie jest kopiowana (jak to się dzieje domyślnie) a przekazywana jest referencja. To oznacza, że przekazywany jest wskaźnik do obszaru pamięci, a nie wartość jako taka. Efekt jest taki, że zarówno procedura z parametrem jak i blok (lub inna procedura czy funkcja) ją wywołujący działają na TYCH SAMYCH danych, bo chodzi o tą samą przestrzeń w pamięci operacyjnej.





Z jednej strony stosowanie klauzuli NOCOPY może nam pomóc – zwłaszcza przy przekazywaniu przez parametr typu OUT dużych wartości np. długich tablic albo dużych obiektów. Z drugiej strony, jeśli np. w procedurze nastąpi jakiś wyjątek, to w naszej przekazanej zmiennej może znaleźć się coś innego niż byśmy się spodziewali. Poniżej przedstawiam przykład takiej sytuacji:





Jak widzimy, w wyniku wywołanego wyjątku, przetwarzanie w procedurze nie dobiegło do końca. W efekcie w zmiennej y bloku wywołującego znalazł się tekst „W trakcie przetwarzania” zamiast „Oryginalny oryginał”

piątek, 3 stycznia 2014

Parametry typu IN, OUT, IN OUT w procedurach i funkcjach PL/SQL

Dla procedur oraz funkcji możemy definiować opcjonalne parametry. Mogą występować w trzech typach:

IN – parametr tylko do odczytu, poprzez który dane zostają przekazane do podprogramu.


OUT – Służy do zwracania wartości z podprogramu. Ma wartość NULL do momentu kiedy zostanie zainicjalizowana.



IN OUT – Połączenie dwóch powyższych typów. Podczas wywoływania programu tym parametrem przekazywane są do niego wartości, a po zakończeniu wykonywania zwracane. Stosuje się go gdy dane wejściowe mają zostać zmienione podczas działania programu.






Podczas deklarowania parametrów dla procedury lub funkcji nie ma sztywnych ograniczeń co do ich ilości oraz kolejności. Parametry mogę zadeklarować na kilka różnych sposobów i poniżej omawiam to na przykładach:

wejsciowy1 – parametr wejścia typu varchar2, nie posiada wartości domyślnej i dlatego przy wywoływaniu podprogramu będę zmuszony ją podać.

wejsciowy2 oraz wejsciowy3 - dwa sposoby zadeklarowania wartości domyślnej dla parametru. Jeśli nie przypiszę żadnej wartości, przypisana zostanie automatycznie wartość występująca po DEFAULT lub znaku przypisania. Podczas wywoływania podprogramu nie muszę podawać wartości do tego parametru.

wejsciowy4 – ponieważ nie określiłem jaki ma to być typ parametru, Oracle domyślnie przyjmuje że jest ot parametr typu IN.

wejsciowy5 – parametr typu wejściowego numerycznego który będę musiał uzupełnić przy wywoływaniu procedury.

wyjsciowy – parametr wyjściowy typu number. Nie mogę określić dla niego wartości domyślnej, ani wartości wejściowej przy wywołaniu programu. Mogę to zrobić jedynie wewnątrz podprogramu.




dwustronny – parametr do którego nie mogę przypisać wartości domyślnej przy wywoływaniu podprogramu. Mogę podać do niego wartość podczas wywoływania podprogramu.


Mogę określać typ parametru, nie mogę natomiast długości. Zamiast więc stosować varchar2(243) muszę zastosować samo varchar2. 

Przykład wzajemnego wywoływania procedur oraz praktycznego przekazywania parametrów.




  1. Tworzę procedurę o nazwie „wypisywacz”, która po otrzymaniu danych w parametrach wejściowych (imię i nazwisko są domyślnie IN) ma wypisać na ekranie powitanie. Ponadto do parametru wyjściowego wzrost ma przypisać wartość 178.




    2. Z bloku anonimowego wywołuję przed momentem stworzoną procedurę podając wartości dla parametrów wejściowych, oraz nazwę zmiennej do której ma zostać przypisana wartość wyjściowa.




    Jak widać, po wywołaniu procedury „wypisywacz” wartość zmiennej do której została przypisana wartość wewnątrz procedury „wypisywacz” uległa zmianie.

    Parametrów wcale nie muszę wypisywać w dokładnie takiej kolejności w jakiej są zdeklarowane w definicji funkcji/procedury. Jedynym warunkiem jest określenie podczas wywoływania podprogramu do jakiej zmiennej przypisuję jaką wartość.