Inspiracja , wiedza , realizacja
Jsystems

W przebudowie

Login



Java

Oracle

Linux

Android

PostgreSQL

Microsoft SQL Server

Instancje pakietu, wykorzystanie sekcja konstruktora, PRAGMA SERIALLY_REUSABLE

Data dodania: Jun 20, 2016
Data aktualizacji: Jun 20, 2016

Zwykłe pakiety działają w takich sposób, że jeśli posiadają jakąś publiczną zmienną i w ramach sesji ustawimy jej w jednym bloku jakąś wartość, a odwołamy się do tej zmiennej w innym, wartość tej zmiennej w drugim bloku pozostanie taka jaka była ustawiona w pierwszym. Sekcja konstruktora zostanie wykonana tylko raz w ramach danej sesji, chyba że przekompilujemy pakiet. To ma swoje plusy- choćby możemy do zmiennej tablicowej pakietu załadować dane pochodzące z zapytania i wykorzystywać je w wielu programach bez potrzeby ich ciągłego czytania. Z drugiej strony, takie dane pozostaną w pamięci i będą ją zajmować do końca sesji, a ta może trwać bardzo długo.

Oracle udostępnia wykorzystanie klauzuli „PRAGMA SERIALLY_REUSABLE” która zmienia ten stan rzeczy dla wybranego pakietu. Jej dodanie w pakiecie (a musimy do zrobić i w sekcji definicji i body pakietu), sprawi że wszystkie zmienne będą przywracane do wartości domyślnych a sekcja konstruktora będzie uruchamiana przy każdym wywołaniu w osobnych blokach. Jeśli wywołania będą zawarte w tym samym bloku, ustawione zmienne takimi pozostaną do zakończenia działania bloku. Z jednej strony zwalniamy często niepotrzebnie zajmowaną pamięć, z drugiej jeśli coś się nie powiedzie w ramach bloku, będziemy musieli zaczynać od nowa.

Pakietów ze zdefiniowaną pragmą „SERIALLY_REUSABLE” nie możemy wykorzystywać z poziomu wyzwalaczy, ani funkcji wywoływanych z poziomu SQL.


W poniższym przykładzie definiuję pakiet zawierający zmienną o domyślnej wartości 0, funkcję która ustawia wartość tej zmiennej na 1, oraz procedurę która wyświetla wartość tej zmiennej. Dodałem też sekcję konstruktora, aby było widać kiedy jest tworzona nowa instancja pakietu. Pakiet posiada też pragmę opisywaną wcześniej.



Po kompilacji pakietu wywołuję procedurę i funkcję w osobnych blokach, a także jedno i drugie w ramach wspólnego bloku:



Spójrzmy teraz na zawartość konsoli. Po ustawieniu zmiennej przez procedurę z pakietu jej wartość wynosi 1. W osobnym bloku uruchamiałem funkcję i jak widzimy funkcja ta zwróciła wartość domyślną zmiennej, a także co ważne ponownie został uruchomiony konstruktor pakietu. W trzecim przypadku gdzie uruchamiałem procedurę i funkcję w jednym bloku widzimy że funkcja widzi ustawioną przez procedurę wartość zmiennej, a sekcja konstruktora została uruchomiona raz dla nich obu.