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

โšก Smart oppsummering

PL/SQL-pakker grupperer relaterte prosedyrer, funksjoner, variabler, markรธrer og unntak i ett skjemaobjekt med en spesifikasjon og en brรธdtekst. Spesifikasjonen deklarerer det offentlige grensesnittet, mens brรธdteksten inneholder den private implementeringen, noe som forbedrer modularitet og ytelse.

  • ๐Ÿ“ฆ Pakkedefinisjon: En pakke er en logisk gruppeping av relaterte underprogrammer og objekter, kompilert og lagret som et enkelt databaseobjekt.
  • ???? Pakkespesifikasjon: Deklarerer de offentlige variablene, markรธrene, typene, unntakene, prosedyrene og funksjonene som er tilgjengelige utenfra pakken.
  • ๐Ÿงฑ Pakkeinnhold: Definerer alle elementer som er deklarert i spesifikasjonen, pluss private elementer som bare kan kalles fra innsiden av pakken.
  • ๐Ÿ” Overbelastning: Flere underprogrammer kan dele ett navn nรฅr parameternummeret, parametertypene eller returtypene deres er forskjellige.
  • ๐Ÿ”— Henvisning og avhengighet: Offentlige elementer kalles pakkenavn.elementnavn, og kroppen forblir avhengig av spesifikasjonen.
  • ๐Ÿค– AI-hjelp: AI-assistenter som GitHub Copilot utkaster pakkespesifikasjoner, brรธdtekster og overbelastede underprogrammer fra en kommentar.

Oracle Oversikt over PL/SQL-pakkespesifikasjon og kroppsstruktur

Hva er pakken i Oracle?

Oracle PL / SQL pakken er en logisk gruppeping av relaterte underprogrammer (prosedyre/funksjon) til et enkelt element. En pakke kompileres og lagres som et databaseobjekt som kan brukes pรฅ nytt senere.

Komponenter av pakker

En PL/SQL-pakke har to komponenter.

  • Pakkespesifikasjon
  • Pakkekropp

Pakkespesifikasjon

Pakkespesifikasjonen bestรฅr av en erklรฆring fra alle offentlige variabler, pekere, objekter, prosedyrer, funksjoner og unntak.

Nedenfor er noen kjennetegn ved pakkespesifikasjonen.

  • Elementene som er deklarert i spesifikasjonen kan nรฅs utenfra pakken. Slike elementer er kjent som offentlige elementer.
  • Pakkespesifikasjonen er et frittstรฅende element, som betyr at den kan eksistere alene uten en pakkeinnhold.
  • Hver gang det refereres til en pakke, opprettes en instans av pakken for den bestemte รธkten.
  • Etter at forekomsten er opprettet for en รธkt, er alle pakkeelementene som er initiert i den forekomsten gyldige til slutten av รธkten.

syntax

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

Syntaksen ovenfor viser opprettelsen av pakkespesifikasjonen.

Pakkekropp

Pakketeksten bestรฅr av definisjonen av alle elementene som finnes i pakkespesifikasjonen. Den kan ogsรฅ ha definisjoner av elementer som ikke er deklarert i spesifikasjonen; disse elementene kalles private elementer og kan bare kalles fra innsiden av pakken.

Nedenfor er egenskapene til en pakkekropp.

  • Den bรธr inneholde definisjoner for alle underprogrammene/markรธrene som er deklarert i spesifikasjonen.
  • Den kan ogsรฅ ha flere underprogrammer eller andre elementer som ikke er deklarert i spesifikasjonen. Disse kalles private elementer.
  • Det er et avhengig objekt, og det avhenger av pakkespesifikasjonen.
  • Pakkeinnholdet fรฅr statusen ยซUgyldigยป hver gang spesifikasjonen kompileres. Derfor mรฅ den kompileres pรฅ nytt hver gang etter at spesifikasjonen er kompilert.
  • De private elementene bรธr defineres fรธrst fรธr de brukes i pakketeksten.
  • Den fรธrste delen av pakkeinnholdet er den globale deklarasjonsdelen. Denne inkluderer variabler, markรธrer og private elementer (fremoverdeklarasjon) som er synlige for hele pakken.
  • Den siste delen av pakken er pakkeinitialiseringsdelen som kjรธres รฉn gang hver gang en pakke refereres til for fรธrste gang i รธkten.

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>

Syntaksen ovenfor viser opprettelsen av pakkeinnholdet.

Nรฅ skal vi se hvordan vi refererer til pakkeelementer i programmet.

Refererende pakkeelementer

Nรฅr elementene er deklarert og definert i pakken, mรฅ vi referere til elementene for รฅ bruke dem.

Alle de offentlige elementene i pakken kan refereres til ved รฅ kalle pakkenavnet etterfulgt av elementnavnet atskilt med et punktum, f.eks. . '.

De offentlige variablene i pakken kan ogsรฅ brukes pรฅ samme mรฅte til รฅ tilordne og hente verdier fra dem, f.eks. . '.

Opprett pakke i PL/SQL

I PL/SQL, hver gang en pakke refereres til eller kalles i en sesjon, opprettes en ny instans for den pakken.

Oracle gir en mulighet for รฅ initialisere pakkeelementer eller รฅ utfรธre en hvilken som helst aktivitet pรฅ tidspunktet for opprettelse av denne forekomsten gjennom "Pakkeinitialisering".

Dette er ikke annet enn en utfรธrelsesblokk som skrives i pakketeksten etter at alle pakkeelementene er definert. Denne blokken vil bli utfรธrt hver gang en pakke refereres til for fรธrste gang i รธkten.

Skjermbildet nedenfor viser hvordan pakkeinitialiseringsblokken plasseres inne i pakkekroppen nรฅr en pakke opprettes.

Opprette en PL/SQL-pakke med en pakkeinitialiseringsblokk i pakkeinnholdet

syntax

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

Syntaksen ovenfor viser definisjonen av pakkeinitialisering i pakketeksten.

Videresend erklรฆringer

Fremoverdeklarasjon eller referanse i pakken er ikke annet enn รฅ deklarere de private elementene separat og definere dem i den senere delen av pakkeinnholdet.

Private elementer kan bare refereres til hvis de allerede er deklarert i pakkeinnholdet. Av denne grunn brukes fremoverdeklarasjon. Men det er ganske uvanlig รฅ bruke det, fordi private elementer som oftest deklareres og defineres i den fรธrste delen av pakkeinnholdet.

Forward erklรฆring er et alternativ gitt av OracleDet er ikke obligatorisk, og bruk av det eller ikke er opp til programmererens behov.

Skjermbildet nedenfor viser hvordan et privat element deklareres videre og senere defineres i pakkeinnholdet.

Videresending av et privat element i en Oracle PL/SQL-pakkeinnhold

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>

Ovennevnte syntaks viser fremad deklarasjon. De private elementene er deklarert separat i den fremre delen av pakken, og de er definert i den senere delen.

Markรธrbruk i pakken

I motsetning til andre elementer, mรฅ man vรฆre forsiktig nรฅr man bruker markรธrer inne i pakken.

Hvis markรธren er definert i pakkespesifikasjonen eller i den globale delen av pakkeinnholdet, vil markรธren, nรฅr den er รฅpnet, forbli der til slutten av รธkten.

Sรฅ man bรธr alltid bruke markรธrattributtet '%ISOPEN' for รฅ bekrefte markรธrens tilstand fรธr man refererer til den.

Overbelastning

Overbelastning er konseptet med รฅ ha mange underprogrammer med samme navn. Disse underprogrammene skiller seg fra hverandre ved antall parametere, parametertyper eller returtype. Med andre ord, underprogrammer med samme navn, men med et annet antall parametere, forskjellige typer parametere eller en annen returtype, regnes som overbelastning.

Dette er nyttig nรฅr mange underprogrammer mรฅ utfรธre den samme oppgaven, men mรฅten de kaller hvert av dem pรฅ bรธr vรฆre forskjellig. I dette tilfellet holdes underprogramnavnet det samme for alle, og parameterne endres i henhold til kallingssetningen.

Eksempel 1: I dette eksemplet skal vi opprette en pakke for รฅ hente og angi verdiene for en ansatts informasjon i ยซempยป-tabellen. Funksjonen get_record returnerer posttypeutdataene for det gitte ansattnummeret, og prosedyren set_record setter inn posttypeposten i emp-tabellen.

Trinn 1) Oppretting av pakkespesifikasjon

Skjermbildet nedenfor viser pakkespesifikasjonen guru99_get_set som opprettes i Oracle.

Oppretter pakkespesifikasjonen guru99_get_set 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;
/

Utgang:

Package created

Code Forklaring

  • Code linje 1โ€“5: Oppretter pakkespesifikasjonen for guru99_get_set med รฉn prosedyre og รฉn funksjon. Disse to er nรฅ offentlige elementer i denne pakken.

Trinn 2) Pakken inneholder en pakketekst, hvor de faktiske definisjonene av alle prosedyrer og funksjoner er definert. I dette trinnet opprettes pakketeksten.

Skjermbildet nedenfor viser definisjonen av guru99_get_set-pakkens innhold i Oracle.

Definere pakketeksten guru99_get_set 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;
/

Utgang:

Package body created

Code Forklaring

  • Code linje 7: Oppretter pakkekroppen.
  • Code linje 9โ€“16: Definere elementet 'set_record' som er deklarert i spesifikasjonen. Dette er det samme som รฅ definere en frittstรฅende prosedyre i PL/SQL.
  • Code linje 17โ€“24: Definere elementet 'get_record'. Det er det samme som รฅ definere en frittstรฅende funksjon.
  • Code linje 25โ€“26: Definere pakkens initialiseringsdel.

Trinn 3) Oppretter en anonym blokk for รฅ sette inn og vise postene ved รฅ referere til pakken som er opprettet ovenfor.

Skjermbildet nedenfor viser den anonyme blokken som kaller pakken, sammen med utdataene i Oracle.

Anonym blokkering som kaller guru99_get_set for รฅ sette inn og vise en ansattpost med utdata

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;
/

Utgang:

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: Fyller ut dataene for posttypevariabelen i en anonym blokk for รฅ kalle 'set_record'-elementet i pakken.
  • Code linje 38: Et kall har blitt gjort til 'set_record' for guru99_get_set-pakken. Nรฅ er pakken instansiert, og den vil vare til slutten av รธkten. Pakkens initialiseringsdel utfรธres siden dette er det fรธrste kallet til pakken, og posten settes inn i tabellen av 'set_record'-elementet.
  • Code linje 41: Kaller elementet 'get_record' for รฅ vise detaljene til den innsatte ansatte. Pakken refereres til for andre gang i lรธpet av dette kallet, men initialiseringsdelen utfรธres ikke pรฅ nytt, ettersom pakken allerede er initialisert i denne รธkten.
  • Code linje 42โ€“45: Skriver ut de ansattes detaljer.

Avhengighet i pakker

Siden pakken er en logisk gruppeping av relaterte ting, har den noen avhengigheter. Fรธlgende er avhengighetene som skal tas hรฅnd om.

  • En spesifikasjon er et frittstรฅende objekt.
  • En pakkes innhold er avhengig av spesifikasjonen.
  • Pakketeksten kan kompileres separat. Nรฅr spesifikasjonen kompileres, mรฅ teksten kompileres pรฅ nytt, da den vil bli ugyldig.
  • Delprogrammet i pakkeinnholdet som er avhengig av et privat element, bรธr bare defineres etter deklarasjonen av det private elementet.
  • Databaseobjektene som det refereres til i spesifikasjonen og brรธdteksten, mรฅ ha gyldig status pรฅ tidspunktet for pakkekompileringen.

Pakkeinformasjon

Nรฅr pakken er opprettet, er pakkeinformasjonen, som pakkekilden, detaljer om underprogrammet og overbelastningsdetaljer, tilgjengelig i Oracle dataordboktabeller.

Tabellen nedenfor viser dataordlistetabellen og pakkeinformasjonen som er tilgjengelig i hver tabell.

Tabellnavn Tekniske beskrivelser Query
ALLE_OBJEKTER Gir detaljene om pakken som object_id, creation_date, last_ddl_time osv. Den inneholder objektene som er opprettet av alle brukere. VELG * FRA alle_objekter der objektnavn =' '
BRUKEROBJEKTER Gir detaljene om pakken som object_id, creation_date, last_ddl_time osv. Den inneholder objektene som er opprettet av den nรฅvรฆrende brukeren. SELECT * FROM user_objects der objektnavn =' '
ALL_SOURCE Gir kilden til objektene som er opprettet av alle brukere. SELECT * FROM all_source hvor navn=' '
USER_SOURCE Gir kilden til objektene opprettet av gjeldende bruker. SELECT * FROM user_source hvor navn=' '
ALLE_PROSEDYRER Gir detaljer om underprogrammet, som objekt-id, overbelastningsdetaljer osv., opprettet av alle brukere. VELG * FRA alle_prosedyrer Der objektnavn=' '
USER_PROCEDURES Gir underprogrammet detaljer som object_id, overload detaljer, etc. opprettet av gjeldende bruker. VELG * FRA brukerprosedyrer Der objektnavn=' '

UTL_FILE โ€“ En oversikt

UTL_FILE er en separat verktรธypakke levert av Oracle รฅ utfรธre spesielle oppgaver. Den brukes hovedsakelig til รฅ lese og skrive operativsystemfiler fra PL/SQL-pakker eller underprogrammer. Den har separate funksjoner for รฅ legge inn informasjon i og hente informasjon fra filer. Den tillater ogsรฅ lesing og skriving i det opprinnelige tegnsettet.

Programmereren kan bruke dette til รฅ skrive operativsystemfiler av alle typer, og filen vil bli skrevet direkte til databaseserveren. Navnet og katalogstien er nevnt i skrivende stund.

Spรธrsmรฅl og svar

Pakker gir modularitet, skjuling av informasjon og enklere applikasjonsdesign. Spesifikasjonen eksponerer et offentlig grensesnitt mens hoveddelen skjuler implementeringen. Oracle laster en pakke inn i minnet ved fรธrste kall, slik at senere underprogramkall unngรฅr disk I/O og kjรธrer raskere.

En pakke grupperer mange relaterte underprogrammer og delte objekter under ett navn, som skiller en offentlig spesifikasjon fra en privat enhet. En frittstรฅende prosedyre eller funksjon er et enkelt, uavhengig skjemaobjekt uten den grensesnittimplementeringsdelingen.

Ja, hvis spesifikasjonen bare deklarerer variabler, konstanter, typer eller unntak. En brรธdtekst blir obligatorisk nรฅr spesifikasjonen deklarerer en prosedyre, funksjon eller markรธr, fordi brรธdteksten mรฅ levere implementeringen av disse. Ellers kan spesifikasjonen stรฅ alene.

Bruk DROP PACKAGE for รฅ fjerne bรฅde spesifikasjonen og brรธdteksten, eller DROP PACKAGE BODY for รฅ fjerne bare brรธdteksten. Kompiler en ugyldig pakke pรฅ nytt med ALTER PACKAGE pakkenavn COMPILE, eller COMPILE BODY for รฅ gjenoppbygge bare brรธdteksten etter endringer.

%ROWTYPE-attributtet deklarerer en rekord hvis felt samsvarer med kolonnene i emp-tabellen. Bruk av emp%ROWTYPE holder parameterne get_record og set_record justert med tabellstrukturen, slik at kolonneendringer krever fรฆrre koderedigeringer.

Ja. Hver รธkt som refererer til en pakke fรฅr sin egen instansiering og pakketilstand, som varer sรฅ lenge รธkten varer. Rekompilering av brรธdteksten forkaster tilstanden og genererer ORA-04068-feilen ved neste kall.

Ja. GitHub Copilot lager utkast til pakkespesifikasjoner, samsvarende brรธdtekster og overbelastede underprogrammer fra en kommentar, og foreslรฅr %ROWTYPE-parametere. RevVis de genererte grensene, initialiseringsblokken og unntakshรฅndteringen fรธr distribusjon.

AI-assistenter skanner en pakke for ugyldige tilstander, manglende brรธdtekstdefinisjoner og avhengighetskjeder som brytes nรฅr spesifikasjonen endres. Denne maskinlรฆringsgjennomgangen flagger tvetydige overbelastede delprogrammer og rekompileringsrisikoer fรธr pakken nรฅr produksjon.

Oppsummer dette innlegget med: