Oracle PL/SQL-csomag: Típus, Specifikáció, Törzs [Példa]

⚡ Okos összefoglaló

A PL/SQL csomagok a kapcsolódó eljárásokat, függvényeket, változókat, kurzorokat és kivételeket egyetlen sémaobjektumba csoportosítják, amely egy specifikációval és egy törzstel rendelkezik. A specifikáció deklarálja a nyilvános interfészt, míg a törzs a privát implementációt tartalmazza, javítva a modularitást és a teljesítményt.

  • 📦 Csomag definíciója: A csomag egy logikai csoportping kapcsolódó alprogramok és objektumok összessége, amelyeket egyetlen adatbázis-objektumként fordítanak le és tárolnak.
  • 📋 Csomag specifikációja: Deklarálja a csomagon kívülről elérhető nyilvános változókat, kurzorokat, típusokat, kivételeket, eljárásokat és függvényeket.
  • 🧱 Csomag törzse: Definiálja a specifikációban deklarált összes elemet, valamint a csak a csomagon belülről meghívható privát elemeket.
  • 🔁 Túlterhelés: Több alprogram is használhat egy nevet, ha paraméterszámuk, paramétertípusuk vagy visszatérési típusuk eltérő.
  • 🔗 Hivatkozás és függőség: A nyilvános elemeket package_name.element_name néven nevezzük, és a törzsük továbbra is a specifikációtól függ.
  • 🤖 AI segítség: Az olyan mesterséges intelligencia asszisztensek, mint a GitHub Copilot, egy megjegyzésből készítenek csomagspecifikációkat, törzseket és túlterhelt alprogramokat.

Oracle PL/SQL csomag specifikációja és törzsszerkezetének áttekintése

Miben van a csomag Oracle?

Oracle PL / SQL a csomag logikus csoportping a kapcsolódó alprogramok (eljárás/függvény) egyetlen elembe. Egy csomagot lefordítanak és adatbázis-objektumként tárolnak, amely később újra felhasználható.

A csomagok összetevői

Egy PL/SQL csomag két összetevőből áll.

  • Csomag specifikáció
  • Csomag test

Csomag specifikáció

A csomagspecifikáció az összes nyilvános elem deklarációjából áll. változók, kurzorok, objektumok, eljárások, függvények és kivételek.

Az alábbiakban a csomag specifikációjának néhány jellemzőjét ismertetjük.

  • A specifikációban deklarált elemek a csomagon kívülről is elérhetők. Az ilyen elemeket nyilvános elemeknek nevezzük.
  • A csomagspecifikáció egy önálló elem, ami azt jelenti, hogy létezhet önmagában, csomag törzse nélkül.
  • Amikor egy csomagra hivatkozunk, a csomag egy példánya létrejön az adott munkamenethez.
  • Miután a példány létrejött egy munkamenethez, az adott példányban kezdeményezett összes csomagelem a munkamenet végéig érvényes.

Szintaxis

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

A fenti szintaxis a csomagspecifikáció létrehozását mutatja.

Csomag test

A csomag törzse a csomagspecifikációban szereplő összes elem definíciójából áll. Tartalmazhat olyan elemek definícióit is, amelyek nincsenek deklarálva a specifikációban; ezeket az elemeket privát elemeknek nevezzük, és csak a csomagon belülről hívhatók meg.

Az alábbiakban a csomagtartó testének jellemzőit ismertetjük.

  • Tartalmaznia kell az összes, a specifikációban deklarált alprogram/kurzor definícióját.
  • Több alprogramot vagy más elemet is tartalmazhat, amelyek nincsenek deklarálva a specifikációban. Ezeket privát elemeknek nevezzük.
  • Ez egy függő objektum, és a csomag specifikációjától függ.
  • A csomag törzsének állapota a specifikáció lefordításakor „Érvénytelen” lesz. Ezért a specifikáció minden egyes fordítása után újra kell fordítani.
  • A privát elemeket először meg kell határozni, mielőtt a csomagtörzsben használnák őket.
  • A csomag törzsének első része a globális deklarációs rész. Ez magában foglalja a változókat, kurzorokat és privát elemeket (előre deklarált), amelyek a teljes csomag számára láthatók.
  • A csomag utolsó része a csomag inicializálása, amely egyszer fut le, valahányszor egy csomagra először hivatkoznak a munkamenetben.

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>

A fenti szintaxis a csomag törzsének létrehozását mutatja.

Most megnézzük, hogyan hivatkozhatunk a csomag elemeire a programban.

Hivatkozási csomagelemek

Miután az elemeket deklaráltuk és definiáltuk a csomagban, hivatkoznunk kell rájuk a használatukhoz.

A csomag összes nyilvános elemére hivatkozhatunk a csomag nevének meghívásával, amelyet az elem neve követ egy ponttal elválasztva, azaz ' . '.

A csomag nyilvános változói ugyanúgy használhatók értékek hozzárendelésére és belőlük való lekérésére, azaz ' . '.

Csomag létrehozása PL/SQL-ben

A PL/SQL-ben, valahányszor egy csomagra hivatkoznak vagy meghívódnak egy munkamenetben, egy új példány jön létre az adott csomaghoz.

Oracle lehetőséget biztosít a csomagelemek inicializálására vagy bármely tevékenység végrehajtására a példány létrehozása során a „Csomaginicializálás” segítségével.

Ez nem más, mint egy végrehajtási blokk, amelyet a csomag törzsébe írnak, miután definiálták az összes csomagelemet. Ez a blokk minden alkalommal végrehajtódik, amikor egy csomagra először hivatkoznak a munkamenetben.

Az alábbi képernyőkép azt mutatja, hogyan kerül a csomag inicializáló blokkja a csomag törzsébe egy csomag létrehozásakor.

PL/SQL csomag létrehozása csomag inicializálási blokkal a csomag törzsében

Szintaxis

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

A fenti szintaxis a csomag inicializálásának definícióját mutatja a csomagtörzsben.

Nyilatkozatok továbbítása

A csomagban az előre deklarálás vagy hivatkozás nem más, mint a privát elemek külön deklarálása és definiálása a csomag törzsének későbbi részében.

A privát elemekre csak akkor lehet hivatkozni, ha már deklarálva vannak a csomag törzsében. Emiatt az előre deklarálást használják. Használata azonban meglehetősen szokatlan, mivel a privát elemeket legtöbbször a csomag törzsének első részében deklarálják és definiálják.

A határidős nyilatkozat az általa biztosított lehetőség OracleNem kötelező, a használata vagy sem a programozó döntésétől függ.

Az alábbi képernyőkép azt mutatja be, hogyan lehet egy private elemet előre deklarálni és később a csomag törzsében definiálni.

Privát elem előre deklarálása egy Oracle PL/SQL csomag törzse

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>

A fenti szintaxis továbbítási deklarációt mutat. A privát elemeket a csomag elülső részében külön deklarálják, és a későbbi részben kerültek meghatározásra.

Kurzorok használata a csomagban

Más elemekkel ellentétben a csomagon belüli kurzorok használatakor óvatosnak kell lenni.

Ha a kurzor definiálva van a csomagspecifikációban vagy a csomag törzsének globális részében, akkor a kurzor a megnyitás után a munkamenet végéig megmarad.

Tehát mindig a '%ISOPEN' kurzorattribútumot kell használni a kurzor állapotának ellenőrzésére, mielőtt rá hivatkoznánk.

A túlterhelés

A túlterhelés azt a koncepciót jelenti, amikor sok azonos nevű alprogram létezik. Ezek az alprogramok a paraméterek számában, típusában vagy a visszatérési típusban különböznek egymástól. Más szóval, az azonos nevű, de eltérő számú paraméterrel, különböző típusú paraméterekkel vagy eltérő visszatérési típussal rendelkező alprogramokat túlterhelésnek tekintjük.

Ez akkor hasznos, ha sok alprogramnak kell ugyanazt a feladatot elvégeznie, de a hívásuk módja eltérő kell legyen. Ebben az esetben az alprogram neve minden alprogram esetében ugyanaz marad, és a paraméterek a hívó utasításnak megfelelően változnak.

Példa 1: Ebben a példában létrehozunk egy csomagot, amely lekéri és beállítja egy alkalmazott adatainak értékeit az 'emp' táblában. A get_record függvény visszaadja az adott alkalmazotti számhoz tartozó rekordtípus kimenetét, a set_record eljárás pedig beszúrja a rekordtípust az emp táblába.

1. lépés) Csomagspecifikáció létrehozása

Az alábbi képernyőkép a guru99_get_set csomagspecifikáció létrehozását mutatja a következőben: Oracle.

A guru99_get_set csomagspecifikáció létrehozása a set_record és get_record függvényekkel 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 Magyarázat

  • Code 1-5. sor: A guru99_get_set csomag specifikációjának létrehozása egy eljárással és egy függvénnyel. Ez a kettő most a csomag nyilvános eleme.

Step 2) A csomag tartalmaz egy csomagtörzset, ahol az összes eljárás és függvény tényleges definíciója definiálva van. Ebben a lépésben jön létre a csomagtörzs.

Az alábbi képernyőkép a guru99_get_set csomag törzsdefinícióját mutatja a következőben: Oracle.

A guru99_get_set csomag törzsének definiálása a set_record, get_record és az inicializáló blokk használatával

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 Magyarázat

  • Code 7. sor: A csomag törzsének létrehozása.
  • Code 9-16. sor: A specifikációban deklarált 'set_record' elem definiálása. Ez ugyanaz, mint egy önálló eljárás definiálása PL/SQL-ben.
  • Code 17-24. sor: A 'get_record' elem definiálása. Ugyanaz, mint egy önálló függvény definiálása.
  • Code 25-26. sor: A csomag inicializálási részének meghatározása.

Step 3) Névtelen blokk létrehozása a rekordok beszúrásához és megjelenítéséhez a fent létrehozott csomagra hivatkozva.

Az alábbi képernyőképen látható a csomagot hívó anonim blokk, valamint a kimenete. Oracle.

Névtelen blokk, amely meghívja a guru99_get_set-et egy alkalmazotti rekord beszúrásához és megjelenítéséhez kimenettel

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 Magyarázat:

  • Code 34-37. sor: A rekordtípus változó adatainak feltöltése egy anonim blokkban a csomag 'set_record' elemének meghívásához.
  • Code 38. sor: Hívás történt a guru99_get_set csomag 'set_record' függvényére. A csomag most példányosítva lett, és a munkamenet végéig megmarad. A csomag inicializálási része végrehajtódik, mivel ez a csomag első hívása, és a rekordot a 'set_record' elem szúrja be a táblázatba.
  • Code 41. sor: A 'get_record' elem meghívása a beszúrt alkalmazott adatainak megjelenítéséhez. A csomagra másodszor is hivatkoznak a hívás során, de az inicializálási rész nem kerül újra végrehajtásra, mivel a csomag már inicializálásra került ebben a munkamenetben.
  • Code 42-45. sor: Az alkalmazottak adatainak kinyomtatása.

Függőség a csomagokban

Mivel a csomag logikus csoportot alkotping a kapcsolódó dolgok közül néhánynak van néhány függősége. Az alábbiakban felsoroljuk azokat a függőségeket, amelyekkel foglalkozni kell.

  • A specifikáció egy önálló objektum.
  • A csomag törzse a specifikációtól függ.
  • A csomag törzse külön is lefordítható. A specifikáció lefordításakor a törzset újra kell fordítani, mivel az érvénytelenné válik.
  • A csomag törzsében található, privát elemtől függő alprogramot csak a privát elem deklarációja után szabad definiálni.
  • A specifikációban és a törzsben hivatkozott adatbázis-objektumoknak érvényes állapotban kell lenniük a csomag fordításakor.

Csomaginformáció

A csomag létrehozása után a csomaginformációk, például a csomag forrása, az alprogram részletei és a túlterhelés részletei elérhetők a Oracle adatszótár-táblázatok.

Az alábbi táblázat az adatszótár-táblázatot és az egyes táblázatokban elérhető csomaginformációkat tartalmazza.

Tábla neve Leírás Kérdés
MINDEN_OBJEKTUM Megadja a csomag részleteit, például az object_id-t, a creation_date-ot, a last_ddl_time-ot stb. Tartalmazza az összes felhasználó által létrehozott objektumokat. SELECT * FROM all_objects ahol objektum_neve =' '
FELHASZNÁLÓI_OBJEKTUMOK Megadja a csomag részleteit, például az object_id-t, a creation_date-ot, a last_ddl_time-ot stb. Tartalmazza az aktuális felhasználó által létrehozott objektumokat. SELECT * FROM user_objects ahol objektum_neve =' '
ALL_SOURCE Megadja az összes felhasználó által létrehozott objektumok forrását. SELECT * FROM all_source ahol név=' '
USER_SOURCE Megadja az aktuális felhasználó által létrehozott objektumok forrását. SELECT * FROM user_source ahol név=' '
ALL_PROCEDURES Megadja az összes felhasználó által létrehozott alprogram részleteit, például az objektumazonosítót, a túlterhelés részleteit stb. SELECT * FROM all_procedures Where object_name=' '
USER_PROCEDURES Megadja az aktuális felhasználó által létrehozott alprogram részleteit, például objektum_azonosítóját, túlterhelési részleteit stb. SELECT * FROM felhasználói_eljárások Where objektum_neve=' '

UTL_FILE – Áttekintés

Az UTL_FILE egy különálló segédprogramcsomag, amelyet a Oracle speciális feladatok végrehajtására. Főként operációs rendszerfájlok PL/SQL csomagokból vagy alprogramokból történő olvasására és írására használják. Külön függvényekkel rendelkezik az információk fájlokba való bevitelére és onnan történő kiolvasására. Lehetővé teszi a natív karakterkészletben történő olvasást és írást is.

A programozó ezt bármilyen típusú operációsrendszer-fájl írására használhatja, és a fájl közvetlenül az adatbázis-kiszolgálóra kerül. A név és a könyvtár elérési útja az írás során kerül említésre.

GYIK

A csomagok modularitást, információrejtést és egyszerűbb alkalmazástervezést biztosítanak. A specifikáció egy nyilvános interfészt tesz elérhetővé, míg a törzs elrejti a megvalósítást. Oracle Az első híváskor betölti a csomagot a memóriába, így a későbbi alprogramhívások elkerülik a lemez I/O-t és gyorsabban futnak.

Egy csomag számos kapcsolódó elemet csoportosít alprogramok és megosztott objektumok egyetlen név alatt, elkülönítve a nyilvános specifikációt a privát objektumtól. Egy önálló eljárás vagy függvény egyetlen, független sémaobjektum, amely nem tartalmazza az interfész-implementáció felosztást.

Igen, ha a specifikáció csak változókat, konstansokat, típusokat vagy kivételeket deklarál. A törzs akkor válik kötelezővé, ha a specifikáció eljárást, függvényt vagy kurzort deklarál, mivel a törzsnek kell biztosítania ezek implementációját. Egyébként a specifikáció önállóan is állhat fenn.

A DROP PACKAGE paranccsal távolítsd el mind a specifikációt, mind a törzset, vagy a DROP PACKAGE BODY paranccsal csak a törzset. Érvénytelen csomagot az ALTER PACKAGE package_name COMPILE paranccsal fordíts újra, vagy a COMPILE BODY paranccsal csak a törzset építsd újra a módosítások után.

A %ROWTYPE attribútum deklarál egy rekord amelynek mezői megegyeznek az emp tábla oszlopaival. Az emp%ROWTYPE használata a get_record és set_record paramétereket a tábla szerkezetéhez igazítja, így az oszlopmódosítások kevesebb kódszerkesztést igényelnek.

Igen. Minden csomagra hivatkozó munkamenet saját példányosítást és csomagállapotot kap, amely az adott munkamenet teljes élettartama alatt megőrződik. A törzs újrafordítása elveti az állapotot, és a következő híváskor az ORA-04068 hibát idézi elő.

Igen. GitHub másodpilóta Csomagspecifikációkat, illeszkedő törzseket és túlterhelt alprogramokat készít egy megjegyzésből, és %ROWTYPE paramétereket javasol. RevTelepítés előtt tekintse meg a létrehozott határokat, az inicializálási blokkot és a kivételkezelést.

A mesterséges intelligencia asszisztensek érvénytelen állapotokat, hiányzó törzsdefiníciókat és a specifikáció változásakor megszakadó függőségi láncokat keresnek a csomagban. Ez a gépi tanulással végzett áttekintés a csomag éles környezetbe kerülése előtt jelzi a kétértelmű, túlterhelt alprogramokat és az újrafordítási kockázatokat.

Foglald össze ezt a bejegyzést a következőképpen: