Oracle PL/SQL-pakket: type, specificatie, body [voorbeeld]
โก Slimme samenvatting
PL/SQL-pakketten groeperen gerelateerde procedures, functies, variabelen, cursors en uitzonderingen in รฉรฉn schema-object met een specificatie en een body. De specificatie declareert de publieke interface, terwijl de body de private implementatie bevat, wat de modulariteit en prestaties verbetert.

Wat zit er in? Oracle?
Oracle PL / SQL pakket is een logische groepping van verwant subprogramma's (procedure/functie) in รฉรฉn enkel element. Een pakket wordt gecompileerd en opgeslagen als een databaseobject dat later opnieuw kan worden gebruikt.
Componenten van pakketten
Een PL/SQL-pakket bestaat uit twee componenten.
- Pakket specificatie
- Pakket lichaam:
Pakket specificatie
De pakketspecificatie bestaat uit een verklaring van alle openbare variabelen, cursors, objecten, procedures, functies en uitzonderingen.
Hieronder volgen enkele kenmerken van de pakketspecificatie.
- De elementen die in de specificatie zijn gedeclareerd, zijn toegankelijk van buiten het pakket. Zulke elementen worden publieke elementen genoemd.
- De pakketspecificatie is een op zichzelf staand element, wat betekent dat deze los kan bestaan โโvan de pakketinhoud.
- Wanneer naar een pakket wordt verwezen, wordt er voor die specifieke sessie een instantie van dat pakket aangemaakt.
- Nadat het exemplaar voor een sessie is aangemaakt, zijn alle pakketelementen die in dat exemplaar worden geรฏnitieerd geldig tot het einde van de sessie.
Syntaxis
CREATE [OR REPLACE] PACKAGE <package_name> IS <sub_program and public element declaration> . . END <package name>
De bovenstaande syntax laat zien hoe de pakketspecificatie wordt aangemaakt.
Pakket lichaam:
De inhoud van een pakket bestaat uit de definitie van alle elementen die in de pakketspecificatie zijn opgenomen. Het kan ook definities bevatten van elementen die niet in de specificatie zijn gedeclareerd; deze elementen worden private elementen genoemd en kunnen alleen vanuit het pakket zelf worden aangeroepen.
Hieronder staan โโde kenmerken van een verpakkingslichaam.
- Het moet definities bevatten voor alle subprogramma's/cursors die in de specificatie zijn gedeclareerd.
- Het kan ook meer subprogramma's of andere elementen bevatten die niet in de specificatie zijn opgenomen. Deze worden private elementen genoemd.
- Het is een afhankelijk object en het is afhankelijk van de pakketspecificatie.
- De status van de pakketbody wordt 'Ongeldig' wanneer de specificatie wordt gecompileerd. Daarom moet deze na elke compilatie van de specificatie opnieuw worden gecompileerd.
- De privรฉ-elementen moeten eerst worden gedefinieerd voordat ze in de pakkettekst worden gebruikt.
- Het eerste deel van de pakketbody is het globale declaratiegedeelte. Dit omvat variabelen, cursors en private elementen (forward declaration) die zichtbaar zijn voor het hele pakket.
- Het laatste deel van het pakket is het initialisatiegedeelte, dat eenmalig wordt uitgevoerd wanneer een pakket voor het eerst in de sessie wordt aangeroepen.
Syntax:
CREATE [OR REPLACE] PACKAGE BODY <package_name> IS <global_declaration part> <Private element definition> <sub_program and public element definition> . <Package Initialization> END <package_name>
De bovenstaande syntax laat zien hoe de pakketbody wordt aangemaakt.
Nu gaan we bekijken hoe we in het programma naar pakketelementen kunnen verwijzen.
Verwijzende pakketelementen
Zodra de elementen in het pakket zijn gedeclareerd en gedefinieerd, moeten we ernaar verwijzen om ze te kunnen gebruiken.
Alle openbare elementen van het pakket kunnen worden benaderd door de pakketnaam te gebruiken, gevolgd door de elementnaam, gescheiden door een punt, bijvoorbeeld ' . '.
De openbare variabelen van het pakket kunnen ook op dezelfde manier worden gebruikt om er waarden aan toe te kennen en eruit op te halen, bijvoorbeeld: ' . '.
Pakket maken in PL/SQL
In PL/SQL wordt er, telkens wanneer er in een sessie naar een pakket wordt verwezen of het wordt aangeroepen, een nieuwe instantie van dat pakket aangemaakt.
Oracle biedt een mogelijkheid om pakketelementen te initialiseren of om enige activiteit uit te voeren op het moment dat deze instantie wordt gemaakt via 'Pakketinitialisatie'.
Dit is niets anders dan een uitvoeringsblok dat in de pakketbody wordt geschreven nadat alle pakketelementen zijn gedefinieerd. Dit blok wordt uitgevoerd telkens wanneer een pakket voor het eerst in de sessie wordt aangeroepen.
De onderstaande schermafbeelding laat zien hoe het initialisatieblok van het pakket in de pakketbody wordt geplaatst bij het aanmaken van een pakket.
Syntaxis
CREATE [OR REPLACE] PACKAGE BODY <package_name> IS <Private element definition> <sub_program and public element definition> . BEGIN <Package Initialization> END <package_name>
De bovenstaande syntaxis toont de definitie van pakketinitialisatie in de pakketbody.
Verklaringen doorsturen
Een forward-declaratie of -referentie in een pakket houdt in dat de private elementen afzonderlijk worden gedeclareerd en later in de pakketbody worden gedefinieerd.
Privรฉ-elementen kunnen alleen worden aangeroepen als ze al in de pakketbody zijn gedeclareerd. Om die reden wordt er gebruikgemaakt van forward declaration. Het gebruik ervan is echter vrij ongebruikelijk, omdat privรฉ-elementen meestal in het eerste deel van de pakketbody worden gedeclareerd en gedefinieerd.
Voorwaartse aangifte is een optie van OracleHet is niet verplicht, en het gebruik ervan is geheel aan de programmeur zelf.
De onderstaande schermafbeelding laat zien hoe een privรฉ-element vooraf wordt gedeclareerd en later in de pakketbody wordt gedefinieerd.
Syntax:
CREATE [OR REPLACE] PACKAGE BODY <package_name> IS <Private element declaration> . . . <Public element definition that refer the above private element> . . <Private element definition> . BEGIN <package_initialization code>; END <package_name>
De bovenstaande syntaxis toont forward declaration. De private elementen worden apart gedeclareerd in het forward gedeelte van het pakket, en ze zijn gedefinieerd in het latere gedeelte.
Cursorsgebruik in pakket
In tegenstelling tot andere elementen moet men voorzichtig zijn bij het gebruik van cursors binnen het pakket.
Als de cursor is gedefinieerd in de pakketspecificatie of in het globale deel van de pakketbody, blijft de cursor, zodra deze is geopend, bestaan โโtot het einde van de sessie.
Daarom moet men altijd het cursorattribuut '%ISOPEN' gebruiken om de status van de cursor te controleren voordat men ernaar verwijst.
Overbelasting
Overloading is het concept van het hebben van meerdere subprogramma's met dezelfde naam. Deze subprogramma's verschillen van elkaar door het aantal parameters, de typen parameters of het retourtype. Met andere woorden, subprogramma's met dezelfde naam, maar met een verschillend aantal parameters, verschillende parametertypen of een verschillend retourtype, worden beschouwd als overloading.
Dit is handig wanneer veel subprogramma's dezelfde taak moeten uitvoeren, maar de manier waarop ze aangeroepen moeten worden, verschilt. In dat geval blijft de naam van het subprogramma voor alle subprogramma's hetzelfde en worden de parameters aangepast aan de aanroepinstructie.
Voorbeeld 1: In dit voorbeeld maken we een pakket om de waarden van de informatie van een medewerker in de tabel 'emp' op te halen en in te stellen. De functie `get_record` retourneert het recordtype voor het opgegeven medewerkersnummer, en de procedure `set_record` voegt het recordtype in de tabel 'emp' in.
Stap 1) Het opstellen van de pakketspecificatie
De onderstaande schermafbeelding toont hoe de pakketspecificatie guru99_get_set wordt aangemaakt. Oracle.
CREATE OR REPLACE PACKAGE guru99_get_set IS PROCEDURE set_record (p_emp_rec IN emp%ROWTYPE); FUNCTION get_record (p_emp_no IN NUMBER) RETURN emp%ROWTYPE; END guru99_get_set; /
Output:
Package created
Code Uitleg
- Code regel 1-5: Het pakketspecificatie voor guru99_get_set wordt aangemaakt met รฉรฉn procedure en รฉรฉn functie. Deze twee zijn nu openbare elementen van dit pakket.
Stap 2) Het pakket bevat een pakketbody, waarin de daadwerkelijke definities van alle procedures en functies zijn vastgelegd. In deze stap wordt de pakketbody aangemaakt.
De onderstaande schermafbeelding toont de definitie van de pakketbody guru99_get_set in Oracle.
CREATE OR REPLACE PACKAGE BODY guru99_get_set IS PROCEDURE set_record(p_emp_rec IN emp%ROWTYPE) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO emp VALUES(p_emp_rec.emp_name,p_emp_rec.emp_no, p_emp_rec.salary,p_emp_rec.manager); COMMIT; END set_record; FUNCTION get_record(p_emp_no IN NUMBER) RETURN emp%ROWTYPE IS l_emp_rec emp%ROWTYPE; BEGIN SELECT * INTO l_emp_rec FROM emp where emp_no=p_emp_no; RETURN l_emp_rec; END get_record; BEGIN dbms_output.put_line('Control is now executing the package initialization part'); END guru99_get_set; /
Output:
Package body created
Code Uitleg
- Code lijn 7: Het pakketlichaam aanmaken.
- Code regel 9-16: Het definiรซren van het element 'set_record' dat in de specificatie is gedeclareerd. Dit is hetzelfde als het definiรซren van een zelfstandige procedure in PL/SQL.
- Code regel 17-24: Het element 'get_record' definiรซren. Dit is hetzelfde als het definiรซren van een zelfstandige functie.
- Code regel 25-26: Het pakketinitialisatiegedeelte definiรซren.
Stap 3) Een anoniem blok creรซren om de records in te voegen en weer te geven door te verwijzen naar het hierboven gemaakte pakket.
De onderstaande schermafbeelding toont het anonieme blok dat het pakket aanroept, samen met de uitvoer ervan. Oracle.
DECLARE l_emp_rec emp%ROWTYPE; l_get_rec emp%ROWTYPE; BEGIN dbms_output.put_line('Insert new record for employee 1004'); l_emp_rec.emp_no:=1004; l_emp_rec.emp_name:='CCC'; l_emp_rec.salary:=20000; l_emp_rec.manager:='BBB'; guru99_get_set.set_record(l_emp_rec); dbms_output.put_line('Record inserted'); dbms_output.put_line('Calling get function to display the inserted record'); l_get_rec:=guru99_get_set.get_record(1004); dbms_output.put_line('Employee name: '||l_get_rec.emp_name); dbms_output.put_line('Employee number:'||l_get_rec.emp_no); dbms_output.put_line('Employee salary:'||l_get_rec.salary); dbms_output.put_line('Employee manager:'||l_get_rec.manager); END; /
Output:
Insert new record for employee 1004 Control is now executing the package initialization part Record inserted Calling get function to display the inserted record Employee name: CCC Employee number: 1004 Employee salary: 20000 Employee manager: BBB
Code Uitleg:
- Code regel 34-37: De gegevens voor de variabele van het recordtype worden in een anoniem blok ingevuld om het element 'set_record' van het pakket aan te roepen.
- Code lijn 38: Er is een aanroep gedaan naar 'set_record' van het guru99_get_set-pakket. Het pakket is nu geรฏnstantieerd en blijft actief tot het einde van de sessie. Het initialisatiegedeelte van het pakket wordt uitgevoerd omdat dit de eerste aanroep van het pakket is, en de record wordt door het 'set_record'-element in de tabel ingevoegd.
- Code lijn 41: Het element 'get_record' wordt aangeroepen om de details van de ingevoegde medewerker weer te geven. Het pakket wordt tijdens deze aanroep voor de tweede keer aangeroepen, maar het initialisatiegedeelte wordt niet opnieuw uitgevoerd, omdat het pakket in deze sessie al is geรฏnitialiseerd.
- Code regel 42-45: Afdrukken van de gegevens van de werknemer.
Afhankelijkheid in pakketten
Aangezien het pakket een logische groep isping Het is een samenhangend geheel met andere zaken en kent een aantal afhankelijkheden. De volgende afhankelijkheden moeten in acht worden genomen.
- Een specificatie is een op zichzelf staand object.
- De behuizing van een pakket is afhankelijk van de specificaties.
- De pakketinhoud kan afzonderlijk worden gecompileerd. Telkens wanneer de specificatie wordt gecompileerd, moet de pakketinhoud opnieuw worden gecompileerd, omdat deze anders ongeldig wordt.
- Het subprogramma in de pakketbody dat afhankelijk is van een privรฉ-element, moet pas na de declaratie van dat privรฉ-element worden gedefinieerd.
- De databaseobjecten waarnaar in de specificatie en de inhoud wordt verwezen, moeten een geldige status hebben op het moment van compilatie van het pakket.
Pakketinformatie
Zodra het pakket is aangemaakt, is de pakketinformatie, zoals de pakketbron, details van de subprogramma's en details van de overbelasting, beschikbaar in de Oracle datadictionarytabellen.
Onderstaande tabel toont de gegevenswoordenlijsttabel en de pakketinformatie die in elke tabel beschikbaar is.
| Tafel naam | Beschrijving | Vraag |
|---|---|---|
| ALLE_OBJECTEN | Geeft details over het pakket, zoals object_id, aanmaakdatum, laatste_ddl_tijd, enz. Het bevat de objecten die door alle gebruikers zijn aangemaakt. | SELECT * FROM all_objects waarbij objectnaam =' ' |
| GEBRUIKERSOBJECTEN | Geeft details over het pakket, zoals object_id, aanmaakdatum, laatste_ddl_tijd, enz. Het bevat de objecten die door de huidige gebruiker zijn aangemaakt. | SELECTEER * VAN user_objects waarbij object_name =' ' |
| ALLE_BRON | Geeft de bron van de objecten die door alle gebruikers zijn gemaakt. | SELECT * FROM all_source waarbij naam=' ' |
| GEBRUIKER_SOURCE | Geeft de bron van de objecten die door de huidige gebruiker zijn gemaakt. | SELECT * FROM user_source waarbij naam=' ' |
| ALLE_PROCEDURES | Geeft details over de subprogramma's, zoals object_id, overload-details, enz., die door alle gebruikers zijn aangemaakt. | SELECT * FROM all_procedures Where object_name=' ' |
| USER_PROCEDURES | Geeft details van het subprogramma, zoals object_id, overload details, etc., dat door de huidige gebruiker is gemaakt. | SELECT * FROM user_procedures WHERE object_name=' ' |
UTL_FILE โ Een overzicht
UTL_FILE is een apart hulpprogrammapakket dat wordt geleverd door Oracle Om speciale taken uit te voeren. Het wordt voornamelijk gebruikt voor het lezen en schrijven van besturingssysteembestanden vanuit PL/SQL-pakketten of -subprogramma's. Het heeft aparte functies voor het invoegen en ophalen van informatie uit bestanden. Het maakt ook lezen en schrijven in de eigen tekenset mogelijk.
De programmeur kan dit gebruiken om besturingssysteembestanden van elk type te schrijven, en het bestand wordt direct naar de databaseserver geschreven. De naam en het mappad worden tijdens het schrijven opgegeven.





