<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=PL%2FSQL</id>
	<title>PL/SQL - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=PL%2FSQL"/>
	<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=PL/SQL&amp;action=history"/>
	<updated>2026-05-21T19:57:29Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Wikipedia (Deutsch) – Lokale Kopie</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki-de.moshellshocker.dns64.de/index.php?title=PL/SQL&amp;diff=268746&amp;oldid=prev</id>
		<title>imported&gt;Invisigoth67: typo</title>
		<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=PL/SQL&amp;diff=268746&amp;oldid=prev"/>
		<updated>2026-03-07T07:39:15Z</updated>

		<summary type="html">&lt;p&gt;typo&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Infobox Programmiersprache&lt;br /&gt;
| Name = &lt;br /&gt;
| Logo = &lt;br /&gt;
| Beschreibung = Prozedurale Erweiterung von [[SQL]]&lt;br /&gt;
| Paradigma = prozedural&lt;br /&gt;
| Erscheinungsjahr = 1991&lt;br /&gt;
| Designer = &lt;br /&gt;
| Entwickler = [[Oracle]]&lt;br /&gt;
| AktuelleVersion = 11.1&lt;br /&gt;
| AktuelleVersionFreigabeDatum = 2009&lt;br /&gt;
| AktuelleVorabVersion = &lt;br /&gt;
| AktuelleVorabVersionFreigabeDatum = &lt;br /&gt;
| Typisierung = [[Starke Typisierung|stark]], [[Statische Typisierung|statisch]], [[Explizite Typisierung|explizit]]&lt;br /&gt;
| Implementierung = [[Oracle (Datenbanksystem)|Oracle-Datenbank]]&lt;br /&gt;
| Dialekte = &lt;br /&gt;
| Standardisierungen = &lt;br /&gt;
| Beeinflusst_von = [[Ada (Programmiersprache)|Ada]], [[SQL]]&lt;br /&gt;
| Beeinflusste = &lt;br /&gt;
| Betriebssystem = &lt;br /&gt;
| Lizenz = proprietär&lt;br /&gt;
| Website = [https://technet.oracle.com/ Oracle Technology Network]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;PL/SQL&amp;#039;&amp;#039;&amp;#039; (&amp;#039;&amp;#039;&amp;#039;P&amp;#039;&amp;#039;&amp;#039;rocedural &amp;#039;&amp;#039;&amp;#039;L&amp;#039;&amp;#039;&amp;#039;anguage/&amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;tructured &amp;#039;&amp;#039;&amp;#039;Q&amp;#039;&amp;#039;&amp;#039;uery &amp;#039;&amp;#039;&amp;#039;L&amp;#039;&amp;#039;&amp;#039;anguage) ist eine [[proprietär]]e [[Programmiersprache]] der Firma [[Oracle]].&lt;br /&gt;
&lt;br /&gt;
PL/SQL verbindet die [[Abfragesprache]] [[SQL]] mit einer [[Prozedurale Programmierung|prozeduralen]] Programmiersprache. Die Syntax ist stark an die Programmiersprache [[Ada (Programmiersprache)|Ada]] angelehnt.&lt;br /&gt;
&lt;br /&gt;
Unterstützt werden [[Variable (Programmierung)|Variablen]], [[Bedingte Anweisung und Verzweigung|Bedingungen]], [[Schleife (Programmierung)|Schleifen]] und [[Ausnahmebehandlung]]en. Ab Version 8 des [[Oracle (Datenbanksystem)|Oracle-RDBMS]] halten auch [[Objektorientierung|objektorientierte]] Merkmale Einzug.&lt;br /&gt;
&lt;br /&gt;
PL/SQL ist für das Arbeiten mit [[Oracle (Datenbanksystem)|Oracle-Datenbanken]] ausgelegt. Insbesondere kann man im Quelltext SQL-Befehle nach dem Oracle-Standard einfügen. Dabei werden die SQL-Anweisungen nicht als Zeichenketten erzeugt und an eine Datenbankschnittstelle übergeben (wie z.&amp;amp;nbsp;B. bei [[Open Database Connectivity|ODBC]], [[Java Database Connectivity|JDBC]] u.&amp;amp;nbsp;ä.), sondern fügen sich nahtlos in den Programmcode ein. Die Syntax kann damit bereits zum Zeitpunkt der Kompilierung überprüft werden.&lt;br /&gt;
&lt;br /&gt;
Die [[Gespeicherte Prozedur|prozedurale Erweiterung]] der SQL-Abfragesprache wird inzwischen auch von vielen anderen Datenbankherstellern implementiert. Daher wurde diese prozedurale SQL-Erweiterung inzwischen vom [[American National Standards Institute|ANSI-Gremium]] standardisiert.&lt;br /&gt;
&lt;br /&gt;
== Verwendung ==&lt;br /&gt;
* Man kann PL/SQL-Code wie SQL-Befehle über ein Datenbank-[[Front-End und Back-End|Frontend]] absetzen, der dann direkt abgearbeitet wird.&lt;br /&gt;
* Man kann einzelne Unterprogramme ([[Stored Procedure]]s) oder Bibliotheken mehrerer Unterprogramme (Stored Packages) als dauerhafte [[Datenbankobjekt]]e auf dem Datenbankserver speichern und damit die Funktionalität der Datenbank erweitern; jeder Benutzer der Datenbank kann diese Unterprogramme aufrufen und nutzen. Die Berechtigungen können für jedes einzelne PL/SQL-Paket an einzelne Benutzer oder Benutzergruppen (sogenannte „Rollen“) vergeben werden.&lt;br /&gt;
* Programmierung von [[Datenbanktrigger]]n&lt;br /&gt;
* Programmierung in diversen Tools ([[Oracle Forms|Oracle-Forms]], Oracle-Reports)&lt;br /&gt;
&lt;br /&gt;
PL/SQL-Programme können die Performance verbessern, wenn der Aufruf von einem Applikationsserver ausgeführt wird, der über eine langsame Netzwerkverbindung mit dem Datenbankserver verbunden ist. So muss in diesem Fall nur zu Beginn und am Ende der Ausführung eine Nachricht über das Netzwerk transportiert werden. Es gibt aber auch andere Möglichkeiten, bei einem langsamen Netzwerk die Performance einer Applikation zu verbessern. So kann z.&amp;amp;nbsp;B. die Oracle-Datenbank auch Java-Programme ausführen, die die Datenbank-Manipulationen vornehmen.&lt;br /&gt;
&lt;br /&gt;
== Grundlegender Aufbau ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;PL/SQL&amp;#039;&amp;#039;&amp;#039;-Programme bestehen aus Blöcken:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
  declare&lt;br /&gt;
      -- Deklarationsblock&lt;br /&gt;
  begin&lt;br /&gt;
     -- Ausführungsteil&lt;br /&gt;
  exception&lt;br /&gt;
     -- Ausnahmeverarbeitung&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  /* So kommentiert man&lt;br /&gt;
  mehrzeilig */&lt;br /&gt;
  --So kommentiert man einzeilig&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Variablendefinitionen ==&lt;br /&gt;
&lt;br /&gt;
Variablen werden im (optionalen) Deklarationsabschnitt definiert und optional initialisiert.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  declare&lt;br /&gt;
      zahl1 number(2);&lt;br /&gt;
      zahl2 number(2) := 17;&lt;br /&gt;
      text varchar(20) := &amp;#039;Das ist ein Text&amp;#039;;&lt;br /&gt;
  begin&lt;br /&gt;
      select hausnummer into zahl1 from Adressverzeichnis where name=&amp;#039;Meier&amp;#039; and rownum=1;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;:=&amp;lt;/code&amp;gt; ist der Zuweisungsoperator, mit dem man einer Variable einen Wert zuweist.&lt;br /&gt;
&lt;br /&gt;
=== Zahlenvariablen ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  variablenname number(P[,S]) := Wert;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um eine Zahlenvariable zu definieren, schreibt man zum Beispiel den Variablennamen, gefolgt vom Variablentyp &amp;lt;code&amp;gt;NUMBER&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Hinter diesem schreibt man in runden Klammern die Genauigkeit &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt; sowie optional ein Komma und die Anzahl an Nachkommastellen &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Genauigkeit entspricht in diesem Fall der Anzahl an Stellen, welche die Variable enthalten kann, und &amp;#039;&amp;#039;nicht&amp;#039;&amp;#039; dem Wertebereich.&lt;br /&gt;
&lt;br /&gt;
Auswahl weiterer Datentypen für Zahlenvariablen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;psql&amp;quot;&amp;gt;&lt;br /&gt;
  dec, decimal, double precision, integer, int, numeric, real, smallint, binary_integer, pls_integer&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Textvariablen ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  variablenname varchar2(L) := &amp;#039;Text&amp;#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um eine Textvariable zu definieren, schreibt man den Variablennamen gefolgt vom Variablentyp &amp;lt;code&amp;gt;VARCHAR2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Der angehängte Längenconstraint (Integer in Klammern) gibt die maximale Länge der Variablen in Bytes an (sofern die Length Semantic nicht auf CHAR gestellt ist).&lt;br /&gt;
&lt;br /&gt;
Auswahl weiterer Datentypen für Textvariablen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
CHAR, NCHAR, NVARCHAR2, CLOB, NCLOB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Datentypen LONG, LONG RAW und VARCHAR sind deprecated.&lt;br /&gt;
&lt;br /&gt;
=== Boolean ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  variablenname boolean := true;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kann &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;FALSE&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;NULL&amp;lt;/code&amp;gt; sein.&lt;br /&gt;
&lt;br /&gt;
=== Datum ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
   datum_1   date;&lt;br /&gt;
   datum_2   date := to_date(&amp;#039;31.12.2016&amp;#039;, &amp;#039;DD.MM.YYYY&amp;#039;);&lt;br /&gt;
   datum_3   date := to_date(&amp;#039;31.12.2016 23:59:59&amp;#039;, &amp;#039;DD.MM.YYYY HH24:MI:SS&amp;#039;);&lt;br /&gt;
   datum_4   date := date &amp;#039;2016-12-31 &amp;#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variablen vom Typ  &amp;lt;code&amp;gt;DATE&amp;lt;/code&amp;gt; enthalten Datum und Uhrzeit sekundengenau. Um eine Datumsvariable zu definieren, schreibt man den Variablennamen gefolgt vom Variablentyp &amp;lt;code&amp;gt;DATE&amp;lt;/code&amp;gt;.&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;TO_DATE&amp;lt;/code&amp;gt; wandelt den Text zwischen den ersten Hochkommas in ein Datum mit dem angegebenen Format zwischen den zweiten Hochkommas um, wobei die Angabe einer Uhrzeit optional und der Default 00:00:00 Uhr ist. Ein Datum ohne Uhrzeitanteil kann ohne Konvertierung von Zeichenkette zu Datum mit einem Datumsliteral definiert werden; man schreibt dann das Schlüsselwort  &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt;, gefolgt von Datum im Format &amp;#039;JJJJ-MM-TT&amp;#039;.&lt;br /&gt;
Um ein Datum in einen Text zu konvertieren, gibt es die Funktion &amp;lt;code&amp;gt;TO_CHAR(Datum)&amp;lt;/code&amp;gt;.&lt;br /&gt;
Neben dem Datentyp &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; gibt es noch den Datentyp &amp;lt;code&amp;gt;timestamp&amp;lt;/code&amp;gt;, der eine größere Präzision hat. Hierzu gibt es weitere Subtypen: &amp;lt;code&amp;gt;timestamp with time zone&amp;lt;/code&amp;gt; speichert die Zeitzone mit den Zeitinformationen, &amp;lt;code&amp;gt;timestamp with local timezone&amp;lt;/code&amp;gt; konvertiert jeweils von der Zeitzone der Session in die lokale Zeitzone des Datenbankservers.&lt;br /&gt;
&lt;br /&gt;
=== Datentyp über Spalte festlegen ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  Variablenname Tabellenname.Spaltenname%type;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Definiert eine Variable des Typs der angegebenen Spalte.&lt;br /&gt;
&lt;br /&gt;
=== Datentyp über Tabelle festlegen ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  Variablenname Tabellenname%rowtype;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Definiert eine Variable für einen Datensatz/Row des Typs der angegebenen Tabelle.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
    CURSOR cursor_name IS&lt;br /&gt;
        SELECT *&lt;br /&gt;
        FROM tabelle;&lt;br /&gt;
&lt;br /&gt;
    variable tabelle%rowtype;&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
    FOR i IN cursor_name LOOP&lt;br /&gt;
        variable := i;&lt;br /&gt;
        andere_variable := variable.SPALTENNAME;&lt;br /&gt;
    END LOOP;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Gültigkeitsbereich von Variablen ===&lt;br /&gt;
PL/SQL erlaubt es, Blöcke zu verschachteln. Variablen, die in äußeren Blöcken deklariert werden, sind in allen inneren Blöcken gültig. Variablen, die in inneren Blöcken deklariert werden, sind nicht in äußeren Blöcken gültig.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, wo Variablen deklariert werden, kann man zwischen zwei Arten unterscheiden.&lt;br /&gt;
* Lokale Variablen – Diese werden in einem inneren Block deklariert. Von außen kann nicht darauf zugegriffen werden.&lt;br /&gt;
* Globale Variablen – Diese werden in einem äußeren Block deklariert, und es kann von außen und innen darauf zugegriffen werden.&lt;br /&gt;
&lt;br /&gt;
In folgendem Beispiel werden zwei Variablen deklariert, und die Summe derer wird in einem inneren Block einer dritten Variable zugewiesen. Auf die Variablen &amp;lt;code&amp;gt;var_num1&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;var_num2&amp;lt;/code&amp;gt; kann von überall des Blocks aus zugegriffen werden. Auf die Variable &amp;lt;code&amp;gt;var_result&amp;lt;/code&amp;gt; dagegen, welche im inneren Block deklariert wurde, kann von außerhalb nicht zugegriffen werden.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
  var_num1 NUMBER;&lt;br /&gt;
  var_num2 NUMBER;&lt;br /&gt;
BEGIN&lt;br /&gt;
  var_num1 := 100;&lt;br /&gt;
  var_num2 := 200;&lt;br /&gt;
  DECLARE&lt;br /&gt;
    var_result NUMBER;&lt;br /&gt;
  BEGIN&lt;br /&gt;
    var_result := var_num1 + var_num2;&lt;br /&gt;
  END;&lt;br /&gt;
  /* Auf var_result kann hier nicht zugegriffen werden */&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Konstanten ===&lt;br /&gt;
Eine Konstante ist ein Wert in einem PL/SQL Block, der sich während des Programmablaufes nicht verändert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
  konstantenname CONSTANT NUMBER(3) := 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Wertzuweisung einer Konstante muss direkt bei der Deklaration erfolgen.&lt;br /&gt;
&lt;br /&gt;
== Benutzerdefinierte Datentypen ==&lt;br /&gt;
&lt;br /&gt;
Benutzerdefinierte Datentypen werden definiert mit Hilfe von:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;psql&amp;quot;&amp;gt;&lt;br /&gt;
  type datentyp is record(feld1 typ1 [:=xyz], feld2 typ2 [:=xyz], ..., feldn typn [:=xyz]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Beispiel:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  declare&lt;br /&gt;
    type t_adresse is record(&lt;br /&gt;
        hausname adresse.hausname%type,&lt;br /&gt;
        strasse adresse.strasse%type,&lt;br /&gt;
        hausnummer adresse.hausnummer%type,&lt;br /&gt;
        postleitzahl adresse.postleitzahl%type);&lt;br /&gt;
    v_adresse t_adresse;&lt;br /&gt;
  begin&lt;br /&gt;
    select hausname, strasse, hausnummer, postleitzahl into v_adresse from adresse where rownum = 1;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm definiert einen eigenen Datentyp mit Namen &amp;lt;code&amp;gt;t_adresse&amp;lt;/code&amp;gt;, welcher die Felder &amp;lt;code&amp;gt;hausname&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;strasse&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hausnummer&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;postleitzahl&amp;lt;/code&amp;gt; enthält.&lt;br /&gt;
&lt;br /&gt;
Mit diesem Datentyp wird eine Variable &amp;lt;code&amp;gt;v_adresse&amp;lt;/code&amp;gt; definiert, welche mit einem Datensatz aus der Tabelle &amp;lt;code&amp;gt;adresse&amp;lt;/code&amp;gt; gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
Mittels Punktnotation kann auf die Attribute zurückgegriffen werden&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  v_adresse.hausname := &amp;#039;Nollenburgerweg 115&amp;#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Schleifen ==&lt;br /&gt;
&lt;br /&gt;
Schleifen wiederholen die in ihrem Rumpf enthaltenen Anweisungen.&lt;br /&gt;
&lt;br /&gt;
=== Loop-Schleife (Basisschleife) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  loop&lt;br /&gt;
    ...&lt;br /&gt;
    exit when BEDINGUNG;&lt;br /&gt;
  end loop;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;code&amp;gt;loop&amp;lt;/code&amp;gt;-Schleife wiederholt die in ihrem Körper enthaltenen Anweisungen. Sie kann durch ein &amp;lt;code&amp;gt;exit when&amp;lt;/code&amp;gt; gefolgt von einer Abbruchbedingung beendet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Beachte:&amp;#039;&amp;#039;&amp;#039; Auch wenn die Bedingung für das &amp;lt;code&amp;gt;exit&amp;lt;/code&amp;gt; erfüllt ist, werden die Anweisungen, die im Schleifenkörper vor der &amp;lt;code&amp;gt;exit&amp;lt;/code&amp;gt;-Anweisung stehen, mindestens einmal ausgeführt.&lt;br /&gt;
&lt;br /&gt;
=== While-Schleife ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  while Bedingung loop&lt;br /&gt;
    ...&lt;br /&gt;
  end loop;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;code&amp;gt;while&amp;lt;/code&amp;gt;-Schleife wiederholt die in ihrem Körper enthaltenen Anweisungen, so lange die Bedingung in ihrem Kopf erfüllt ist.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Beachte:&amp;#039;&amp;#039;&amp;#039; Sollte die Bedingung im Kopf nicht erfüllt sein, werden die Anweisungen im Schleifenkörper nie ausgeführt.&lt;br /&gt;
&lt;br /&gt;
=== For-Schleife ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  for v_counter in 1..10 loop&lt;br /&gt;
    ...&lt;br /&gt;
  end loop;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;code&amp;gt;for&amp;lt;/code&amp;gt;-Schleife zählt eine Indexvariable von einem festgelegten Startwert bis zu einem festgelegten Endwert. Der kleinere Wert steht immer links, der größere immer rechts. Gibt man das Schlüsselwort &amp;lt;code&amp;gt;REVERSE&amp;lt;/code&amp;gt; nach dem &amp;lt;code&amp;gt;IN&amp;lt;/code&amp;gt; an, so wird vom größeren zum kleineren Wert heruntergezählt.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Beachte:&amp;#039;&amp;#039;&amp;#039; Auch hierbei muss der kleinere Wert links und der größere Wert rechts stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  begin&lt;br /&gt;
     for i in reverse 1 .. 5 loop&lt;br /&gt;
      dbms_output.put_line(to_char(i));&lt;br /&gt;
     end loop;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
  5&lt;br /&gt;
  4&lt;br /&gt;
  3&lt;br /&gt;
  2&lt;br /&gt;
  1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hinweis:&amp;#039;&amp;#039;&amp;#039; Wenn Sie beim Arbeiten mit SQL*Plus die erwarteten Zahlen 5 bis 1 nicht sehen, müssen Sie vorher die Ausgabe einschalten.&lt;br /&gt;
:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  set serveroutput on&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ab Oracle 21c gibt es sehr viele Erweiterungen zur &amp;lt;code&amp;gt;FOR&amp;lt;/code&amp;gt;-Schleife, die die Syntax enorm ausweiten. Die bisher (aus Ada übernommene) absichtlich stark eingeschränkte &amp;lt;code&amp;gt;FOR&amp;lt;/code&amp;gt;-Schleife kann damit umgangen werden.&amp;lt;ref&amp;gt;{{Internetquelle|url=https://oracle-base.com/articles/21c/for-loop-iteration-enhancements-21c|titel=FOR LOOP Iteration Enhancements in Oracle Database 21c|sprache=englisch|abruf=2016-03-06}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cursor-For-Schleife ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  for Record-Index in (Select Mitarbeiter_Nummer from Personaltabelle)&lt;br /&gt;
  loop&lt;br /&gt;
    ...&lt;br /&gt;
  end loop;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Cursor &amp;lt;code&amp;gt;for&amp;lt;/code&amp;gt;-Schleife öffnet automatisch den Cursor, liest die Datensätze ein und schließt den Cursor wieder.&lt;br /&gt;
&lt;br /&gt;
Alternativ dazu kann das &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;-Statement des Cursors auch vorher definiert werden, um es mehrfach zu verwenden bzw. um die Darstellung übersichtlicher zu gestalten (besonders bei längeren/komplexeren Abfragen von Vorteil).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  cursor cursor_mitarbeiter is&lt;br /&gt;
&lt;br /&gt;
  Select Mitarbeiter_Nummer from Personaltabelle;&lt;br /&gt;
  for Record-Index in cursor_mitarbeiter&lt;br /&gt;
&lt;br /&gt;
  loop&lt;br /&gt;
    ...&lt;br /&gt;
  end loop;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Zugriff auf die Mitarbeiter-Nummer innerhalb der &amp;lt;code&amp;gt;FOR&amp;lt;/code&amp;gt;-Schleife erfolgt mit dem Verbindungsoperator &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  Record-Index.Mitarbeiter_Nummer&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bedingungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von Bedingungen kann man auf verschiedene Situationen unterschiedlich reagieren.&lt;br /&gt;
&lt;br /&gt;
=== IF-THEN-ELSE ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  declare&lt;br /&gt;
    v_land welt.land%type;&lt;br /&gt;
  begin&lt;br /&gt;
    dbms_output.enable(20000);&lt;br /&gt;
    select land into v_land from welt&lt;br /&gt;
      where rownum = 1;&lt;br /&gt;
    if v_land = 39 then&lt;br /&gt;
        dbms_output.put_line(&amp;#039;Land ist 39&amp;#039;);&lt;br /&gt;
    elsif v_land = 49 then&lt;br /&gt;
        dbms_output.put_line(&amp;#039;Land ist 49&amp;#039;);&lt;br /&gt;
    else&lt;br /&gt;
        dbms_output.put_line(&amp;#039;Land unbekannt&amp;#039;);&lt;br /&gt;
    end if;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;if&amp;lt;/code&amp;gt; prüft, ob eine Bedingung erfüllt ist. Ist die Bedingung erfüllt, wird der Code zwischen &amp;lt;code&amp;gt;if&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;end if&amp;lt;/code&amp;gt; ausgeführt, ansonsten wird er übersprungen. Optional kann mit &amp;lt;code&amp;gt;elsif&amp;lt;/code&amp;gt; eine weitere Bedingung mit zugehörigem Code angegeben werden, der ausgeführt wird, falls diese Bedingung erfüllt ist. Zu guter Letzt kann man ein allgemeines &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; angeben, dessen Code ausgeführt wird, wenn keine der vorangegangenen Bedingungen erfüllt waren.&lt;br /&gt;
&lt;br /&gt;
Bedingungsstrukturen kann man zudem mittels des &amp;lt;code&amp;gt;CASE&amp;lt;/code&amp;gt;-Statements ausdrücken.&lt;br /&gt;
=== CASE-WHEN ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  DECLARE&lt;br /&gt;
    v_land welt.land%TYPE;&lt;br /&gt;
  BEGIN&lt;br /&gt;
    DBMS_OUTPUT.enable(20000);&lt;br /&gt;
    SELECT land INTO v_land FROM welt&lt;br /&gt;
      WHERE ROWNUM = 1;&lt;br /&gt;
    CASE WHEN v_land = 39 THEN DBMS_OUTPUT.put_line(&amp;#039;Land ist 39&amp;#039;);&lt;br /&gt;
         WHEN v_land = 49 THEN DBMS_OUTPUT.put_line(&amp;#039;Land ist 49&amp;#039;);&lt;br /&gt;
         WHEN v_land = 59 THEN DBMS_OUTPUT.put_line(&amp;#039;Land ist 59&amp;#039;);&lt;br /&gt;
                          ELSE DBMS_OUTPUT.put_line(&amp;#039;Land unbekannt&amp;#039;);&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vereinfachte Form für reine Wertelisten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  DECLARE&lt;br /&gt;
    v_land welt.land%TYPE;&lt;br /&gt;
  BEGIN&lt;br /&gt;
    DBMS_OUTPUT.enable(20000);&lt;br /&gt;
    SELECT land INTO v_land FROM welt&lt;br /&gt;
      WHERE ROWNUM = 1;&lt;br /&gt;
    CASE v_land&lt;br /&gt;
       WHEN 39 THEN DBMS_OUTPUT.put_line(&amp;#039;Land ist 39&amp;#039;);&lt;br /&gt;
       WHEN 49 THEN DBMS_OUTPUT.put_line(&amp;#039;Land ist 49&amp;#039;);&lt;br /&gt;
       WHEN 59 THEN DBMS_OUTPUT.put_line(&amp;#039;Land ist 59&amp;#039;);&lt;br /&gt;
               ELSE DBMS_OUTPUT.put_line(&amp;#039;Land unbekannt&amp;#039;);&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception-Handling ==&lt;br /&gt;
Es gibt zwei Arten von Exceptions:&lt;br /&gt;
* vordefinierte Exceptions und&lt;br /&gt;
* benutzerdefinierte Exceptions,&lt;br /&gt;
deren Handling analog ist.&lt;br /&gt;
&lt;br /&gt;
=== Vordefinierte Exceptions ===&lt;br /&gt;
Exceptions werden automatisch von PL/SQL ausgelöst, wenn Fehler bei der Arbeit mit Datenbankobjekten (Tabellen, Views, Packages u.&amp;amp;nbsp;ä.) oder Programmierfehler (bspw. Division durch Null) bei der Abarbeitung des Programms auftreten. Es gibt in PL/SQL 20 Exceptions mit vordefinierten Namen.&lt;br /&gt;
Jede Exception hat einen Fehlercode, der aus den Buchstaben &amp;#039;&amp;#039;&amp;#039;ORA-&amp;#039;&amp;#039;&amp;#039; und 5 Ziffern besteht.&lt;br /&gt;
Typische Exceptions dieser Art sind&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;no_data_found (ORA-01403)&amp;#039;&amp;#039;&amp;#039; – Eine SELECT-Anfrage liefert eine leere Datenmenge&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;too_many_rows (ORA-01422)&amp;#039;&amp;#039;&amp;#039; – Eine SELECT-Anfrage liefert eine Datenmenge mit mehr als einem Satz, an einer Stelle, an der nur ein einzelner Satz als Ergebnis der Anfrage erwartet wurde.&lt;br /&gt;
&lt;br /&gt;
=== Benutzerdefinierte Exceptions ===&lt;br /&gt;
Für die Behandlung logischer Programmfehler können eigene Exceptions in der Form&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;exception_name&amp;gt; exception;&lt;br /&gt;
  pragma exception_init(&amp;lt;exception_name&amp;gt;, -&amp;lt;exception_number&amp;gt;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
definiert und durch das Kommando&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  raise &amp;lt;exception_name&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ausgelöst werden.&lt;br /&gt;
&lt;br /&gt;
=== Exceptionblock ===&lt;br /&gt;
Der Exceptionblock dient dazu, alle Exceptions des dazugehörigen Ausführungsteiles abzufangen. Es besteht damit die Möglichkeit, nach einer Exception eine individuelle Fehlerbehandlung anzuschließen. Zum einen kann der Fehler nach dem Abfangen behandelt werden, danach kann im Programm weitergearbeitet werden; zum anderen kann die Exception an den umschließenden Block weitergereicht werden. Falls die Exception bis zum äußersten Block propagiert wird und dort keine entsprechende Fehlerbehandlung definiert wurde, führt dies zu einem unkontrollierten Abbruch des Programms.&lt;br /&gt;
&lt;br /&gt;
Der generelle Aufbau eines Exceptionblocks ist folgender:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;plpgsql&amp;quot;&amp;gt;&lt;br /&gt;
  begin&lt;br /&gt;
     -- Programmcode der eine Exception auslösen kann&lt;br /&gt;
     Ausführungsteil&lt;br /&gt;
     ...&lt;br /&gt;
  exception&lt;br /&gt;
  when &amp;lt;exception_name_1&amp;gt; then&lt;br /&gt;
     -- Exceptionbehandlung für die Exception &amp;lt;exception_name_1&amp;gt;&lt;br /&gt;
     Ausführungsteil&lt;br /&gt;
  ...&lt;br /&gt;
  when &amp;lt;exception_name_n&amp;gt; then&lt;br /&gt;
     -- Exceptionbehandlung für die Exception &amp;lt;exception_name_n&amp;gt;&lt;br /&gt;
     Ausführungsteil&lt;br /&gt;
  when others then&lt;br /&gt;
    -- Exceptionbehandlung für alle restlichen, nicht erwarteten Exceptions&lt;br /&gt;
     Ausführungsteil&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der &amp;lt;code&amp;gt;when others&amp;lt;/code&amp;gt;-Zweig ist optional; er fängt alle bis dahin im Exceptionblock nicht behandelten Exceptions ab. Fehlt dieser Zweig, werden unbehandelte Exceptions implizit an den umschließenden Block weitergereicht. Soll eine Exception explizit weitergereicht werden, muss der &amp;#039;&amp;#039;Ausführungsteil&amp;#039;&amp;#039; mit der Programmzeile &amp;lt;code&amp;gt;raise &amp;lt;exception_name&amp;gt;;&amp;lt;/code&amp;gt; enden.&lt;br /&gt;
&lt;br /&gt;
== Vergleich mit T-SQL ==&lt;br /&gt;
PL/SQL ist trotz oberflächlicher Ähnlichkeiten grundsätzlich anders als [[Transact-SQL]]. Bei der Übernahme von Quellcode handelt es sich daher in der Regel um eine nicht ganz einfache Arbeit. Nicht nur auf Grund der Unterschiede in den Feature-Sets der beiden Sprachen,&amp;lt;ref&amp;gt;{{Internetquelle |autor=Narayana Vyas Kondreddi |url=https://vyaskn.tripod.com/oracle_sql_server_differences_equivalents.htm |titel=Migrating from Oracle to SQL Server |werk=vyaskn.tripod.com |sprache=en |archiv-url=https://web.archive.org/web/20021202150959/http://vyaskn.tripod.com/oracle_sql_server_differences_equivalents.htm |archiv-datum=2002-12-02 |abruf=2014-10-27}}&amp;lt;/ref&amp;gt; sondern auch wegen der sehr deutlichen Unterschiede, wie Oracle und SQL Server mit der Steuerung der Parallelität und dem [[Lock]]ing umgehen. Es gibt jedoch Software-Tools, die die Übernahme erleichtern können, zum Beispiel Oracle Translation Scratch Editor&amp;lt;ref&amp;gt;{{Internetquelle |url=http://www.oracle.com/technetwork/database/migration/scratchlauncher-098387.html |titel=Oracle Scratchlauncher |werk=oracle.com |sprache=en |archiv-url=https://web.archive.org/web/20110418111650/http://www.oracle.com/technetwork/database/migration/scratchlauncher-098387.html |archiv-datum=2011-04-18 |abruf=2014-10-27}}&amp;lt;/ref&amp;gt; und SwisSQL.&amp;lt;ref&amp;gt;{{Internetquelle |url=http://www.swissql.com/ |titel=SwisSQL |werk=swissql.com |sprache=en |archiv-url=https://web.archive.org/web/20160407100425/http://www.swissql.com/ |archiv-datum=2016-04-07 |abruf=2014-10-27}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vergleichbare Möglichkeiten der Programmierung mit anderen Datenbank-Management-Systemen ==&lt;br /&gt;
* [[PL/pgSQL]] in der [[Open Source|Open-Source]]-[[Datenbank]] [[PostgreSQL]]&lt;br /&gt;
* [[SQL-PL]] für [[Adabas]]&lt;br /&gt;
* [[Db2#SQL PL|SQL PL]] für [[Db2]]&lt;br /&gt;
* [[Transact-SQL]] (TSQL) ist die entsprechende Programmiersprache für RDBMS von [[Sybase]] und [[Microsoft]]&lt;br /&gt;
* [[Stored Procedures]] in [[MySQL]] ab Version 5&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
{{Wikibooks|PL/SQL}}&lt;br /&gt;
* [https://download.oracle.com/docs/cd/B28359_01/server.111/b28286/toc.htm PL/SQL Dokumentation von Oracle] (englisch)&lt;br /&gt;
* [https://www.orafaq.com/wiki/PL/SQL Oracle FAQ’s: PL/SQL]&lt;br /&gt;
&lt;br /&gt;
== Einzelnachweise ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Normdaten|TYP=s|GND=4457669-9}}&lt;br /&gt;
&lt;br /&gt;
{{SORTIERUNG:Plsql}}&lt;br /&gt;
[[Kategorie:SQL]]&lt;br /&gt;
[[Kategorie:Oracle]]&lt;br /&gt;
[[Kategorie:Programmiersprache]]&lt;/div&gt;</summary>
		<author><name>imported&gt;Invisigoth67</name></author>
	</entry>
</feed>