Oracle PL/SQL-pakke: Type, Specifikation, Body [Eksempel]

⚡ Smart opsummering

PL/SQL-pakker grupperer relaterede procedurer, funktioner, variabler, cursorer og undtagelser i ét skemaobjekt med en specifikation og en brødtekst. Specifikationen deklarerer den offentlige grænseflade, mens brødteksten indeholder den private implementering, hvilket forbedrer modularitet og ydeevne.

  • 📦 Pakkedefinition: En pakke er en logisk gruppeping af relaterede underprogrammer og objekter, kompileret og lagret som et enkelt databaseobjekt.
  • ???? Pakkespecifikation: Deklarerer de offentlige variabler, cursorer, typer, undtagelser, procedurer og funktioner, der er tilgængelige uden for pakken.
  • 🧱 Pakkeindhold: Definerer alle elementer, der er deklareret i specifikationen, plus private elementer, der kun kan kaldes indefra pakken.
  • 🔁 Overbelastning: Flere underprogrammer kan dele ét navn, når deres parameternummer, parametertyper eller returtype er forskellige.
  • 🔗 Henvisning og afhængighed: Offentlige elementer kaldes som package_name.element_name, og kroppen forbliver afhængig af specifikationen.
  • 🤖 AI Assistance: AI-assistenter som f.eks. GitHub Copilot udarbejder pakkespecifikationer, brødtekster og overbelastede underprogrammer fra en kommentar.

Oracle Oversigt over PL/SQL-pakkespecifikationer og -struktur

Hvad er pakken i Oracle?

Oracle PL / SQL Pakken er en logisk gruppeping af relaterede underprogrammer (procedure/funktion) til et enkelt element. En pakke kompileres og gemmes som et databaseobjekt, der kan genbruges senere.

Komponenter af pakker

En PL/SQL-pakke har to komponenter.

  • Pakkespecifikation
  • Pakke Krop

Pakkespecifikation

Pakkespecifikationen består af en erklæring fra alle offentlige variabler, markører, objekter, procedurer, funktioner og undtagelser.

Nedenfor er et par karakteristika for pakkespecifikationen.

  • Elementerne, der er deklareret i specifikationen, kan tilgås uden for pakken. Sådanne elementer kaldes offentlige elementer.
  • Pakkespecifikationen er et selvstændigt element, hvilket betyder, at den kan eksistere alene uden en pakkebrødtekst.
  • Når der refereres til en pakke, oprettes en instans af pakken for den pågældende session.
  • Når instansen er oprettet til en session, er alle de pakkeelementer, der startes i den instans, gyldige indtil slutningen af ​​sessionen.

Syntaks

CREATE [OR REPLACE] PACKAGE <package_name> 
IS
<sub_program and public element declaration>
.
.
END <package name>

Ovenstående syntaks viser oprettelsen af ​​pakkespecifikationen.

Pakke Krop

Pakketeksten består af definitionen af ​​alle de elementer, der findes i pakkespecifikationen. Den kan også indeholde definitioner af elementer, der ikke er deklareret i specifikationen; disse elementer kaldes private elementer og kan kun kaldes indefra pakken.

Nedenfor er karakteristikaene for en pakkekrop.

  • Den skal indeholde definitioner for alle de underprogrammer/markører, der er blevet deklareret i specifikationen.
  • Den kan også have flere underprogrammer eller andre elementer, der ikke er deklareret i specifikationen. Disse kaldes private elementer.
  • Det er et afhængigt objekt, og det afhænger af pakkespecifikationen.
  • Pakkens indholdstilstand bliver 'Ugyldig', hver gang specifikationen kompileres. Derfor skal den kompileres igen hver gang efter kompileringen af ​​specifikationen.
  • De private elementer bør defineres først, før de bruges i pakkens krop.
  • Den første del af pakketeksten er den globale deklarationsdel. Denne omfatter variabler, cursorer og private elementer (fremadrettet deklaration), der er synlige for hele pakken.
  • Den sidste del af pakken er pakkeinitialiseringsdelen, der udføres én gang, hver gang en pakke refereres til for første gang i sessionen.

Syntaks:

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>

Ovenstående syntaks viser oprettelsen af ​​pakkekroppen.

Nu skal vi se på, hvordan man refererer til pakkeelementer i programmet.

Henvisende pakkeelementer

Når elementerne er deklareret og defineret i pakken, skal vi referere til elementerne for at bruge dem.

Alle pakkens offentlige elementer kan henvises til ved at kalde pakkenavnet efterfulgt af elementnavnet adskilt af et punktum, f.eks. . '.

Pakkens offentlige variabler kan også bruges på samme måde til at tildele og hente værdier fra dem, dvs. . '.

Opret pakke i PL/SQL

I PL/SQL oprettes der en ny instans for en pakke, når der henvises til eller kaldes en pakke i en session.

Oracle giver en facilitet til at initialisere pakkeelementer eller til at udføre enhver aktivitet på tidspunktet for oprettelsen af ​​denne instans gennem 'Pakkeinitialisering'.

Dette er intet andet end en udførelsesblok, der skrives i pakketeksten efter at alle pakkeelementerne er defineret. Denne blok udføres, hver gang en pakke refereres til for første gang i sessionen.

Skærmbilledet nedenfor viser, hvordan pakkeinitialiseringsblokken placeres i pakkens brødtekst, når en pakke oprettes.

Oprettelse af en PL/SQL-pakke med en pakkeinitialiseringsblok i pakketeksten

Syntaks

CREATE [OR REPLACE] PACKAGE BODY <package_name>
IS
<Private element definition>
<sub_program and public element definition>
.
BEGIN
<Package Initialization> 
END <package_name>

Ovenstående syntaks viser definitionen af ​​pakkeinitialisering i pakkens krop.

Fremsende erklæringer

Fremadrettet deklaration eller reference i pakken er intet andet end at deklarere de private elementer separat og definere dem i den senere del af pakkeindholdet.

Private elementer kan kun refereres til, hvis de allerede er deklareret i pakketeksten. Af denne grund bruges fremadrettet deklaration. Men det er ret usædvanligt at bruge det, fordi private elementer oftest deklareres og defineres i den første del af pakketeksten.

Fremsende erklæring er en mulighed, som OracleDet er ikke obligatorisk, og brugen af ​​det eller ej er op til programmørens krav.

Skærmbilledet nedenfor viser, hvordan et privat element fremaddeklareres og senere defineres i pakkens brødtekst.

Videregående erklæring af et privat element i en Oracle PL/SQL-pakkeindhold

Syntaks:

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>

Ovenstående syntaks viser fremad-deklaration. De private elementer er deklareret separat i den forreste del af pakken, og de er blevet defineret i den senere del.

Brug af markører i pakken

I modsætning til andre elementer skal man være forsigtig, når man bruger markører inde i pakken.

Hvis markøren er defineret i pakkespecifikationen eller i den globale del af pakkeindholdet, vil markøren, når den er åbnet, forblive der indtil slutningen af ​​sessionen.

Så man bør altid bruge markørattributten '%ISOPEN' til at verificere markørens tilstand, før man refererer til den.

Overloading (Overbelastning)

Overbelastning er konceptet med at have mange underprogrammer med samme navn. Disse underprogrammer adskiller sig fra hinanden ved antallet af parametre, typerne af parametre eller returtypen. Med andre ord betragtes underprogrammer med samme navn, men med et forskelligt antal parametre, forskellige typer parametre eller en forskellig returtype, som overbelastning.

Dette er nyttigt, når mange underprogrammer skal udføre den samme opgave, men måden at kalde dem på skal være forskellig. I dette tilfælde forbliver underprogrammets navn det samme for alle, og parametrene ændres i henhold til kaldsætningen.

Eksempel 1: I dette eksempel skal vi oprette en pakke til at hente og indstille værdierne for en medarbejders oplysninger i tabellen 'emp'. Funktionen get_record returnerer outputtet for posttypen for det givne medarbejdernummer, og proceduren set_record indsætter posttypen i tabellen 'emp'.

Trin 1) Oprettelse af pakkespecifikation

Skærmbilledet nedenfor viser guru99_get_set-pakkespecifikationen, der oprettes i Oracle.

Oprettelse af guru99_get_set pakkespecifikationen med set_record og get_record i 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 Forklaring

  • Code linje 1-5: Opretter pakkespecifikationen for guru99_get_set med én procedure og én funktion. Disse to er nu offentlige elementer i denne pakke.

Trin 2) Pakken indeholder en pakketekst, hvor de faktiske definitioner af alle procedurer og funktioner er defineret. I dette trin oprettes pakketeksten.

Skærmbilledet nedenfor viser definitionen af ​​guru99_get_set-pakkens indhold i Oracle.

Definering af guru99_get_set-pakkens brødtekst med set_record, get_record og initialiseringsblokken

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 Forklaring

  • Code linje 7: Oprettelse af pakkekroppen.
  • Code linje 9-16: Definition af elementet 'set_record', der er deklareret i specifikationen. Dette er det samme som at definere en standalone procedure i PL/SQL.
  • Code linje 17-24: Definering af elementet 'get_record'. Det er det samme som at definere en selvstændig funktion.
  • Code linje 25-26: Definition af pakkens initialiseringsdel.

Trin 3) Opretter en anonym blok for at indsætte og vise poster ved at henvise til den ovenfor oprettede pakke.

Skærmbilledet nedenfor viser den anonyme blok, der kalder pakken, sammen med dens output i Oracle.

Anonym blokkald guru99_get_set for at indsætte og vise en medarbejderpost med output

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 Forklaring:

  • Code linje 34-37: Udfylder dataene for posttypevariablen i en anonym blok for at kalde 'set_record'-elementet i pakken.
  • Code linje 38: Der er foretaget et kald til 'set_record' for guru99_get_set-pakken. Pakken er nu instantieret, og den vil forblive aktiv indtil slutningen af ​​sessionen. Pakkens initialiseringsdel udføres, da dette er det første kald til pakken, og posten indsættes i tabellen af ​​elementet 'set_record'.
  • Code linje 41: Kald af elementet 'get_record' for at vise detaljerne om den indsatte medarbejder. Pakken refereres til for anden gang under dette kald, men initialiseringsdelen udføres ikke igen, da pakken allerede er initialiseret i denne session.
  • Code linje 42-45: Udskrivning af medarbejderoplysninger.

Afhængighed i pakker

Da pakken er en logisk gruppeping af relaterede ting har det nogle afhængigheder. Følgende er de afhængigheder, der skal tages hånd om.

  • En specifikation er et selvstændigt objekt.
  • En pakkes indhold afhænger af specifikationen.
  • Pakkens indhold kan kompileres separat. Når specifikationen kompileres, skal indholdet kompileres igen, da det vil blive ugyldigt.
  • Underprogrammet i pakkebrødteksten, der er afhængigt af et privat element, bør først defineres efter deklarationen af ​​det private element.
  • De databaseobjekter, der refereres til i specifikationen og brødteksten, skal have gyldig status på tidspunktet for pakkekompileringen.

Pakkeinformation

Når pakken er oprettet, er pakkeoplysninger såsom pakkekilde, underprogramdetaljer og overbelastningsdetaljer tilgængelige i Oracle dataordbogstabeller.

Tabellen nedenfor viser dataordbogstabellen og de pakkeoplysninger, der er tilgængelige i hver tabel.

Tabelnavn Beskrivelse Query
ALLE_OBJEKTER Angiver detaljer om pakken som object_id, creation_date, last_ddl_time osv. Den indeholder de objekter, der er oprettet af alle brugere. VÆLG * FRA alle_objekter hvor objektnavn =' '
BRUGEROBJEKTER Angiver detaljer om pakken som object_id, creation_date, last_ddl_time osv. Den indeholder de objekter, der er oprettet af den aktuelle bruger. VÆLG * FRA bruger_objekter hvor objektnavn =' '
ALLE_KILDE Giver kilden til de objekter, der er oprettet af alle brugere. SELECT * FROM all_source hvor navn=' '
USER_SOURCE Giver kilden til de objekter, der er oprettet af den aktuelle bruger. VÆLG * FRA bruger_kilde hvor navn=' '
ALLE_PROCEDURER Giver underprogramdetaljer som objekt-id, overbelastningsdetaljer osv. oprettet af alle brugere. VÆLG * FRA alle_procedurer Hvor objektnavn=' '
USER_PROCEDURES Giver underprogrammet detaljer som object_id, overload detaljer osv. oprettet af den aktuelle bruger. VÆLG * FRA brugerprocedurer Hvor objektnavn=' '

UTL_FILE – En oversigt

UTL_FILE er en separat hjælpepakke leveret af Oracle til at udføre særlige opgaver. Det bruges primært til at læse og skrive operativsystemfiler fra PL/SQL-pakker eller underprogrammer. Det har separate funktioner til at indsætte information i og hente information fra filer. Det tillader også læsning og skrivning i det oprindelige tegnsæt.

Programmøren kan bruge dette til at skrive operativsystemfiler af enhver type, og filen vil blive skrevet direkte til databaseserveren. Navnet og mappestien er nævnt i skrivende stund.

Ofte Stillede Spørgsmål

Pakker tilbyder modularitet, informationsskjuling og nemmere applikationsdesign. Specifikationen eksponerer en offentlig grænseflade, mens kroppen skjuler implementeringen. Oracle indlæser en pakke i hukommelsen ved første kald, så senere underprogramkald undgår disk I/O og kører hurtigere.

En pakke grupperer mange relaterede underprogrammer og delte objekter under ét navn, der adskiller en offentlig specifikation fra en privat instans. En selvstændig procedure eller funktion er et enkelt, uafhængigt skemaobjekt uden den opdeling i grænsefladeimplementering.

Ja, hvis specifikationen kun deklarerer variabler, konstanter, typer eller undtagelser. En brødtekst bliver obligatorisk, når specifikationen deklarerer en procedure, funktion eller cursor, fordi brødteksten skal angive deres implementering. Ellers kan specifikationen stå alene.

Brug DROP PACKAGE til at fjerne både specifikationen og brødteksten, eller DROP PACKAGE BODY for kun at fjerne brødteksten. Genkompiler en ugyldig pakke med ALTER PACKAGE pakkenavn COMPILE, eller COMPILE BODY for kun at genopbygge brødteksten efter ændringer.

Attributten %ROWTYPE deklarerer en optage hvis felter matcher kolonnerne i emp-tabellen. Brug af emp%ROWTYPE holder parametrene get_record og set_record justeret med tabelstrukturen, så ændringer af kolonner kræver færre koderedigeringer.

Ja. Hver session, der refererer til en pakke, får sin egen instantiering og pakketilstand, som fortsætter i hele sessionens levetid. Rekompilering af brødteksten kasserer tilstanden og udløser ORA-04068-fejlen ved næste kald.

Ja. GitHub Copilot udarbejder pakkespecifikationer, matchende brødtekster og overbelastede underprogrammer fra en kommentar og foreslår %ROWTYPE-parametre. RevSe de genererede grænser, initialiseringsblokken og undtagelseshåndteringen før implementering.

AI-assistenter scanner en pakke for ugyldige tilstande, manglende brødtekstdefinitioner og afhængighedskæder, der bryder, når specifikationen ændres. Denne maskinlæringsgennemgang markerer tvetydige overbelastede underprogrammer og rekompileringsrisici, før pakken når produktion.

Opsummer dette indlæg med: