Oracle PL/SQL-Paket: Typ, Spezifikation, Hauptteil [Beispiel]

โšก Intelligente Zusammenfassung

PL/SQL-Pakete gruppieren zusammengehรถrige Prozeduren, Funktionen, Variablen, Cursor und Ausnahmen in einem Schemaobjekt mit einer Spezifikation und einem Rumpf. Die Spezifikation deklariert die รถffentliche Schnittstelle, wรคhrend der Rumpf die private Implementierung enthรคlt. Dies verbessert Modularitรคt und Leistung.

  • ๐Ÿ“ฆ Paketdefinition: Ein Paket ist eine logische Gruppierungping von zusammengehรถrigen Unterprogrammen und Objekten, die als ein einzelnes Datenbankobjekt kompiliert und gespeichert werden.
  • ๐Ÿ“‹ Paketspezifikation: Deklariert die รถffentlichen Variablen, Cursor, Typen, Ausnahmen, Prozeduren und Funktionen, auf die von auรŸerhalb des Pakets zugegriffen werden kann.
  • ๐Ÿงฑ Verpackungsinhalt: Definiert jedes in der Spezifikation deklarierte Element sowie private Elemente, die nur innerhalb des Pakets aufgerufen werden kรถnnen.
  • ๐Ÿ” รœberlastung: Mehrere Unterprogramme kรถnnen denselben Namen tragen, wenn sich ihre Parameteranzahl, Parametertypen oder ihr Rรผckgabetyp unterscheiden.
  • ๐Ÿ”— รœberweisung und Abhรคngigkeit: ร–ffentliche Elemente werden als Paketname.Elementname aufgerufen, der Inhalt bleibt von der Spezifikation abhรคngig.
  • ๐Ÿค– KI-Unterstรผtzung: KI-Assistenten wie GitHub Copilot erstellen aus einem Kommentar Entwรผrfe fรผr Paketspezifikationen, -kรถrper und รผberladene Unterprogramme.

Oracle PL/SQL-Paketspezifikation und รœbersicht รผber die Struktur

Was ist im Paket enthalten? Oracle?

Oracle PL / SQL Paket ist eine logische Gruppeping von verwandten Unterprogramme (Prozedur/Funktion) in ein einzelnes Element. Ein Paket wird kompiliert und als Datenbankobjekt gespeichert, das spรคter wiederverwendet werden kann.

Komponenten von Paketen

Ein PL/SQL-Paket besteht aus zwei Komponenten.

  • Paketspezifikation
  • Paketkรถrper

Paketspezifikation

Die Paketspezifikation besteht aus einer Deklaration aller รถffentlichen Variablen, CursorObjekte, Prozeduren, Funktionen und Ausnahmen.

Nachfolgend sind einige Merkmale der Paketspezifikation aufgefรผhrt.

  • Auf die in der Spezifikation deklarierten Elemente kann von auรŸerhalb des Pakets zugegriffen werden. Solche Elemente werden als รถffentliche Elemente bezeichnet.
  • Die Paketspezifikation ist ein eigenstรคndiges Element, das heiรŸt, sie kann auch ohne Paketrumpf existieren.
  • Immer wenn auf ein Paket verwiesen wird, wird fรผr diese spezielle Sitzung eine Instanz des Pakets erstellt.
  • Nachdem die Instanz fรผr eine Sitzung erstellt wurde, sind alle in dieser Instanz initiierten Paketelemente bis zum Ende der Sitzung gรผltig.

Syntax

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

Die obige Syntax zeigt die Erstellung der Paketspezifikation.

Paketkรถrper

Der Paketrumpf besteht aus der Definition aller Elemente, die in der Paketspezifikation vorhanden sind. Er kann auch Definitionen von Elementen enthalten, die nicht in der Spezifikation deklariert sind; diese Elemente werden als private Elemente bezeichnet und kรถnnen nur innerhalb des Pakets aufgerufen werden.

Nachfolgend sind die Merkmale eines Gehรคuses aufgefรผhrt.

  • Es sollte Definitionen fรผr alle Unterprogramme/Cursor enthalten, die in der Spezifikation deklariert wurden.
  • Es kann auch weitere Unterprogramme oder andere Elemente enthalten, die nicht in der Spezifikation deklariert sind. Diese werden als private Elemente bezeichnet.
  • Es handelt sich um ein abhรคngiges Objekt, das von der Paketspezifikation abhรคngt.
  • Der Status des Paketrumpfs รคndert sich bei jeder Kompilierung der Spezifikation in โ€žUngรผltigโ€œ. Daher muss die Spezifikation nach jeder Kompilierung neu kompiliert werden.
  • Die privaten Elemente sollten zuerst definiert werden, bevor sie im Paketkรถrper verwendet werden.
  • Der erste Teil des Paketrumpfs ist der globale Deklarationsteil. Dieser umfasst Variablen, Cursor und private Elemente (Vorwรคrtsdeklaration), die fรผr das gesamte Paket sichtbar sind.
  • Der letzte Teil des Pakets ist die Paketinitialisierung, die einmalig ausgefรผhrt wird, wenn in der Sitzung zum ersten Mal auf ein Paket verwiesen wird.

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>

Die obige Syntax zeigt die Erstellung des Paketrumpfs.

Nun sehen wir uns an, wie man im Programm auf Paketelemente zugreift.

Verweisende Paketelemente

Sobald die Elemente im Paket deklariert und definiert sind, mรผssen wir auf die Elemente verweisen, um sie verwenden zu kรถnnen.

Alle รถffentlichen Elemente des Pakets kรถnnen durch Aufruf des Paketnamens gefolgt vom Elementnamen, getrennt durch einen Punkt, referenziert werden, z. B. ' Die '.

Die รถffentlichen Variablen des Pakets kรถnnen auf die gleiche Weise verwendet werden, um ihnen Werte zuzuweisen und von ihnen abzurufen, d.h. ' Die '.

Erstellen Sie ein Paket in PL/SQL

In PL/SQL wird immer dann eine neue Instanz eines Pakets erstellt, wenn in einer Sitzung auf dieses Paket verwiesen oder es aufgerufen wird.

Oracle Bietet eine Mรถglichkeit, Paketelemente zu initialisieren oder beliebige Aktivitรคten zum Zeitpunkt der Instanzerstellung durch โ€žPaketinitialisierungโ€œ auszufรผhren.

Es handelt sich hierbei lediglich um einen Ausfรผhrungsblock, der nach der Definition aller Paketelemente im Paketrumpf eingefรผgt wird. Dieser Block wird immer dann ausgefรผhrt, wenn in der Sitzung zum ersten Mal auf ein Paket verwiesen wird.

Der folgende Screenshot zeigt, wie der Paketinitialisierungsblock beim Erstellen eines Pakets im Paketkรถrper platziert wird.

Erstellen eines PL/SQL-Pakets mit einem Paketinitialisierungsblock im Paketrumpf

Syntax

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

Die obige Syntax zeigt die Definition der Paketinitialisierung im Pakethauptteil.

Weiterleitungserklรคrungen

Eine Vorwรคrtsdeklaration oder -referenz im Paket bedeutet nichts anderes, als die privaten Elemente separat zu deklarieren und sie im spรคteren Teil des Paketrumpfs zu definieren.

Auf private Elemente kann nur zugegriffen werden, wenn sie bereits im Paketrumpf deklariert wurden. Aus diesem Grund wird die Vorwรคrtsdeklaration verwendet. Ihre Verwendung ist jedoch eher ungewรถhnlich, da private Elemente meist im ersten Teil des Paketrumpfs deklariert und definiert werden.

Die Vorwรคrtsdeklaration ist eine Option von OracleEs ist nicht obligatorisch, und ob es verwendet wird oder nicht, hรคngt von den Anforderungen des Programmierers ab.

Der folgende Screenshot zeigt, wie ein privates Element vorab deklariert und spรคter im Paketrumpf definiert wird.

Vorwรคrtsdeklaration eines privaten Elements in einem Oracle PL/SQL-Paketrumpf

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>

Die obige Syntax zeigt eine Vorwรคrtsdeklaration. Die privaten Elemente werden im Vorwรคrtsteil des Pakets separat deklariert und im spรคteren Teil definiert.

Verwendung von Cursorn im Paket

Im Gegensatz zu anderen Elementen muss man bei der Verwendung von Cursorn innerhalb des Pakets vorsichtig sein.

Wenn der Cursor in der Paketspezifikation oder im globalen Teil des Paketrumpfs definiert ist, bleibt der Cursor nach dem ร–ffnen bis zum Ende der Sitzung bestehen.

Daher sollte man vor dem Zugriff auf den Cursor immer das Cursorattribut '%ISOPEN' verwenden, um dessen Zustand zu รผberprรผfen.

รœberlastung

รœberladung bezeichnet das Konzept, mehrere Unterprogramme mit demselben Namen zu haben. Diese Unterprogramme unterscheiden sich durch die Anzahl oder die Typen der Parameter oder den Rรผckgabetyp. Anders ausgedrรผckt: Unterprogramme mit demselben Namen, aber unterschiedlicher Anzahl oder unterschiedlichen Typen von Parametern oder unterschiedlichem Rรผckgabetyp gelten als รผberladen.

Dies ist nรผtzlich, wenn mehrere Unterprogramme dieselbe Aufgabe ausfรผhren mรผssen, die Aufrufweise jedoch jeweils unterschiedlich sein soll. In diesem Fall bleibt der Name des Unterprogramms fรผr alle gleich, wรคhrend die Parameter entsprechend der aufrufenden Anweisung angepasst werden.

Beispiel 1: In diesem Beispiel erstellen wir ein Paket, um die Werte der Mitarbeiterinformationen in der Tabelle โ€žempโ€œ abzurufen und festzulegen. Die Funktion โ€žget_recordโ€œ gibt den Datensatztyp fรผr die angegebene Mitarbeiternummer zurรผck, und die Prozedur โ€žset_recordโ€œ fรผgt den Datensatztyp in die Tabelle โ€žempโ€œ ein.

Schritt 1) โ€‹โ€‹Erstellung der Verpackungsspezifikation

Der folgende Screenshot zeigt, wie die Paketspezifikation guru99_get_set erstellt wird. Oracle.

Erstellung der guru99_get_set-Paketspezifikation mit set_record und get_record in 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;
/

Ausgang:

Package created

Code Erlรคuterung

  • Code Zeile 1-5: Die Paketspezifikation fรผr guru99_get_set mit einer Prozedur und einer Funktion wurde erstellt. Diese beiden sind nun รถffentliche Elemente dieses Pakets.

Schritt 2) Das Paket enthรคlt einen Paketrumpf, in dem die eigentlichen Definitionen aller Prozeduren und Funktionen festgelegt sind. In diesem Schritt wird der Paketrumpf erstellt.

Der folgende Screenshot zeigt die Body-Definition des Pakets guru99_get_set in Oracle.

Definition des Paketrumpfs von guru99_get_set mit set_record, get_record und dem Initialisierungsblock

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

Ausgang:

Package body created

Code Erlรคuterung

  • Code Zeile 7: Erstellung des Paketrumpfs.
  • Code Zeile 9-16: Das in der Spezifikation deklarierte Element โ€žset_recordโ€œ wird definiert. Dies entspricht der Definition einer eigenstรคndigen Prozedur in PL/SQL.
  • Code Zeile 17-24: Das Element 'get_record' wird definiert. Dies entspricht der Definition einer eigenstรคndigen Funktion.
  • Code Zeile 25-26: Definieren des Paketinitialisierungsteils.

Schritt 3) Es wird ein anonymer Block erstellt, um die Datensรคtze durch Verweis auf das oben erstellte Paket einzufรผgen und anzuzeigen.

Der folgende Screenshot zeigt den anonymen Block, der das Paket aufruft, zusammen mit seiner Ausgabe in Oracle.

Anonymer Block ruft guru99_get_set auf, um einen Mitarbeiterdatensatz einzufรผgen und anzuzeigen mit Ausgabe

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

Ausgang:

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 Erlรคuterung:

  • Code Zeile 34-37: Die Daten fรผr die Variable โ€žrecord typeโ€œ werden in einem anonymen Block eingefรผgt, um das Element โ€žset_recordโ€œ des Pakets aufzurufen.
  • Code Zeile 38: Es wurde die Methode โ€žset_recordโ€œ des Pakets โ€žguru99_get_setโ€œ aufgerufen. Das Paket ist nun instanziiert und bleibt bis zum Ende der Sitzung aktiv. Da dies der erste Aufruf des Pakets ist, wird die Paketinitialisierung ausgefรผhrt, und der Datensatz wird durch das Element โ€žset_recordโ€œ in die Tabelle eingefรผgt.
  • Code Zeile 41: Das Element โ€žget_recordโ€œ wird aufgerufen, um die Details des eingefรผgten Mitarbeiters anzuzeigen. Das Paket wird wรคhrend dieses Aufrufs zum zweiten Mal referenziert, die Initialisierung wird jedoch nicht erneut ausgefรผhrt, da das Paket in dieser Sitzung bereits initialisiert wurde.
  • Code Zeile 42-45: Ausdrucken der Mitarbeiterdaten.

Abhรคngigkeit in Paketen

Da das Paket eine logische Gruppe istping Es bestehen einige Abhรคngigkeiten zwischen verwandten Dingen. Im Folgenden sind die Abhรคngigkeiten aufgefรผhrt, die berรผcksichtigt werden mรผssen.

  • Eine Spezifikation ist ein eigenstรคndiges Objekt.
  • Der Inhalt eines Pakets ist von der Spezifikation abhรคngig.
  • Der Paketrumpf kann separat kompiliert werden. Jedes Mal, wenn die Spezifikation kompiliert wird, muss der Rumpf neu kompiliert werden, da er sonst ungรผltig wird.
  • Das Unterprogramm im Paketrumpf, das von einem privaten Element abhรคngt, sollte erst nach der Deklaration des privaten Elements definiert werden.
  • Die in der Spezifikation und im Hauptteil referenzierten Datenbankobjekte mรผssen zum Zeitpunkt der Paketkompilierung einen gรผltigen Status aufweisen.

Paketinformationen

Sobald das Paket erstellt ist, sind die Paketinformationen wie Paketquelle, Unterprogrammdetails und รœberladungsdetails in der Oracle Datenwรถrterbuchtabellen.

Die folgende Tabelle enthรคlt die Datenwรถrterbuchtabelle und die in jeder Tabelle verfรผgbaren Paketinformationen.

Tabellenname Beschreibung Abfrage
ALLE_OBJEKTE Enthรคlt Details zum Paket wie object_id, creation_date, last_ddl_time usw. Es enthรคlt die von allen Benutzern erstellten Objekte. SELECT * FROM all_objects where object_name =' '
USER_OBJECTS Gibt die Details des Pakets an, wie object_id, creation_date, last_ddl_time usw. Es enthรคlt die vom aktuellen Benutzer erstellten Objekte. SELECT * FROM user_objects where object_name =' '
ALL_SOURCE Gibt die Quelle der von allen Benutzern erstellten Objekte an. SELECT * FROM all_source where name=' '
USER_SOURCE Gibt die Quelle der vom aktuellen Benutzer erstellten Objekte an. SELECT * FROM user_source where name=' '
ALLE_PROZEDUREN Zeigt Details zu den Unterprogrammen an, wie z. B. object_id, รœberladungsdetails usw., die von allen Benutzern erstellt wurden. SELECT * FROM all_procedures WHERE object_name=' '
USER_PROCEDURES Gibt die vom aktuellen Benutzer erstellten Unterprogrammdetails wie Objekt-ID, รœberladungsdetails usw. an. SELECT * FROM user_procedures WHERE object_name=' '

UTL_FILE โ€“ Ein รœberblick

UTL_FILE ist ein separates Hilfsprogramm, das von Oracle Es dient der Ausfรผhrung spezieller Aufgaben. Hauptsรคchlich wird es zum Lesen und Schreiben von Betriebssystemdateien aus PL/SQL-Paketen oder Unterprogrammen verwendet. Es verfรผgt รผber separate Funktionen zum Einfรผgen und Auslesen von Informationen aus Dateien. AuรŸerdem ermรถglicht es das Lesen und Schreiben im nativen Zeichensatz.

Der Programmierer kann damit Betriebssystemdateien beliebigen Typs erstellen, die direkt auf dem Datenbankserver gespeichert werden. Name und Verzeichnispfad werden beim Erstellen der Datei angegeben.

Hรคufig gestellte Fragen

Pakete bieten Modularitรคt, Informationskapselung und vereinfachen die Anwendungsentwicklung. Die Spezifikation stellt eine รถffentliche Schnittstelle bereit, wรคhrend der Rumpf die Implementierung verbirgt. Oracle Beim ersten Aufruf wird ein Paket in den Speicher geladen, sodass nachfolgende Unterprogrammaufrufe Festplattenzugriffe vermeiden und schneller ausgefรผhrt werden.

Ein Paket fasst viele verwandte Produkte zusammen Unterprogramme Gemeinsame Objekte werden unter einem Namen gefรผhrt, wodurch eine รถffentliche Spezifikation von einem privaten Teil getrennt wird. Eine eigenstรคndige Prozedur oder Funktion ist ein einzelnes, unabhรคngiges Schemaobjekt ohne diese Trennung zwischen Schnittstelle und Implementierung.

Ja, wenn die Spezifikation nur Variablen, Konstanten, Typen oder Ausnahmen deklariert. Ein Rumpf wird obligatorisch, sobald die Spezifikation eine Prozedur, Funktion oder einen Cursor deklariert, da dieser deren Implementierung bereitstellen muss. Andernfalls kann die Spezifikation eigenstรคndig sein.

Verwenden Sie DROP PACKAGE, um sowohl die Spezifikation als auch den Body zu entfernen, oder DROP PACKAGE BODY, um nur den Body zu entfernen. Kompilieren Sie ein ungรผltiges Paket mit ALTER PACKAGE Paketname COMPILE neu, oder mit COMPILE BODY, um nach ร„nderungen nur den Body neu zu erstellen.

Das %ROWTYPE-Attribut deklariert einen Rekord deren Felder den Spalten der Tabelle โ€žempโ€œ entsprechen. Durch die Verwendung von โ€žemp%ROWTYPEโ€œ bleiben die Parameter โ€žget_recordโ€œ und โ€žset_recordโ€œ an die Tabellenstruktur angepasst, sodass Spaltenรคnderungen weniger Codeanpassungen erfordern.

Ja. Jede Sitzung, die auf ein Paket verweist, erhรคlt eine eigene Instanziierung und einen eigenen Paketstatus, der fรผr die Dauer der Sitzung erhalten bleibt. Durch das erneute Kompilieren des Sitzungsrumpfs wird der Status verworfen und beim nรคchsten Aufruf der Fehler ORA-04068 ausgelรถst.

Ja. GitHub-Copilot Erstellt aus einem Kommentar Entwรผrfe fรผr Paketspezifikationen, passende Rumpfe und รผberladene Unterprogramme und schlรคgt %ROWTYPE-Parameter vor. RevPrรผfen Sie vor der Bereitstellung die generierten Grenzen, den Initialisierungsblock und die Ausnahmebehandlung.

KI-Assistenten scannen ein Paket auf ungรผltige Zustรคnde, fehlende Definitionen und Abhรคngigkeitsketten, die bei Spezifikationsรคnderungen brechen. Diese maschinelle Lernprรผfung kennzeichnet mehrdeutige, รผberladene Unterprogramme und Risiken einer Neukompilierung, bevor das Paket in Produktion geht.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: