<html><head>
<link rel="stylesheet" href="josh.css"></head><body bgcolor="#FFFFFF">
<div id="Beschreibung">
			<table width="100%" cellspacing="0" cellpadding="0" border="0">
				<tr><td valign="top" class="name">Befehlsreferenz</td><td valign="top" nowrap class="compatibility">&#160; </td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr><td>Dieses Kapitel ist das Kernst&uuml;ck von <span class="emphasis">SQL in a Nutshell</span>; hier werden in alphabetischer Reihenfolge alle SQL-Befehle detailliert und anhand von Beispielen erl&auml;utert. Bei jedem Befehl und jeder Funktion ist in einer Haupttabelle angegeben, inwieweit die in diesem Buch behandelten vier SQL-Dialekte (SQL Server, MySQL, Oracle und PostgreSQL) diese(n) unterst&uuml;tzen: "Unterst&uuml;tzt", "Unterst&uuml;tzt, mit Variationen", "Unterst&uuml;tzt, mit Einschr&auml;nkungen" und "Nicht unterst&uuml;tzt". Nach einer kurzen Beschreibung des SQL99-Standards werden die Datenbanksysteme der einzelnen Hersteller kurz aber gr&uuml;ndlich mit Beispielen und Beispielcode erkl&auml;rt.</td>
				</tr>
			</table>
		</div>
<div id="ALTER PROCEDURE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">ALTER PROCEDURE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p><span class="emphasis"></span>Mit der Anweisung <span class="emphasis">ALTER PROCEDURE</span>
 kann eine bestehende gespeicherte Prozedur ver&auml;ndert werden. Welche &Auml;nderungen in welchem Umfang vorgenommen werden k&ouml;nnen, h&auml;ngt vom Hersteller ab.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In SQL Server wird mit dieser Anweisung eine zuvor mit <span class="emphasis">CREATE PROCEDURE</span> erzeugte Prozedur ge&auml;ndert, wobei dies jedoch weder Auswirkungen auf Zugriffsrechte noch auf abh&auml;ngige gespeicherte Prozeduren oder Trigger hat.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle wird mit diesem Befehl einfach eine gespeicherte PL/SQL-Prozedur neu kompiliert, wobei sich der Code aber nicht &auml;ndern l&auml;sst. Dazu m&uuml;ssen Sie in Oracle den Befehl <span class="emphasis">CREATE OR REPLACE PROCEDURE</span> verwenden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER PROCEDURE procedure_name {CASCADE | RESTRICT}
[LANGUAGE | PARAMETER STYLE | &lt;SQL data access&gt; | &lt;null clause behavior&gt; | DYNAMIC RESULT SETS | NAME]
[parameter datatype [,...n]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wie unter <span class="emphasis">CREATE PROCEDURE</span> beschrieben, k&ouml;nnen <span class="emphasis">LANGUAGE</span>, <span class="emphasis">PARAMETER STYLE</span>, die SQL-Datenzugriffsmethode (d.&#160;h. <span class="emphasis">NO SQL</span>, <span class="emphasis">CONTAINS SQL</span> usw.), das Null-Klausel-Verhalten (d.&#160;h. <span class="emphasis">CALL ON NULL INPUT</span>), <span class="emphasis">DYNAMIC RESULT SET</span> und der Prozedur-<span class="emphasis">NAME</span> allesamt ge&auml;ndert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der Befehl <span class="emphasis">ALTER PROCEDURE</span> kann auch verwendet werden, um die Anzahl oder den Typ der Eingabeparameter zu &auml;ndern.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER PROC[EDURE] procedure_name [;number]
[ {@parameter datatype } [VARYING] [= default] [OUTPUT] ][,...n]
[WITH { RECOMPILE | ENCRYPTION  | RECOMPILE , ENCRYPTION } ]
[FOR REPLICATION]
AS
T-SQL Block</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In SQL Server k&ouml;nnen mit diesem Befehl alle bestehenden Parameter f&uuml;r zuvor erzeugte gespeicherte Prozeduren ge&auml;ndert werden. Eigentlich ist dieser Befehl nur eine Kurzversion der Anweisung <span class="emphasis">DROP PROCEDURE</span>, gefolgt von einer modifizierten <span class="emphasis">CREATE PROCEDURE</span>-Anweisung. Die Zugriffsrechte der gespeicherten Prozedur m&uuml;ssen so nicht neu eingerichtet werden. Eine vollst&auml;ndige Beschreibung der Syntax finden Sie unter <span class="emphasis">CREATE PROCEDURE</span>. Dieser Befehl kann in SQL Server vom Eigent&uuml;mer der gespeicherten Prozedur sowie von einem Mitglied der festen Datenbankrollen <span class="emphasis">db_owner</span> und <span class="emphasis">ddl_admin</span> ausgef&uuml;hrt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER PROCEDURE [user.]<span class="replaceable">procedure_name</span> COMPILE [DEBUG];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle muss der Name der Prozedur oder des Package, das kompiliert werden soll, angegeben werden. Das Schl&uuml;sselwort <span class="emphasis">COMPILE</span> ist ebenfalls erforderlich. Mit der Option <span class="emphasis">COMPILE [DEBUG]</span> wird der PL/SQL-Code neu generiert. Dieser Befehl kann nur vom Eigent&uuml;mer der gespeicherten Prozedur oder von Personen mit dem Privileg <span class="emphasis">ALTER ANY PROCEDURE</span> ausgef&uuml;hrt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In diesem Beispiel f&uuml;r Microsoft SQL Server wird eine Prozedur mit dem Namen <span class="emphasis">get_next_br</span> erzeugt, die einen eindeutigen CHAR(22)-Ausgabestring generiert. Dann soll diese Prozedur dahingehend ge&auml;ndert werden, dass ein eindeutiger INT-Wert zur&uuml;ckgegeben wird. Dazu wird <span class="emphasis">ALTER PROCEDURE</span> verwendet:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>-- Gespeicherte Prozedur in Microsoft SQL Server
CREATE PROCEDURE get_next_nbr
   @next_nbr CHAR(22) OUTPUT
AS
BEGIN
  DECLARE @random_nbr INT
  SELECT @random_nbr = RAND(  ) * 1000000

SELECT @next_nbr =
  RIGHT('000000' + CAST(ROUND(RAND(@random_nbr)*1000000,0))AS CHAR(6), 6) +
  RIGHT('0000' + CAST(DATEPART (yy, GETDATE(  ) ) AS CHAR(4)), 2) +
  RIGHT('000'  + CAST(DATEPART (dy, GETDATE(  ) ) AS CHAR(3)), 3) +
  RIGHT('00'   + CAST(DATEPART (hh, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (mi, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (ss, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('000'  + CAST(DATEPART (ms, GETDATE(  ) ) AS CHAR(3)), 3)
END
GO

ALTER PROCEDURE get_next_nbr
   @next_nbr INT OUTPUT
AS
BEGIN
  DECLARE @convert_to_nbr CHAR(22)
  DECLARE @random_nbr INT
  SELECT  @random_nbr = RAND(  ) * 1000000

SELECT @convert_to_nbr =
  RIGHT('000000' + CAST(ROUND(RAND(@random_nbr)*1000000,0))AS CHAR(6), 6) +
  RIGHT('0000' + CAST(DATEPART (yy, GETDATE(  ) ) AS CHAR(4)), 2) +
  RIGHT('000'  + CAST(DATEPART (dy, GETDATE(  ) ) AS CHAR(3)), 3) +
  RIGHT('00'   + CAST(DATEPART (hh, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (mi, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (ss, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('000'  + CAST(DATEPART (ms, GETDATE(  ) ) AS CHAR(3)), 3)

SELECT @next_nbr = CAST(@convert_to_nbr AS INT)

END
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="ALTER TABLE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">ALTER TABLE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">ALTER TABLE </span>

kann eine bestehende Tabelle ge&auml;ndert werden, ohne dass diese gel&ouml;scht wird oder dies Auswirkungen auf die Zugriffsrechte der Tabelle hat. Damit k&ouml;nnen auf einfache Art und Weise inkrementelle &Auml;nderungen an einer Tabelle durchgef&uuml;hrt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Sowohl Oracle als auch Microsoft SQL Server unterst&uuml;tzen diesen Befehl mit einer Reihe von Variationen, die die verschiedenen Methoden zur Zuweisung physischer Dateien abdecken.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Einschr&auml;nkungen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER TABLE table_name
[ADD [COLUMN] column_name datatype attributes]
| [ALTER [COLUMN] column_name SET DEFAULT default_value]
| [ALTER [COLUMN] column_name DROP DEFAULT]
| [ALTER [COLUMN] column_name ADD SCOPE table_name
| [ALTER [COLUMN] column_name DROP SCOPE {RESTRICT | CASCADE}]
| [DROP [COLUMN] column_name {RESTRICT | CASCADE}]
| [ADD table_constraint_name]
| [DROP CONSTRAINT table_constraint_name {RESTRICT | CASCADE}]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der SQL99-Anweisung <span class="emphasis">ALTER TABLE</span> k&ouml;nnen viele n&uuml;tzliche &Auml;nderungen an einer bestehenden Tabelle vorgenommen werden. Dieser vielseitige Befehl bietet die M&ouml;glichkeit, Spalten- und Tabellen-Constraints hinzuzuf&uuml;gen, <span class="emphasis">DEFAULT</span>-Werte festzulegen und zu l&ouml;schen, den <span class="emphasis">SCOPE</span>-Wert von Spalten, die einen benutzerdefinierten Typ referenzieren, hinzuzuf&uuml;gen oder zu l&ouml;schen und mit <span class="emphasis">DROP</span> sowohl Spalten- als auch Tabellen-Constraints zu l&ouml;schen. <span class="emphasis">DROP RESTRICT</span> fordert das Host-DBMS auf, die Ausf&uuml;hrung des Befehls abzubrechen, wenn festgestellt wird, dass andere Objekte in der Datenbank von dem Spalten- oder Tabellen-Constraint abh&auml;ngen. <span class="emphasis">DROP CASCADE</span> teilt dem Host-DBMS mit, dass alle Datenbankobjekte gel&ouml;scht werden sollen, die von dem Spalten- oder Tabellen-Constraint abh&auml;ngen. N&auml;here Erl&auml;uterungen zu diesem Befehl finden Sie unter <span class="emphasis">CREATE TABLE</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER TABLE table_name
[ALTER COLUMN column_name new_data_type attributes {ADD | DROP}
   ROWGUIDCOL]
| [ADD [COLUMN] column_name datatype attributes][,...n]
| [WITH CHECK | WITH NOCHECK] ADD table_constraint][,...n]
| [DROP { [ CONSTRAINT ] constraint_name | COLUMN column_name }] [,...n]
| [{ CHECK | NOCHECK } CONSTRAINT { ALL | constraint_name [,...n] }]
| [{ ENABLE | DISABLE } TRIGGER { ALL | trigger_name [,...n] }]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Microsoft SQL Server-Implementierung von <span class="emphasis">ALTER TABLE</span> bietet eine Vielzahl von M&ouml;glichkeiten.  Mit <span class="emphasis">ALTER COLUMN</span> k&ouml;nnen bestehende Spalten im Hinblick auf Datentyp, Null-Zul&auml;ssigkeit, Identit&auml;tsfunktionen usw. ge&auml;ndert werden. Mit <span class="emphasis">ADD </span>wird der Tabelle an der letzten Spaltenposition eine neue Spalte, eine berechnete Spalte oder ein Constraint hinzugef&uuml;gt. (Derzeit gibt es keine M&ouml;glichkeit, eine Spalte in der Mitte oder an einer anderen Stelle der Tabelle einzuf&uuml;gen.) Das optionale Wort <span class="emphasis">COLUMN</span> wird nur aus Gr&uuml;nden der Lesbarkeit angegeben, ist aber nicht notwendig. Die neue Spalte muss genauso wie bei der Anweisung <span class="emphasis">CREATE TABLE</span> definiert werden, einschlie&szlig;lich aller Constraints, Standardwerte und Sortierreihenfolgen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klauseln <span class="emphasis">WITH CHECK</span> und <span class="emphasis">WITH NOCHECK</span> teilen SQL Server mit, ob die Tabellendaten anhand der neu hinzugef&uuml;gten Constraints oder Schl&uuml;ssel validiert werden sollen. Wenn Constraints mit <span class="emphasis">WITH NOCHECK</span> hinzugef&uuml;gt werden, ignoriert der Abfrageoptimierer sie, bis sie mit <span class="emphasis">ALTER TABLE table_name CHECK CONSTRAINT ALL</span> aktiviert werden. Constraints k&ouml;nnen mit <span class="emphasis">DROP CONSTRAINT</span> gel&ouml;scht (das Schl&uuml;sselwort <span class="emphasis">CONSTRAINT</span> ist dabei nicht erforderlich) und mit <span class="emphasis">CHECK CONSTRAINT</span> und <span class="emphasis">NOCHECK CONSTRAINT</span> aktiviert bzw. deaktiviert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In &auml;hnlicher Weise kann ein benannter Trigger f&uuml;r eine Tabelle mit der Klausel <span class="emphasis">ENABLE TRIGGER</span> aktiviert und mit der Klausel <span class="emphasis">DISABLE TRIGGER</span> deaktiviert werden. Die Trigger f&uuml;r eine Tabelle k&ouml;nnen auch alle auf einmal mit dem Schl&uuml;sselwort <span class="emphasis">ALL</span> anstatt dem Tabellennamen aktiviert werden wird, wie zum Beispiel in <span class="emphasis">ALTER TABLE employee DISABLE TRIGGER ALL</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER [IGNORE] TABLE table_name
[ADD [COLUMN] column_name datatype attributes ]
   [FIRST | AFTER column_name]] [,...n]
| [ADD INDEX [index_name] (index_col_name,...)] [,...n]
| [ADD PRIMARY KEY (index_col_name,...)] [,...n]
| [ADD UNIQUE [index_name] (index_col_name,...)] [,...n]
| [ALTER [COLUMN] column_name {SET DEFAULT literal | DROP DEFAULT}] [,...n]
| [CHANGE [COLUMN] old_col_name create_definition] [,...n]
| [MODIFY [COLUMN] column_name datatype attributes] [,...n]
| [DROP [COLUMN] column_name] [,...n]
| [DROP PRIMARY KEY] [,...n]
| [DROP INDEX index_name] [,...n]
| [RENAME [AS] new_tbl_name] [,...n]
| [table_options]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>N&auml;here Informationen zu den zul&auml;ssigen Spaltenattributen und Tabellen-Constraints finden Sie unter der Anweisung <span class="emphasis">CREATE TABLE</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Option <span class="emphasis">IGNORE</span> wird MySQL aufgefordert, doppelte Zeilen zu l&ouml;schen, wenn ein neuer eindeutiger Schl&uuml;ssel definiert wird. Wenn <span class="emphasis">IGNORE</span> nicht angegeben ist, wird die Operation abgebrochen, wenn es f&uuml;r den eindeutigen Schl&uuml;ssel mehrere Datens&auml;tze gibt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Option <span class="emphasis">FIRST</span> wird verwendet, wenn eine neue Spalte als erste Spalte der Tabelle hinzugef&uuml;gt werden soll. Mit <span class="emphasis">AFTER column_name</span> kann eine neue Spalte nach einer vorhandenen Spalte (<span class="emphasis">column_name</span>) in die Tabelle eingef&uuml;gt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Bei der Anweisung <span class="emphasis">ALTER TABLE</span> bietet MySQL zus&auml;tzliche Flexibilit&auml;t, weil der Benutzer die M&ouml;glichkeit hat, mehrere <span class="emphasis">ADD</span>-, <span class="emphasis">ALTER</span>-, <span class="emphasis">DROP</span>- und <span class="emphasis">CHANGE</span>-Klauseln in eine einzige <span class="emphasis">ALTER TABLE</span>-Anweisung zu stellen. Es sei jedoch darauf hingewiesen, dass die Klauseln <span class="emphasis">CHANGE column_name</span> und <span class="emphasis">DROP INDEX</span> MySQL-Erweiterungen sind, die es im SQL99-Standard nicht gibt. MySQL unterst&uuml;tzt au&szlig;erdem die Oracle-Erweiterung <span class="emphasis">MODIFY column_name</span>. Mit der Klausel <span class="emphasis">ALTER COLUMN</span> kann ein neuer Standardwert f&uuml;r eine Spalte festgelegt oder gel&ouml;scht werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Eine Tabelle kann mit <span class="emphasis">RENAME AS</span> umbenannt werden, und eine Spalte mit <span class="emphasis">CHANGE</span>. Mit dem nachfolgenden Code wird zum Beispiel sowohl eine Tabelle als auch eine Spalte umbenannt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER TABLE employee RENAME AS emp;
ALTER TABLE employee CHANGE employee_ssn emp_ssn INTEGER;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Weil MySQL es erlaubt, Indizes nur f&uuml;r Teile einer Spalte zu erstellen (zum Beispiel die ersten zehn Zeichen), k&ouml;nnen die Befehle <span class="emphasis">CHANGE</span> und <span class="emphasis">MODIFY</span> nicht dazu verwendet werden, eine Spalte zu erzeugen, die k&uuml;rzer ist als die entsprechenden Indizes. Bei Benutzung von <span class="emphasis">DROP COLUMN</span> wird die Spalte sowohl aus der Tabelle als auch aus allen Indizes, die auf dieser Spalte basieren, gel&ouml;scht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">DROP PRIMARY KEY</span> schl&auml;gt nicht automatisch fehl, wenn auf der Tabelle kein Prim&auml;rschl&uuml;ssel liegt. In diesem Fall l&ouml;scht MySQL den ersten eindeutigen Index der Tabelle.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In MySQL kann der Datentyp einer bestehenden Spalte umdefiniert werden, ohne dass Daten verloren gehen. Die in der Spalte enthaltenen Werte m&uuml;ssen mit dem neuen Datentyp kompatibel sein. Beispielsweise kann eine Datumsspalte in eine Zeichenspalte umdefiniert werden, nicht aber eine Zeichenspalte in eine Integerspalte. Dazu ein Beispiel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER TABLE mytable MODIFY mycolumn LONGTEXT</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>MySQL erlaubt die Klauseln <span class="emphasis">FOREIGN KEY</span>, <span class="emphasis">CHECK</span> und <span class="emphasis">REFERENCES</span>, diese sind allerdings leer. Befehle, die diese Klauseln enthalten, k&ouml;nnen zwar ausgef&uuml;hrt werden, sie haben jedoch keine Auswirkung. Sie stehen haupts&auml;chlich zur Verf&uuml;gung, um das Portieren zu erleichtern.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER TABLE [owner_name.]table_name
[ADD column_name datatype attributes]
| [MODIFY {column_name datatype
   | column_constraint
   | physical_storage_attributes [LOGGING | NOLOGGING]
   | nested_table_attributes}]
| [MODIFY CONSTRAINT {constraint_name {constraint_state}
   | drop_constraint_clause
   | drop_column_clause
   | [ALLOCATE | DEALLOCATE extent_clause]
   | [CACHE | NOCACHE]
   | [LOGGING | NOLOGGING]
   | [MONITORING | NOMONITORING] ]
| [DROP {[COLUMN] column_name | constraint_name}]
| [ALLOCATE EXTENT details]
| [DEALLOCATE UNUSED details]
| [RENAME TO new_table_name]
| [OVERFLOW physical_storage_attributes]
| [ADD OVERFLOW physical_storage_attributes]
| [{ADD | DROP | MODIFY | MOVE | TRUNCATE | SPLIT | EXCHANGE | MODIFY}
   PARTITION partition_details]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Anweisung <span class="emphasis">ALTER TABLE</span> in Oracle zeigt die zahlreichen M&ouml;glichkeiten zur Steuerung des physischen Speichers und zur Manipulation von Tabellen, wie zum Beispiel die Handhabung von Daten-Extents und Overflow-Extents und die Partitionierung von Tabellen zur besseren Verteilung extremer Nutzungslasten. Die Syntax, die f&uuml;r bestimmte oben aufgef&uuml;hrte Zeilen wie <span class="emphasis">column_constraint</span>, <span class="emphasis">physical_storage_attributes</span> und <span class="emphasis">nested_table_attributes</span> zul&auml;ssig ist, wird im Abschnitt zur Oracle-Implementierung von <span class="emphasis">CREATE TABLE</span> beschrieben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Dieser Befehl kann verwendet werden, um mit <span class="emphasis">ADD</span> eine neue Spalte oder einen neuen Constraint hinzuzuf&uuml;gen oder um mit <span class="emphasis">MODIFY</span> und <span class="emphasis">DROP</span> bestehende Spalten und Constraints zu &auml;ndern bzw. zu l&ouml;schen. Wenn eine neue Spalte hinzugef&uuml;gt wird, sollte diese als <span class="emphasis">NULL</span> definiert werden, es sei denn, die Tabelle enth&auml;lt keine Zeilen. Mit dem Schl&uuml;sselwort <span class="emphasis">MODIFY</span> k&ouml;nnen Sie die Eigenschaften einer zuvor erzeugten Tabelle &auml;ndern. Mit <span class="emphasis">MODIFY CONSTRAINT </span>k&ouml;nnen Sie Tabellen-Constraints l&ouml;schen oder &auml;ndern und unter anderem auch festlegen, ob <span class="emphasis">LOGGING</span>, <span class="emphasis">CACHE</span> oder <span class="emphasis">MONITOR</span> aktiviert und ob Speicher-Extents alloziert (<span class="emphasis">ALLOCATE</span>) oder dealloziert (<span class="emphasis">DEALLOCATE</span>) werden sollen. Weiterhin werden die Schl&uuml;sselw&ouml;rter <span class="emphasis">ENABLE</span> und <span class="emphasis">DISABLE</span> zum Aktivieren und Deaktivieren von Tabellen-Constraints unterst&uuml;tzt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Oracle-Implementierung von <span class="emphasis">ALTER TABLE</span> ist sehr vielf&auml;ltig und komplex. Umfassende Informationen zu Unterklauseln f&uuml;r gemeinsame Befehle finden Sie unter der Anweisung <span class="emphasis">CREATE TABLE</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der folgende Code f&uuml;gt einer Tabelle in Oracle beispielsweise eine neue Spalte hinzu und legt einen neuen, eindeutigen Constraint auf diese Tabelle:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER TABLE titles
ADD subtitle VARCHAR2(32) NULL
CONSTRAINT unq_subtitle UNIQUE;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn einer Tabelle ein Fremdschl&uuml;ssel-Constraint hinzugef&uuml;gt wird, &uuml;berpr&uuml;ft das DBMS, ob alle Daten in der Tabelle diese Integrit&auml;tsregel erf&uuml;llen. Ist dies nicht der Fall, schl&auml;gt <span class="emphasis">ALTER TABLE</span> fehl.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Alle Anwendungen, die <span class="literal">SELECT</span> <span class="literal">*</span> verwenden, geben die neuen Spalten zur&uuml;ck, auch wenn dies nicht geplant war. Andererseits geben vorkompilierte Objekte wie gespeicherte Prozeduren m&ouml;glicherweise keine neuen Spalten zur&uuml;ck.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle l&auml;sst auch mehrfache Aktionen wie <span class="emphasis">ADD</span> oder <span class="emphasis">MODIFY</span> in mehreren Spalten zu, wobei die Aktion in runde Klammern gesetzt werden muss. Mit dem folgenden Befehl werden beispielsweise einer Tabelle in einer einzigen Anweisung mehrere Spalten hinzugef&uuml;gt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER TABLE titles
ADD (subtitles VARCHAR2(32) NULL,
   year_of_copyright INT,
   date_of_origin DATE);</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER TABLE table [*]
[ADD [COLUMN] column_name datatype attributes]
| [ALTER [COLUMN] column_name {SET DEFAULT value | DROP DEFAULT}]
| [RENAME [COLUMN] column_name TO new_column_name]
| [RENAME TO new_table_name]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die PostgreSQL-Implementierung von <span class="emphasis">ALTER TABLE</span> erm&ouml;glicht das Hinzuf&uuml;gen weiterer Spalten mit dem Schl&uuml;sselwort <span class="emphasis">ADD</span>
 . Bestehenden Spalten k&ouml;nnen mit <span class="emphasis">ALTER COLUMN . . . SET DEFAULT</span> neue Standardwerte zugewiesen werden, w&auml;hrend sich mit <span class="emphasis">ALTER COLUMN . . . DROP DEFAULT</span> ein spaltenbasierter Standardwert vollst&auml;ndig l&ouml;schen l&auml;sst. Dar&uuml;ber hinaus k&ouml;nnen mit der Klausel <span class="emphasis">ALTER</span> neue Standardwerte zu Spalten hinzugef&uuml;gt werden, wobei davon aber nur neu eingef&uuml;gte Zeilen betroffen sind. Mit <span class="emphasis">RENAME</span> k&ouml;nnen bestehende Spalten und Tabellen umbenannt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="ALTER TRIGGER">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">ALTER TRIGGER </td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">ALTER TRIGGER</span>

 kann eine vorhandene Triggerdefinition ge&auml;ndert werden, ohne dass dies Auswirkungen auf Zugriffsrechte oder Abh&auml;ngigkeiten hat.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Derzeit gibt es keinen SQL99-Standard f&uuml;r diesen Befehl.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER TRIGGER trigger_name
ON {table_name | view_name}
[WITH ENCRYPTION]
{FOR | AFTER | INSTEAD OF} {[DELETE] [,] [INSERT] [,] [UPDATE]}
[WITH APPEND]
[NOT FOR REPLICATION]
AS
  T-SQL_block
| [FOR { [INSERT] [,] [UPDATE] }
[NOT FOR REPLICATION]
AS

  { IF UPDATE(column) [{AND | OR} UPDATE(column)] [...n]
    |
    IF (COLUMNS_UPDATED(  ) {bitwise_operator} updated_bitmask)
    { comparison_operator} column_bitmask [...n] }
    T-SQL_block ] } ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server erm&ouml;glicht die Angabe von <span class="emphasis">FOR | AFTER | INSTEAD OF { [DELETE] [,] [UPDATE] [,][INSERT] } | { [INSERT] [,] [UPDATE] }</span>, um zu beschreiben, welcher Trigger einer Anweisung zur Datenmodifikation von dem Befehl betroffen ist. Es muss mindestens einer dieser Werte angegeben werden. Es ist jedoch jede beliebige Kombination m&ouml;glich, wobei die zus&auml;tzlichen Optionen durch Kommas zu trennen sind. Die Optionen <span class="emphasis">FOR</span> und <span class="emphasis">AFTER</span> sind im Prinzip gleich und sorgen daf&uuml;r, dass der Triggercode ausgel&ouml;st wird, sobald die Datenmanipulationsoperation abgeschlossen ist. Alternativ dazu fordert die Klausel <span class="emphasis">INSTEAD OF</span> SQL Server auf, die Datenmanipulationsoperation vollst&auml;ndig durch den Code des Triggers zu ersetzen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">WITH APPEND</span> wird SQL Server mitgeteilt, dass der Basistabelle ein weiterer Trigger des angegebenen Typs hinzugef&uuml;gt werden soll. Dies ist nur bei <span class="emphasis">FOR</span>-Triggern m&ouml;glich. Die Klausel <span class="emphasis">NOT FOR REPLICATION</span> teilt SQL Server mit, den Trigger nicht auszuf&uuml;hren, wenn die Aktion durch ein Replikations-Login wie <span class="emphasis">sqlrepl</span> ausgel&ouml;st wird. Die Klausel <span class="emphasis">IF UPDATE (column)</span> pr&uuml;ft, ob eine <span class="emphasis">INSERT</span>- oder <span class="emphasis">UPDATE</span>-Aktion (aber nicht <span class="emphasis">DELETE</span>) f&uuml;r eine bestimmte Spalte vorliegt. Sie ist sehr n&uuml;tzlich, wenn es um zeilenbasierte Operationen mit Cursorn geht. Mit den Operatoren <span class="emphasis">{AND | OR}</span> k&ouml;nnen zus&auml;tzliche Spalten in derselben Klausel getestet werden. Mit <span class="emphasis">IF (COLUMNS_UPDATED( ))</span> wird ein <span class="emphasis">INSERT</span>- oder <span class="emphasis">UPDATE</span>-Trigger abgefragt, um herauszufinden, ob die angegebenen Spalten betroffen waren. Die Ergebnisse werden als Bit-Operatoren zur&uuml;ckgegeben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER TRIGGER [user.]<span class="replaceable">trigger_name </span>[ENABLE | DISABLE | COMPILE [DEBUG] ];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle kann der dem Trigger zugrunde liegende Code mit diesem Befehl nicht vollst&auml;ndig ge&auml;ndert werden (dies l&auml;sst sich mit der Oracle-Implementierung von <span class="emphasis">CREATE OR REPLACE TRIGGER</span>) erreichen. Mit <span class="emphasis">ALTER TRIGGER </span> kann in Oracle ein Trigger aktiviert, deaktiviert oder neu kompiliert werden. Mit der Option <span class="emphasis">COMPILE [DEBUG] </span>werden PL/SQL-Informationen neu generiert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle erlaubt

Trigger <span class="emphasis">nur</span> f&uuml;r Tabellen (auch wenn <span class="emphasis">INSTEAD OF</span>-Trigger f&uuml;r Views erlaubt sind). Microsoft SQL Server erlaubt Trigger f&uuml;r Tabellen und aktualisierbare Views.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="ALTER VIEW">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">ALTER VIEW</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Derzeit gibt es keinen SQL99-Standard f&uuml;r die <span class="emphasis">ALTER VIEW</span>

-Anweisung. Es ist daher wichtig zu wissen, dass sich dieser Befehl in jeder unterst&uuml;tzten Implementierung anders verh&auml;lt. Oracle verwendet diesen Befehl zum Neukompilieren eines Views, Microsoft SQL Server dagegen zum &Auml;ndern von Views, ohne dass gleichzeitig davon abh&auml;ngige gespeicherte Prozeduren, Trigger oder Zugriffsrechte aktualisiert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Derzeit gibt es keinen SQL99-Standard f&uuml;r diesen Befehl.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER VIEW <span class="replaceable">view_name </span>[(<span class="replaceable">column</span> [,...n])]
[WITH {ENCRYPTION | SCHEMABINDING | VIEW_METADATA]
AS
<span class="replaceable">select_statement</span>
[WITH CHECK OPTION]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Genau wie bei der Anweisung <span class="emphasis">CREATE VIEW</span> hat der Programmierer auch bei <span class="emphasis">ALTER VIEW</span> die M&ouml;glichkeit, die Spalten-Aliasnamen festzulegen, die der View zur Benennung der Spalten verwenden soll. Dar&uuml;ber hinaus kann die gesamte <span class="emphasis">SELECT</span>-Anweisung angegeben werden, die dem View zugrunde liegt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die anderen Klauseln der Anweisung <span class="emphasis">ALTER VIEW</span> sind unter <span class="emphasis">CREATE VIEW</span> beschrieben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server kann die Spaltenzugriffsrechte nur verwalten, wenn die Spaltennamen nach der Ausf&uuml;hrung des Befehls unver&auml;ndert bleiben. Mit dem Schl&uuml;sselwort <span class="emphasis">ENCRYPTION</span> kann der Code von Views in der Systemtabelle <span class="emphasis">syscomments</span> von SQL Server verschl&uuml;sselt werden. Die <span class="emphasis">CHECK OPTION</span>-Schl&uuml;sselw&ouml;rter bewirken, dass alle Daten&auml;nderungen, die im View ausgef&uuml;hrt werden, die Kriterien der definierenden SELECT-Anweisung (<span class="emphasis">select_statement</span>) erf&uuml;llen. Wenn der View vorher eine dieser beiden Optionen enthielt, m&uuml;ssen diese mit der Anweisung <span class="emphasis">ALTER VIEW</span> aktiviert werden, um aktiv zu bleiben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ALTER VIEW [user.]<span class="replaceable">view_name </span>COMPILE</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">ALTER VIEW</span> wird ein View in Oracle neu kompiliert. Sie ist n&uuml;tzlich, um sicherzustellen, dass ein View noch g&uuml;ltig ist, nachdem &Auml;nderungen an der Basistabelle vorgenommen wurden. Ein View wird ung&uuml;ltig, wenn seine Basistabellen ge&auml;ndert wurden und er nicht neu kompiliert wurde.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel </span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In diesem Beispiel aus SQL Server wird ein View mit dem Namen <span class="emphasis">california_authors</span> erzeugt, der Autoren aus Kalifornien enth&auml;lt. Dann wird <span class="emphasis">ALTER VIEW</span> verwendet, um den View zu erweitern und zu ersetzen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE VIEW california_authors
AS
SELECT au_lname, au_fname, city, state
FROM authors
WHERE state = 'CA'
WITH CHECK OPTION
GO

ALTER VIEW california_authors
AS
SELECT au_fname, au_lname, address, city, state, zip
FROM pubs..authors
WHERE state = "CA"
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CALL">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CALL </td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">CALL</span>  wird eine gespeicherte Prozedur aufgerufen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CALL procedure_name [(parameter [,...n] )]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">CALL</span> l&auml;sst sich schnell und einfach eine gespeicherte Prozedur aufrufen. Sie brauchen lediglich den Namen der gespeicherten Prozedur und in Klammern eingeschlossen die von der gespeicherten Prozedur verwendeten Parameter anzugeben. Wenn die gespeicherte Prozedur nur <span class="emphasis">OUT</span>-Parameter oder &uuml;berhaupt keine Parameter hat, k&ouml;nnen die Klammern leer bleiben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt die <span class="emphasis">CALL</span>-Anweisung nicht. Eine nahezu identische Funktionalit&auml;t erreichen Sie aber mit der Anweisung <span class="emphasis">EXECUTE</span> . Umfassende Informationen &uuml;ber diese SQL Server-Erweiterung finden Sie in der Dokumentation des Herstellers.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CALL [schema.][{type_name | package_name}.]procedure_name@dblink
[(parameter [,...n] )]
[INTO :variable_name [INDICATOR :indicator_name] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Oracle-Anweisung <span class="emphasis">CALL</span> k&ouml;nnen unabh&auml;ngige gespeicherte Prozeduren, Funktionen und Methoden sowie gespeicherte Prozeduren und Funktionen in einem Typ oder Package aufgerufen werden. Wenn sich die Prozedur oder die Funktion in einer anderen Datenbank befindet, deklarieren Sie die Datenbank einfach mit einer dblink-Anweisung, die angibt, wo sich das Objekt befindet. dblink muss ein zuvor erzeugter Datenbank-Link sein.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn die aufgerufene Routine eine Funktion ist, erfordert Oracle die <span class="emphasis">INTO</span> -Klausel. Umgekehrt kann INTO nur verwendet werden, wenn Funktionen aufgerufen werden. Die Variable, in der der von der Funktion zur&uuml;ckgegebene Wert gespeichert werden soll, muss ebenfalls angegeben werden. Zum Schluss kann noch ein Indikator angegeben werden, der die Bedingung der Hostvariablen enth&auml;lt, wenn die Funktion eine vorkompilierte Pro*C/C++-Routine ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In diesem Beispiel wird eine einfache gespeicherte Prozedur erzeugt, die anschlie&szlig;end unabh&auml;ngig davon aufgerufen wird:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE PROCEDURE update_employee_salary
(emp_id NUMBER, updated_salary NUMBER)
IS
BEGIN
  UPDATE employee SET salary = updated_salary WHERE employee_id =emp_id ;
END;

CALL update_employee_salary(1517, 95000);</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CASE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CASE </td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Die Funktion <span class="emphasis">CASE</span>

 stellt eine <span class="emphasis">IF-THEN-ELSE</span>-Funktionalit&auml;t in einer <span class="emphasis">SELECT</span>- oder <span class="emphasis">UPDATE</span>-Anweisung zur Verf&uuml;gung. Sie wertet eine Liste von Bedingungen aus und gibt einen von mehreren m&ouml;glichen Werten zur&uuml;ck.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Nicht unterst&uuml;tzt (Sie k&ouml;nnen stattdessen die Funktion <span class="emphasis">DECODE</span> verwenden, N&auml;heres dazu finden Sie in der Dokumentation des Herstellers)</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">CASE</span> kennt zwei Verwendungsarten: einfach und komplex. Bei einfachen <span class="emphasis">CASE</span>-Ausdr&uuml;cken wird ein Wert - der <span class="emphasis">input_value</span> - mit einer Liste anderer Werte verglichen und das Ergebnis zur&uuml;ckgegeben, das zu dem ersten &uuml;bereinstimmenden Wert passt. Komplexe <span class="emphasis">CASE</span>-Ausdr&uuml;cke erm&ouml;glichen die Analyse verschiedener logischer Bedingungen und geben das Ergebnis zur&uuml;ck, das zur ersten wahren Bedingung geh&ouml;rt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>-- Einfache Vergleichsoperation
CASE input_value
WHEN when_condition THEN resulting_value
[...n]
[ELSE else_result_value]
END

-- Boolesche Suchoperation
CASE
WHEN Boolean_condition THEN resulting_value
[...n]
[ELSE else_result_expression]
END</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Bei einer einfachen <span class="emphasis">CASE</span>-Funktion wird der <span class="emphasis">input_value</span> mit jeder <span class="emphasis">WHEN</span>-Klausel verglichen. Der <span class="emphasis">resulting_value</span> wird f&uuml;r die erste wahre Instanz (TRUE) zur&uuml;ckgegeben, bei der gilt <span class="emphasis">input_value</span> = <span class="emphasis">when_condition</span>. Wenn keine <span class="emphasis">when_condition</span> TRUE ist, wird der <span class="emphasis">else_result_value</span> zur&uuml;ckgegeben. Ist kein <span class="emphasis">else_result_value</span> angegeben, wird NULL zur&uuml;ckgegeben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Struktur der komplexeren Booleschen Operation &auml;hnelt im Prinzip der einfachen Vergleichsoperation, unterscheidet sich aber dadurch, dass jede <span class="emphasis">WHEN</span>-Klausel ihren eigenen Booleschen Vergleichsoperator hat.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Bei beiden Verwendungsformen k&ouml;nnen mehrere <span class="emphasis">WHEN</span>-Klauseln verwendet werden, auch wenn nur eine <span class="emphasis">ELSE</span>-Klausel erforderlich ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Nachfolgend eine einfache Vergleichsoperation, bei der mit der Funktion <span class="emphasis">CASE</span> die Anzeige in der Spalte "contract" ge&auml;ndert wird, um sie besser lesbar zu machen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT  au_fname,
        au_lname,
        CASE contract
            WHEN 1 THEN 'Yes'
            ELSE 'No'
        END 'contract'
FROM    authors
WHERE   state = 'CA'</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Zum Vergleich eine komplexe <span class="emphasis">CASE</span>-Funktion in einer <span class="emphasis">SELECT</span>-Anweisung, die Auskunft dar&uuml;ber gibt, wie viele Titel in bestimmten Zeitr&auml;umen verkauft wurden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT CASE
           WHEN ytd_sales IS NULL  THEN 'Unknown'
           WHEN ytd_sales &lt;=   200 THEN 'Not more than 200'
           WHEN ytd_sales &lt;=  1000 THEN 'Between  201 and  1000'
           WHEN ytd_sales &lt;=  5000 THEN 'Between 1001 and  5000'
           WHEN ytd_sales &lt;= 10000 THEN 'Between 5001 and 10000'
           ELSE 'Over 10000'
       END 'YTD Sales',
       COUNT(*) 'Number of Titles'
FROM   titles
GROUP BY CASE
           WHEN ytd_sales IS NULL  THEN 'Unknown'
           WHEN ytd_sales &lt;=   200 THEN 'Not more than 200'
           WHEN ytd_sales &lt;=  1000 THEN 'Between  201 and  1000'
           WHEN ytd_sales &lt;=  5000 THEN 'Between 1001 and  5000'
           WHEN ytd_sales &lt;= 10000 THEN 'Between 5001 and 10000'
           ELSE 'Over 10000'
         END
ORDER BY MIN( ytd_sales )</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Ergebnisse sehen folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>YTD Sales              Number of Titles
---------------------- ----------------
Unknown                2
Not more than 200      1
Between  201 and  1000 2
Between 1001 and  5000 9
Between 5001 and 10000 1
Over 10000             3</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Als n&auml;chstes haben wir eine <span class="emphasis">UPDATE</span>-Anweisung, mit der f&uuml;r alle Titel ein Rabatt festgelegt werden soll. Der etwas komplexere Befehl gew&auml;hrt auf alle PC-Titel einen Rabatt von 25&#160;%, auf alle anderen Titel 10&#160;% und auf alle Titel, die bisher mehr als 10.000 Mal verkauft wurden, einen Rabatt von nur 5&#160;%.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die folgende <span class="emphasis">UPDATE</span>-Abfrage verwendet einen komplexen <span class="emphasis">CASE</span>-Ausdruck, um die Preise anzupassen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>UPDATE  titles
SET     price = price *
        CASE
            WHEN ytd_sales &gt; 10000     THEN 0.95  -- 5% discount
            WHEN type = 'popular_comp' THEN 0.75  -- 25% discount
            ELSE 0.9                              -- 10% discount
        END
WHERE   pub_date IS NOT NULL</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Hier wurden also drei verschiedene Aktualisierungsoperationen mit einer einzigen Anweisung ausgef&uuml;hrt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CAST">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CAST </td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">CAST</span>
 wird ein Ausdruck explizit in einen anderen Datentyp umgewandelt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CAST(expression AS data_type[(length)])</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Funktion <span class="emphasis">CAST</span> kann ein beliebiger Ausdruck wie beispielsweise ein Spaltenwert oder eine Variable in einen anderen definierten Datentyp konvertiert werden. Optional kann bei Datentypen, die L&auml;ngenangaben unterst&uuml;tzen (wie <span class="emphasis">CHAR</span> oder <span class="emphasis">VARCHAR</span>), auch eine L&auml;nge angegeben werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Beachten Sie, dass es bei manchen Konvertierungen wie zum Beispiel von <span class="emphasis">DECIMAL</span>-Werten in <span class="emphasis">INTEGER</span>-Werte zu Rundungen kommen kann. Manche Konvertierungsoperationen l&ouml;sen auch einen Fehler aus, wenn der neue Datentyp &uuml;ber nicht gen&uuml;gend Platz zur Anzeige des konvertierten Wertes verf&uuml;gt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel wird der bisher erzielte Umsatz als <span class="emphasis">CHAR</span> abgerufen und mit einer Literalzeichenfolge und einem Teil des Buchtitels verkn&uuml;pft. Hier wird <span class="emphasis">ytd_sales</span> zu <span class="emphasis">CHAR(5)</span> konvertiert und die L&auml;nge des <span class="emphasis">title</span> verk&uuml;rzt, um die Ergebnisse leichter lesbar zu machen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT CAST(ytd_sales AS CHAR(5)) + "Copies sold of " + CAST(title AS
VARCHAR(30))
FROM titles
WHERE ytd_sales IS NOT NULL
  AND ytd_sales &gt; 10000
ORDER BY ytd_sales DESC</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Ergebnisse sehen folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>---------------------------------------------------
22246 Copies sold of The Gourmet Microwave
18722 Copies sold of You Can Combat Computer Stress
15096 Copies sold of Fifty Years in Buckingham Pala</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CLOSE CURSOR">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CLOSE CURSOR</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">CLOSE CURSOR</span>

 wird ein serverseitiger Cursor geschlossen, der mit der Anweisung <span class="emphasis">DECLARE CURSOR</span> erzeugt wurde. MySQL unterst&uuml;tzt zwar keine serverseitigen Cursor, daf&uuml;r aber umfassende Erweiterungen in der Programmiersprache C.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CLOSE { cursor_name }</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">cursor_name</span> ist der Name des Cursors gemeint, der mit dem Befehl <span class="emphasis">DECLARE CURSOR </span>erzeugt wurde.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Das folgende Beispiel aus Microsoft SQL Server &ouml;ffnet einen Cursor und liest alle Zeilen aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DECLARE employee_cursor CURSOR FOR
  SELECT lname, fname
  FROM pubs.dbo.authors
  WHERE lname LIKE 'K%'

OPEN employee_cursor

FETCH NEXT FROM employee_cursor

WHILE @@FETCH_STATUS = 0
BEGIN
  FETCH NEXT FROM Employee_Cursor
END

CLOSE employee_cursor

DEALLOCATE employee_cursor</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">DEALLOCATE</span> in Microsoft SQL Server werden die vom Cursor beanspruchten Ressourcen und Datenstrukturen freigegeben; Oracle, PostgreSQL und MySQL verwenden diese Anweisung nicht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="COMMIT TRANSACTION">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">COMMIT TRANSACTION</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">COMMIT</span>
 <span class="emphasis">TRANSACTION</span> wird eine offene Transaktion explizit beendet, unabh&auml;ngig davon, ob diese explizit mit <span class="emphasis">BEGIN</span> oder implizit als Bestandteil einer <span class="emphasis">INSERT</span>-, <span class="emphasis">UPDATE</span>- oder <span class="emphasis">DELETE</span>-Anweisung ge&ouml;ffnet wurde. Mit diesem Befehl kann eine Datenmanipulationsoperation manuell und dauerhaft beendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>COMMIT [WORK]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">COMMIT</span> lassen sich nicht nur einzelne oder mehrere Datenmanipulationsoperationen beenden, vielmehr hat diese Anweisung auch interessante Auswirkungen auf andere Aspekte einer Transaktion. Zun&auml;chst einmal werden s&auml;mtliche zugeh&ouml;rigen offenen Cursor geschlossen. Zweitens werden alle Daten aus mit <span class="emphasis">ON COMMIT DELETE ROWS</span> angegebenen Tabellen gel&ouml;scht. Drittens werden alle Sperren, die im Rahmen der Transaktion angelegt wurden, aufgehoben. Zum Schluss werden noch alle verz&ouml;gerten Constraints &uuml;berpr&uuml;ft. Wenn gegen die verz&ouml;gerten Constraints versto&szlig;en wird, wird die Transaktion zur&uuml;ckgenommen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>SQL99 schreibt vor, dass Transaktionen <span class="emphasis">implizit ge&ouml;ffnet</span> werden, wenn eine der folgenden Anweisungen ausgef&uuml;hrt wird:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ul><li><span class="emphasis">ALTER </span></li><li><span class="emphasis">CLOSE </span></li><li><span class="emphasis">COMMIT AND CHAIN</span> (neu in SQL99)</li><li><span class="emphasis">CREATE </span></li><li><span class="emphasis">DELETE </span></li><li><span class="emphasis">DROP </span></li><li><span class="emphasis">FETCH </span></li><li><span class="emphasis">FREE LOCATOR </span></li><li><span class="emphasis">GRANT </span></li><li><span class="emphasis">HOLD LOCATOR</span></li><li><span class="emphasis">INSERT </span></li><li><span class="emphasis">OPEN </span></li><li><span class="emphasis">RETURN</span></li><li><span class="emphasis">REVOKE</span></li><li><span class="emphasis">ROLLBACK AND CHAIN </span>(neu in SQL99)</li><li><span class="emphasis">SELECT </span></li><li><span class="emphasis">START TRANSACTION </span>(neu in SQL99)</li><li><span class="emphasis">UPDATE </span></li></ul>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der SQL99-Standard beinhaltet die neuen optionalen Schl&uuml;sselw&ouml;rter <span class="emphasis">AND CHAIN</span>. Bislang wird dieser Befehl noch von keinem der in diesem Buch behandelten Hersteller unterst&uuml;tzt. Diese neue Syntax sieht folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>COMMIT [WORK] [AND [NO] CHAIN]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Option <span class="emphasis">AND CHAIN</span> wird das DBMS aufgefordert, die nachfolgende Transaktion so zu behandeln, als sei sie Bestandteil der vorhergehenden Transaktion. Die beiden Transaktionen stellen zwar separate Arbeitseinheiten dar, aber sie teilen sich eine gemeinsame Transaktionsumgebung (wie beispielsweise die Isolationsebene). Mit der Option <span class="emphasis">AND NO CHAIN</span> wird die einzelne Transaktion einfach beendet. Der Befehl <span class="emphasis">COMMIT</span> hat dieselbe Funktion wie <span class="emphasis">COMMIT WORK AND NO CHAIN</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>COMMIT [TRAN[SACTION] [transaction_name | @tran_name_variable] ]
|
COMMIT [WORK]
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server bietet die M&ouml;glichkeit, eine bestimmte benannte Transaktion festzuschreiben. Der Befehl <span class="emphasis">COMMIT</span> muss immer mit einem <span class="emphasis">BEGIN TRAN</span>-Befehl kombiniert werden. Mit Hilfe der <span class="emphasis">COMMIT TRANSACTION</span>-Syntax kann der Programmierer eine explizite Transaktion angeben, die geschlossen werden oder deren Name in einer Variablen gespeichert werden soll. Seltsamerweise schreibt SQL Server aber dennoch nur die letzte offene Transaktion fest, auch wenn der Name der Transaktion angegeben wird. Wenn Sie <span class="emphasis">COMMIT WORK</span> verwenden, darf kein Transaktionsname und keine Variable, die einen Transaktionsnamen enth&auml;lt, angegeben werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn es um verschachtelte benannte Trigger geht, ist diese Syntax jedoch irref&uuml;hrend, weil damit die &auml;u&szlig;erste Transaktion geschlossen wird. Transaktionen in SQL Server werden numerisch durch die globale Variable <span class="emphasis">@@TRANCOUNT </span> identifiziert. Alle Transaktionen werden nur dann festgeschrieben, wenn <span class="emphasis">@@TRANCOUNT</span> = 0 ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>COMMIT [WORK];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle l&auml;sst keine speziell benannten Transaktionen zu (Savepoints sind allerdings erlaubt). Aus diesem Grunde werden mit dem Befehl <span class="emphasis">COMMIT</span> einfach alle Datenmanipulationsoperationen seit dem letzten impliziten oder expliziten <span class="emphasis">COMMIT</span> festgeschrieben. Oracle unterst&uuml;tzt das Schl&uuml;sselwort <span class="emphasis">WORK</span>, dieses ist jedoch vollkommen optional.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>COMMIT [WORK | TRANSACTION];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In PostgreSQL sind die beiden Schl&uuml;sselw&ouml;rter <span class="emphasis">WORK</span> und <span class="emphasis">TRANSACTION</span> optional. Die Wirkung des Befehls ist immer gleich, egal ob mit oder ohne die beiden Schl&uuml;sselw&ouml;rter. Nach der Ausf&uuml;hrung sind alle festgeschriebenen Transaktionen auf der Festplatte vorhanden und f&uuml;r andere Benutzer sichtbar.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>INSERT INTO sales VALUES('7896','JR3435','Oct 28
1997',25,'Net
60','BU7832');

COMMIT WORK;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="Verkettungsoperatoren">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">Verkettungsoperatoren</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Sollte es erforderlich sein, die Daten mehrerer Spalten in einer einzigen Spalte der Ergebnismenge von <span class="emphasis">SELECT</span> zusammenzufassen, kann dazu das vom jeweiligen DBMS unterst&uuml;tzte Verkettungssymbol verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT lname || ', ' || fname FROM customers WHERE cust_id = 41;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der ANSI-Standard f&uuml;r den Verkettungsoperator ist ein  doppelter senkrechter Strich ( <span class="literal">||</span> ), wie im vorherigen Codebeispiel zu sehen ist. Dieser wird von Oracle und PostgreSQL unterst&uuml;tzt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server verwendet ein  Pluszeichen ( + ) als Verkettungssymbol.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>MySQL verwendet die Funktion <span class="emphasis">CONCAT(string1, numeric1, string2, numeric2 [,...n])</span> zur Verkettung.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CONNECT">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CONNECT</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">CONNECT</span>

 wird eine Verbindung zum DBMS und zu einer bestimmten Datenbank innerhalb des DBMS aufgebaut.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Einschr&auml;nkungen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CONNECT [TO] DEFAULT
| {[server_specification] [AS connection_name] [USER user_name ] }</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn die Anweisung <span class="emphasis">CONNECT</span> aufgerufen wird, ohne dass die aktuelle Verbindung explizit geschlossen wurde, wird die alte Sitzung in den Ruhezustand versetzt und die neue Sitzung aktiv. Der Zeitraum zwischen der Ausf&uuml;hrung der Anweisungen <span class="emphasis">CONNECT</span> und <span class="emphasis">DISCONNECT</span> wird &uuml;blicherweise als <span class="emphasis">Sitzung</span> (oder Session) bezeichnet . In der Regel f&uuml;hrt der Benutzer alle Arbeiten an einem DBMS in einer explizit eingeleiteten Sitzung aus.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Das Oracle-Tool SQL*Plus verwendet den Befehl <span class="emphasis">CONNECT</span> in etwas anderer Form, und zwar wird der Benutzer mit einem bestimmten Schema verbunden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Ergebnisse der Anweisung <span class="emphasis">CONNECT TO DEFAULT</span> variieren von Hersteller zu Hersteller aufgrund der unterschiedlichen Implementierung. Laut Standard sollte mit diesem Befehl eine Standardsitzung mit dem Server begonnen werden, wobei sowohl f&uuml;r die Benutzerautorisierung als auch f&uuml;r die aktuelle Datenbank der Standardwert verwendet wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im Gegensatz zu <span class="emphasis">CONNECT TO DEFAULT</span> k&ouml;nnen Sie bei <span class="emphasis">CONNECT TO server_name</span> den Servernamen angeben. In diesem Fall wird die Verbindung zu dem explizit genannten Server aufgebaut. Dar&uuml;ber hinaus kann die Verbindung mit <span class="emphasis">AS</span> und ein Benutzer mit <span class="emphasis">USER</span> deklariert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CONN[ECT] [[username/password] [AS [SYSOPER | SYSDBA] ] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">CONNECT</span> kann eine Datenbankverbindung unter einem bestimmten Benutzernamen angegeben werden. Alternativ dazu k&ouml;nnen Sonderrechte mit <span class="emphasis">AS SYSOPER</span> oder <span class="emphasis">AS SYSDBA</span> angefordert werden. Wenn bereits eine andere Verbindung ge&ouml;ffnet ist, werden mit <span class="emphasis">CONNECT</span> alle offenen Transaktionen festgeschrieben, die aktuelle Sitzung wird geschlossen und die neue ge&ouml;ffnet.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL unterst&uuml;tzt den Befehl <span class="emphasis">CONNECT</span> nicht explizit. Es wird aber die Anweisung <span class="emphasis">SPI_CONNECT</span> im Server Programming Interface und <span class="emphasis">PG_CONNECT</span> im PG/tcl-Paket unterst&uuml;tzt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Um mit einer bestimmten Benutzer-ID eine Verbindung aufzubauen, k&ouml;nnte der Benutzer oder ein automatisiertes Programm folgenden Befehl verwenden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CONNECT TO USER pubs_admin</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn das DBMS benannte Verbindungen erfordert, k&ouml;nnte alternativ die folgende Syntax verwendet werden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CONNECT TO USER pubs_admin AS pubs_administrative_session;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt <span class="emphasis">CONNECT TO</span> nur in ESQL (Embedded SQL):</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>EXEC SQL CONNECT TO new_york.pubs USER pubs_admin</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CREATE DATABASE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CREATE DATABASE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>In SQL99 ist die Anweisung <span class="emphasis">CREATE DATABASE</span>

 nicht enthalten. Die SQL99-Anweisungen <span class="emphasis">CREATE SCHEMA</span> und <span class="emphasis">CREATE CATALOG</span> kommen der Anweisung <span class="emphasis">CREATE DATABASE</span> noch am n&auml;chsten. (<span class="emphasis">CREATE SCHEMA</span> wird weiter unten erl&auml;utert.) Es ist jedoch fast unm&ouml;glich, eine SQL-Datenbank ohne diesen Befehl zu betreiben. Fast alle Datenbankhersteller unterst&uuml;tzten daher irgendeine Version dieses Befehls.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE database_name</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In dieser Syntax ist <span class="emphasis">database_name</span> die ID der neu anzulegenden Datenbank. Mit diesem Befehl wird eine neue, leere Datenbank mit einem bestimmten Namen erstellt. Bei den meisten Herstellern muss der Benutzer in der Root-, Master- oder Systemdatenbank stehen, wenn er eine neue Datenbank erstellen m&ouml;chte. Sobald die neue Datenbank angelegt ist, kann sie mit Datenbankobjekten (Tabellen, Views, Trigger usw.) best&uuml;ckt werden. Anschlie&szlig;end werden die Tabellen mit Daten gef&uuml;llt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In SQL Server und Oracle wird die Datenbank in einer vorbereiteten Dateistruktur instanziiert. Diese Dateien diesen als Verbindungsst&uuml;cke zwischen dem Datenbanksystem und dem Betriebssystem. Aus diesem Grunde sind die SQL Server- und Oracle-Varianten von <span class="emphasis">CREATE DATABASE </span>um einiges komplexer.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Syntax f&uuml;r Microsoft SQL Server sieht folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE DATABASE database_name
[ ON [PRIMARY]
[ &lt;file&gt; [,...n] ]
[, &lt;file_group&gt; [,...n] ]
]
[ LOG ON { &lt;file&gt; [,...n]} ]
[ FOR LOAD | FOR ATTACH ]
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Bei dieser Implementierung kann nicht nur der Name der Datenbank angegeben werden, sondern auch der Ort, an dem die Datenbank gespeichert werden soll. Sowohl Oracle als auch SQL Server verwenden <span class="emphasis">Dateien</span> (vordefinierter Platz auf der Festplatte) als Repository f&uuml;r Datenbanken. Die Datenbanken k&ouml;nnen in einer oder mehreren Dateien oder Dateigruppen gespeichert werden. SQL Server bietet auch die M&ouml;glichkeit, die Transaktionsprotokolle mit Hilfe der Klausel <span class="emphasis">LOG ON</span> an einem anderen Ort zu speichern als die Datenbank. Diese Funktionen erm&ouml;glichen eine umfassende Planung im Hinblick auf den optimalen Festplattendurchsatz.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit den <span class="emphasis">FOR LOAD</span>-Klauseln wird festgelegt, dass die Datenbank unmittelbar nach der Erstellung aus einer Backup-Kopie geladen wird. Auf diese Weise wird der anf&auml;ngliche Erstellungsvorgang beschleunigt. Mit der Klausel <span class="emphasis">FOR ATTACH</span> wird SQL Server mitgeteilt, dass die Datenbank aus einer bestehenden Betriebssystem-Dateistruktur, wie zum Beispiel einer DVD-ROM, einer CD-ROM oder einer tragbaren Festplatte, angeh&auml;ngt wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL und PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In MySQL wird mit <span class="emphasis">CREATE DATABASE</span> im Wesentlichen ein neues Verzeichnis erzeugt, in dem die Datenbankobjekte abgelegt werden. Bei diesen beiden Herstellern ist somit das Anlegen einer Datenbank kaum schwieriger als das Anlegen eines Verzeichnisses im Dateisystem. Die Datenbank wird als Verzeichnis unter dem Hauptverzeichnis des Herstellers angelegt, und alle in der Datenbank neu erzeugten Objekte werden in diesem Verzeichnis abgelegt. PostgreSQL bietet dieselbe Funktionalit&auml;t, es besteht jedoch zus&auml;tzlich die M&ouml;glichkeit, den Speicherort der Datenbank mit der Option <span class="emphasis">WITH LOCATION</span> anzugeben:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE DATABASE name [ WITH LOCATION = 'dbpath' ];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So wird beispielsweise die Datenbank <span class="emphasis">sales_revenue</span> im Verzeichnis <span class="emphasis">/home/teddy/private_db</span> erstellt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE DATABASE sales_revenue WITH LOCATION = '/home/teddy/private_db';</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE DATABASE [database_name]
[CONTROLFILE REUSE]
[LOGFILE [GROUP1 integer] file1 integer [K | M] [,...n] [REUSE]]
   [MAXLOGFILES integer]
   [[MAXLOGMEMBERS] integer]
   [[MAXLOGHISTORY] integer]
[DATAFILE file1 [AUTOEXTEND [,...n] [ON | OFF]]
      [NEXT integer [K | M]]
      [MAXSIZE [UNLIMITED | integer [K | M]]
   [MAXDATAFILES integer]
   [,...n]]
[MAXINSTANCES integer]
[MAXDATAFILES integer]
[ARCHIVELOG | NOARCHIVELOG]
{CHARACTER SET charset}
{NATIONAL CHARACTER SET charset};</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">CREATE DATABASE</span> ist ein sehr m&auml;chtiger Befehl in Oracle und sollte daher nur von erfahrenen Datenbankadministratoren eingesetzt werden. Neulingen m&uuml;ssen sich im Klaren dar&uuml;ber sein, dass die bestehende Datenbank mit diesem Befehl zerst&ouml;rt werden kann.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Genau wie bei Microsoft SQL Server gehen auch bei Oracle die M&ouml;glichkeiten zur Steuerung der Datenbank-Dateistrukturen weit &uuml;ber das blo&szlig;e Benennen der Datenbank und das Festlegen eines Pfads f&uuml;r die Datenbankdateien hinaus. Oracle-spezifisch ist die Datei <span class="emphasis">INIT.ORA</span>, die den Namen der Datenbank sowie eine Vielzahl anderer Optionen f&uuml;r das Anlegen und Starten der Datenbank enth&auml;lt. Die Datei <span class="emphasis">INIT.ORA</span> muss immer verwendet werden und auf die Steuerdateien verweisen, sonst kann die Datenbank nicht gestartet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn die Option <span class="emphasis">the file1 [,...n]</span> zur Verf&uuml;gung steht, k&ouml;nnen der Dateiname und die Dateigr&ouml;&szlig;e (in Byte, Kilobyte oder Megabyte) angegeben werden. Das Format daf&uuml;r sieht folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>'file_path_and_name' SIZE bytes [K | M] REUSE</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Bei Angabe der Optionen <span class="emphasis">[K | M]</span> wird die Byte-Gr&ouml;&szlig;e der Datei mit 1024 bzw. 1048576 multipliziert. Die Option <span class="emphasis">REUSE</span> erstellt die Datei, wenn sie noch nicht existiert, und verwendet die alte Datei, wenn es sie schon gibt; bei Angabe der Option <span class="emphasis">CONTROLFILE REUSE</span> werden hingegen die Steuerdateien &uuml;berschrieben, genau wie bei <span class="emphasis">LOGFILE . . . REUSE</span> die Logdateien.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn eine Gruppe von Logdateien angegeben wird, stehen diese in der Regel in runden Klammern. Die Klammern sind nicht erforderlich, wenn eine Gruppe mit nur einem Element erzeugt wird; dies ist jedoch selten der Fall. Nachfolgend ein Beispiel f&uuml;r eine Liste von Logdateien in runden Klammern:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE DATABASE publications
LOGFILE ('/s01/oradata/loga01','/s01/oradata/loga02') SIZE 5M
DATAFILE</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Dar&uuml;ber hinaus erm&ouml;glichen die Optionen <span class="emphasis">LOGFILE</span> und <span class="emphasis">DATAFILE</span> und deren Unteroptionen die genaue Steuerung der Gr&ouml;&szlig;e und des Wachstumsverhaltens der Redo-Logs (Wiederholungsprotokolle) und Datenbankdateien. Mit <span class="emphasis">MAXLOGFILES</span> und <span class="emphasis">MAXDATAFILES</span> werden die Obergrenzen f&uuml;r die Redo-Logs bzw. die Datenbankdateien definiert. Wenn <span class="emphasis">AUTOEXTEND</span> aktiviert ist, w&auml;chst die Datendatei in Schritten von <span class="emphasis">NEXT</span>, bis <span class="emphasis">MAXSIZE</span> erreicht ist, es sei denn, sie ist auf <span class="emphasis">UNLIMITED</span> gesetzt. Mit <span class="emphasis">MAXLOGMEMBERS</span> wird gesteuert, wie viele Kopien einer Redo-Log-Gruppe angelegt werden d&uuml;rfen. <span class="emphasis">MAXLOGHISTORY</span> wird in Oracle Parallel Server verwendet und gibt die maximale Anzahl archivierter Redo-Logs an, damit in der Steuerdatei der richtige Platzverbrauch erfasst wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem Parameter <span class="emphasis">MAXINSTANCES</span> wird die maximale Anzahl von Instanzen festgelegt, die die gerade erstellte Datenbank mounten d&uuml;rfen. <span class="emphasis">ARCHIVELOG</span> | <span class="emphasis">NOARCHIVELOG</span> sind Optionen, die sich gegenseitig ausschlie&szlig;en und die Funktionsweise der Redo-Logs angeben. Mit <span class="emphasis">ARCHIVELOG</span> werden die Daten aus Gr&uuml;nden der Wiederherstellbarkeit in einer zus&auml;tzlichen Archivierungsdatei gesichert. Bei beiden Optionen ist eine Datenwiederherstellung m&ouml;glich, bei <span class="emphasis">NOARCHIVELOG</span>, dem Standard, normalerweise aber keine Wiederherstellung von Medien. <span class="emphasis">CHARACTER SET</span> h&auml;ngt vom Betriebssystem ab und legt die Sprache und den Zeichensatz f&uuml;r die Speicherung der Daten fest.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CREATE FUNCTION">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CREATE FUNCTION</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">CREATE FUNCTION</span>

 wird eine <span class="emphasis">benutzerdefinierte Funktion</span> (UDF) erzeugt, die Eingabeargumente erwartet und genau wie <span class="emphasis">CAST( )</span> einen einzelnen Wert zur&uuml;ckgibt. Eine UDF kann in einer Abfrage genau wie eine Systemfunktion verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Kapitel 4finden Sie eine vollst&auml;ndige Beschreibung der SQL-Funktionen und deren Implementierungen durch die einzelnen Hersteller.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">CREATE FUNCTION</span> k&ouml;nnen Datenbankprogrammierer benutzerdefinierte Funktionen schreiben. Diese Funktionen k&ouml;nnen dann in Abfragen und Datenmanipulationsoperationen wie <span class="emphasis">INSERT</span>, <span class="emphasis">UPDATE</span> und der <span class="emphasis">WHERE</span>-Klausel von <span class="emphasis">DELETE</span>-Anweisungen verwendet werden. Auch wenn die grundlegende Syntax f&uuml;r diese Anweisung bereits erl&auml;utert wurde, gibt es so viele herstellerspezifische Unterschiede im Hinblick auf die Implementierung, dass diese nachfolgend einzeln beschrieben werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE FUNCTION function_name
[(parameter datatype attributes [,...n])]
RETURNS datatype

  [LANGUAGE {ADA | C | FORTRAN | MUMPS | PASCAL | PLI | SQL}]
  [PARAMETER STYLE {SQL | GENERAL}]
  [SPECIFIC specific_name]
  [DETERMINISTIC | NOT DETERMINISTIC]
  [NO SQL | CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA]
  [RETURNS NULL ON NULL INPUT | CALL ON NULL INPUT]
  [STATIC DISPATCH]

code block</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der SQL99-Standard sieht f&uuml;r die Anweisung <span class="emphasis">CREATE FUNCTION</span> eine Hauptkomponente und eine weiterf&uuml;hrende Komponente vor, die allerdings seltener verwendet wird. In den meisten UDF definiert der Benutzer den Funktionsnamen, eventuelle Eingabeparameter und den Wert, den die UDF zur&uuml;ckgibt. So sieht auch die Grundform f&uuml;r die Verwendung dieses Befehls aus.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der SQL99-Standard bietet jedoch noch viel mehr. Mit der Klausel <span class="emphasis">LANGUAGE</span> kann die Sprache, in der die Funktion geschrieben wurde (z.&#160;B. PostgreSQL), angegeben werden. Mit der Klausel <span class="emphasis">PARAMETER STYLE</span> wird ein anderer Parameterstil als der typische SQL-Stil deklariert, und zwar &uuml;ber das Schl&uuml;sselwort <span class="emphasis">GENERAL</span>. (Der Standardwert ist SQL.) Mit der Deklaration <span class="emphasis">SPECIFIC</span> wird der Funktionsname in einem benutzerdefinierten Datentyp n&auml;her bestimmt. Die Klauseln <span class="emphasis">DETERMINISTIC</span> und <span class="emphasis">NOT DETERMINISTIC</span> teilen dem Host-DBMS mit, ob die Funktion bei gleichen Eingabeparametern immer dasselbe Ergebnis zur&uuml;ckgibt (= deterministisch) oder nicht. In Constraints d&uuml;rfen nur deterministische Funktionen verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der SQL-Datenzugriffsklausel wird dem Host-DBMS mitgeteilt, ob die Funktion keinen SQL-Code enth&auml;lt (<span class="emphasis">NO SQL</span>), SQL-Code enth&auml;lt (<span class="emphasis">CONTAINS SQL</span>), die Anweisung <span class="emphasis">SELECT</span> oder <span class="emphasis">FETCH</span> verwendet (<span class="emphasis">READS SQL DATA</span>) und ob datenmodifizierende Anweisungen eingesetzt werden (<span class="emphasis">MODIFIES SQL DATA</span>). Standard ist <span class="emphasis">CONTAINS SQL</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>F&uuml;r Hostsprachen, die Nullwerte nicht verarbeiten k&ouml;nnen, kann <span class="emphasis">RETURNS NULL ON NULL INPUT</span> deklariert werden. Die Funktion gibt dann unmittelbar einen Nullwert zur&uuml;ck, wenn eine Null &uuml;bergeben wird. Im Gegensatz dazu wird bei <span class="emphasis">CALL ON NULL INPUT</span>, dem Standard, der Nullparameter ganz normal mit m&ouml;glicherweise unbekannten Ergebnissen weiterverarbeitet.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">STATIC DISPATCH</span> ist f&uuml;r Nicht-SQL-Funktionen mit Parametern gedacht, die benutzerdefinierte Typen oder <span class="emphasis">ARRAYS</span> verwenden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE FUNCTION [owner_name.]function_name
( [ {@parameter1 datatype [=default]} [,...n] ] )
RETURNS {datatype | TABLE]
[WITH {ENCRYPTION | SCHEMABINDING}]
AS &lt;Transact-SQL body&gt;
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>
SQL Server-Funktionen k&ouml;nnen &uuml;ber den Datentyp <span class="emphasis">TABLE</span> mehrere Werte zur&uuml;ckgeben. Der Datentyp <span class="emphasis">TABLE</span> wird als <span class="emphasis">inline</span> betrachtet, wenn er &uuml;ber keine zugeh&ouml;rige Spaltenliste verf&uuml;gt und in einer einzigen <span class="emphasis">SELECT</span>-Anweisung definiert ist. Wenn die Klausel <span class="emphasis">RETURN</span> &uuml;ber den Datentyp <span class="emphasis">TABLE</span> mehrere Werte zur&uuml;ckgibt und wenn in <span class="emphasis">TABLE</span> Spalten und deren Datentypen definiert sind, handelt es sich um eine tabellenwertige Funktion vom Typ <span class="emphasis">Multistatement</span>, die mehrere Anweisungen enth&auml;lt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In SQL Server m&uuml;ssen ein oder mehrere vom Benutzer &uuml;bergebene Parameter f&uuml;r eine benutzerdefinierte Funktion deklariert werden. Alle SQL Server-Datentypen au&szlig;er <span class="emphasis">timestamp</span> k&ouml;nnen als Parameter verwendet werden. Von der Funktion k&ouml;nnen alle Datentypen mit Ausnahme von <span class="emphasis">timestamp</span>, <span class="emphasis">text</span>, <span class="emphasis">ntext</span> und <span class="emphasis">image</span> zur&uuml;ckgegeben werden. Wenn ein Inline-Tabellenwert erforderlich ist, kann die Option <span class="emphasis">TABLE</span> ohne zugeh&ouml;rige Spaltenliste verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Benutzerdefinierte Funktionen in Microsoft SQL k&ouml;nnen, wie viele andere Datenbankobjekte in SQL Server auch, mit den Optionen <span class="emphasis">ENCRYPTION</span> oder <span class="emphasis">SCHEMABINDING</span> erstellt werden. Mit der Option <span class="emphasis">ENCRYPTION</span> wird SQL Server aufgefordert, die Systemspaltentabelle, in der der Text der Funktion gespeichert ist, zu verschl&uuml;sseln. Auf diese Weise kann der Funktionscode nicht von Unbefugten eingesehen werden. Die Option <span class="emphasis">SCHEMABINDING</span> gibt an, dass die Funktion an ein bestimmtes Datenbankobjekt wie eine Tabelle oder einen View gebunden ist. Dieses Datenbankobjekt kann nicht ver&auml;ndert oder gel&ouml;scht werden, solange die Funktion existiert (bzw. die Option <span class="emphasis">SCHEMABINDING</span> verwendet wird).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der Coderumpf in Transact-SQL ist entweder eine einzelne <span class="emphasis">SELECT</span>-Anweisung im Format <span class="emphasis">RETURN (SELECT . . . )</span> bei Inline-Funktionen oder eine Reihe von Transact-SQL-Anweisungen bei Operationen, die aus mehreren Anweisungen bestehen. Der Transact-SQL-Rumpf in einem <span class="emphasis">BEGIN . . . END</span>-Block darf keine dauerhaften &Auml;nderungen an Daten vornehmen und auch sonst keine andauernden Nebeneffekte haben. Die letzte Anweisung im Block muss ein bedingungsloses <span class="emphasis">RETURN</span> sein, das einen einzelnen Datentyp-Wert oder <span class="emphasis">TABLE</span>-Wert zur&uuml;ckgibt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der Transact-SQL-Block darf keine globalen Variablen enthalten, deren Werte sich st&auml;ndig &auml;ndern, wie beispielsweise <span class="emphasis">@@CONNECTIONS</span> oder <span class="emphasis">GETDATE</span>. Erlaubt sind hingegen globale Variablen, deren Wert sich nicht ver&auml;ndert, wie etwa <span class="emphasis">@@SERVERNAME</span>. Es gibt noch eine Reihe anderer Einschr&auml;nkungen, da der Code weder dauerhafte &Auml;nderungen an Daten vornehmen oder sonstige andauernde Nebeneffekte haben darf. Aus diesem Grunde d&uuml;rfen <span class="emphasis">INSERT</span>-, <span class="emphasis">UPDATE</span>- und <span class="emphasis">DELETE</span>-Anweisungen nur die lokalen <span class="emphasis">TABLE</span>-Variablen &auml;ndern.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Nachfolgend ein Beispiel f&uuml;r eine Skalarfunktion, die einen einzelnen Wert zur&uuml;ckgibt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE FUNCTION metric_volume -- Input dimensions in centimeters.
   (@length decimal(4,1),
   @width decimal(4,1),
   @height decimal(4,1) )
RETURNS decimal(12,3) -- Cubic Centimeters.
AS BEGIN
      RETURN ( @length * @width * @height )
   END
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Diese benutzerdefinierte Funktion kann dann wie jede andere Funktion in einer Abfrage oder einer anderen Operation verwendet werden. So k&ouml;nnen zum Beispiel mit der folgenden Abfrage der Projektname und das Volumen aller Bauprojekte mit einem Volumen von mehr als 300.000 Kubikmetern ausgegeben werden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT project_name,
   metric_volume(construction_height,
      construction_length,
      construction_width)
FROM housing_construction
WHERE metric_volume(construction_height,
      construction_length,
      construction_width) &gt;= 300000
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Benutzerdefinierte Funktionen, die einen Tabellenwert zur&uuml;ckgeben, werden oftmals als Ergebnismengenwert ausgew&auml;hlt oder in der <span class="emphasis">FROM</span>-Klausel einer <span class="emphasis">SELECT</span>-Anweisung verwendet, genau wie eine ganz normale Tabelle. In einer <span class="emphasis">FROM</span>-Klausel kann wie bei einer normalen Tabelle eine Tabellenaliasfunktion zugewiesen werden. Dazu ein Beispiel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT co.order_id, co.order_price
FROM   construction_orders AS co,
       fn_construction_projects('Cancelled') AS fcp
WHERE  co.construction_id = fcp.construction_id
ORDER BY co.order_id
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [AGGREGATE] FUNCTION function_name
RETURNS {STRING | REAL | INTEGER}
SONAME shared_program_library_name ;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In MySQL werden mit <span class="emphasis">CREATE FUNCTION</span> benutzerdefinierte Funktionen wie <span class="emphasis">SUM( )</span> und <span class="emphasis">COUNT( )</span> mit Hilfe der Option <span class="emphasis">AGGREGATE</span> aggregiert. Der Typ des R&uuml;ckgabewertes kann entweder <span class="emphasis">STRING</span> f&uuml;r Zeichendaten, <span class="emphasis">REAL</span> f&uuml;r Flie&szlig;kommazahlen oder <span class="emphasis">INTEGER</span> f&uuml;r Ganzzahlen sein.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Implementierung von <span class="emphasis">CREATE FUNCTION</span> in MySQL unterscheidet sich erheblich von der anderer Hersteller, da der prozedurale Code in C/C++ geschrieben sein muss und vorausgesetzt wird, dass das Betriebssystem das dynamische Laden von Bibliotheken unterst&uuml;tzt. Das C/C++-Programm wird in der Option <span class="emphasis">shared_program_library_name</span> angegeben. Die Funktion kann entweder direkt in den MySQL-Server kompiliert werden und steht dann permanent zur Verf&uuml;gung, oder sie wird als dynamisch aufrufbares Programm verwendet. Da die benutzerdefinierten Funktionen in C/C++ geschrieben werden, w&uuml;rde eine ausf&uuml;hrliche Beschreibung dieser Implementierung &uuml;ber den Rahmen dieses Buches hinausgehen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [OR REPLACE] FUNCTION [owner_name.]function_name
[(parameter1 [IN | OUT | IN OUT] [NOCOPY] datatype][,...n)]]
RETURN datatype [DETERMINISTIC | AUTHID {CURRENT_USER | DEFINER} ]
  {IS | AS} {PL/SQL block | external program};</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle
sind benutzerdefinierte Funktionen und gespeicherte Prozeduren im Hinblick auf den Aufbau und die Struktur sehr &auml;hnlich. Der Hauptunterschied besteht darin, dass gespeicherte Prozeduren keinen Wert an den aufrufenden Prozess zur&uuml;ckgeben k&ouml;nnen, w&auml;hrend bei Funktionen ein einzelner Wert zur&uuml;ckgegeben werden kann.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle sind als Argumente und Parameter f&uuml;r benutzerdefinierte Funktionen u.&#160;a. <span class="emphasis">IN</span>, <span class="emphasis">OUT</span> und <span class="emphasis">IN OUT</span> zul&auml;ssig. Der Qualifier <span class="emphasis">IN</span> wird beim Aufruf der Funktion angegeben und gibt einen Wert an die Funktion zur&uuml;ck; <span class="emphasis">OUT</span>-Argumente geben einen Wert an den aufrufenden Prozess zur&uuml;ck. Mit anderen Worten, der Qualifier <span class="emphasis">IN</span> wird vom Benutzer oder von dem Prozess, der die Funktion aufruft, angegeben, w&auml;hrend das <span class="emphasis">OUT</span>-Argument von der Funktion zur&uuml;ckgegeben wird. <span class="emphasis">IN OUT</span> ist eine Kombination aus <span class="emphasis">IN</span> und <span class="emphasis">OUT</span>. Das Schl&uuml;sselwort <span class="emphasis">NOCOPY</span> wird verwendet, um die Leistung zu verbessern, wenn ein <span class="emphasis">OUT</span>- oder <span class="emphasis">IN OUT</span>-Argument sehr gro&szlig; ist, wie zum Beispiel ein Varray oder ein Datensatz.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem Schl&uuml;sselwort <span class="emphasis">RETURN</span> wird der Datentyp des von der Funktion zur&uuml;ckgegebenen Wertes festgelegt. Das Schl&uuml;sselwort <span class="emphasis">DETERMINISTIC</span> wird verwendet, um die Verarbeitung von Funktionen zu beschleunigen, die explizit als deterministisch deklariert wurden. Der gespeicherte R&uuml;ckgabewert kann von einem materialisierten View, einem anderen gleichzeitigen Aufruf derselben Funktion oder einem funktionsbasierten Index stammen. Mit <span class="emphasis">AUTHID CURRENT_USER</span> und <span class="emphasis">AUTHID DEFINER</span> kann dar&uuml;ber hinaus festgelegt werden, dass die Funktion im Zugriffsrechtekontext des aktuellen Benutzers oder des Benutzers, der die Funktion definiert hat, laufen soll.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So kann zum Beispiel der Gewinn eines Bauprojekts durch &Uuml;bergabe des Projektnamens in der folgenden Funktion ermittelt werden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE FUNCTION project_revenue (project IN varchar2)
RETURN NUMBER
AS
   proj_rev NUMBER(10,2);
BEGIN
   SELECT SUM(DECODE(action,'COMPLETED',amount,0)) -
          SUM(DECODE(action,'STARTED',amount,0))   +
          SUM(DECODE(action,'PAYMENT',amount,0))
   INTO proj_rev
   FROM construction_actions
   WHERE project_name = project;
   RETURN (proj_rev);
END;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In diesem Beispiel erwartet die benutzerdefinierte Funktion den Projektnamen als Argument. Anschlie&szlig;end wird im Hintergrund der Projektumsatz berechnet, indem die Anfangskosten von der Schlusszahlung abgezogen und eventuelle weitere Zahlungen hinzuaddiert werden. Die Zeile <span class="literal">RETURN(proj_rev);</span> gibt den Betrag an den aufrufenden Prozess zur&uuml;ck.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE FUNCTION name ( [ parameter1 [,...n] ] )
RETURNS datatype
AS {definition | object_file, link_symbol}
LANGUAGE {'C' | 'SQL' | 'PLPGSQL' | 'PLTCL' | 'PLTCLU' | 'PLPERL'
   | 'internal'}
[WITH ISCACHABLE];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die PostgreSQL-Variation von <span class="emphasis">CREATE FUNCTION</span> geh&ouml;rt zu den flexibelsten Implementierungen dieses Befehls. Wie bei den anderen Implementierungen werden <span class="emphasis">Parameter</span> &uuml;bergeben, die einen Wert eines bestimmten Datentyps zur&uuml;ckgeben. PostgreSQL erm&ouml;glicht dar&uuml;ber hinaus
das <span class="emphasis">&Uuml;berladen</span> von Funktionen, wobei derselbe Funktionsname f&uuml;r verschiedene Funktionen verwendet werden kann, solange die Eingabeparameter unterschiedlich sind.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem Datentypattribut <span class="emphasis">WITH ISCACHABLE</span> wird die Leistung von PostgreSQL optimiert, indem angegeben wird, dass die Funktion immer den gleichen Wert f&uuml;r die gleichen Eingabewerte zur&uuml;ckgibt. Mit dieser Einstellung kann der Optimierer den Funktionsaufruf dann schon im Vornherein auswerten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die <span class="emphasis">Definition</span> kann ein String sein, der die
Funktion definiert (in Abh&auml;ngigkeit von der Sprache, in der die Funktion geschrieben wurde), zum Beispiel ein interner Funktionsname, der Pfad und Name einer Objektdatei, eine SQL-Abfrage oder der Text einer prozeduralen Sprache. Die Definition kann auch eine <span class="emphasis">Objektdatei</span> oder ein <span class="emphasis">Verkn&uuml;pfungssymbol</span> einer in C geschriebenen Funktion sein.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Nachfolgend ein Beispiel f&uuml;r eine einfache SQL-Funktion in PostgreSQL:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE FUNCTION max_project_nbr
RETURNS int4
AS "SELECT MAX(project_ID) FROM housing_construction AS RESULT"
LANGUAGE 'sql';</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL verwendet <span class="emphasis">CREATE FUNCTION</span> als Ersatz f&uuml;r <span class="emphasis">CREATE PROCEDURE</span>sowie zum Definieren von Aktionen f&uuml;r <span class="emphasis">CREATE TRIGGER</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem Schl&uuml;sselwort <span class="emphasis">LANGUAGE</span> kann die PostgreSQL-Funktion ein externes Programm aufrufen. Da es sich dabei um Programme handelt, die in anderen Sprachen geschrieben wurden, w&uuml;rde eine detaillierte Beschreibung an dieser Stelle zu weit f&uuml;hren. Die Klausel <span class="emphasis">LANGUAGE 'sql'</span> sollten Sie aber auf jeden Fall verwenden, wenn Sie benutzerdefinierte Funktionen in SQL schreiben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CREATE INDEX">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CREATE INDEX</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>

Indizes sind spezielle Objekte, die auf Tabellen aufsetzen und viele Datenmanipulationsoperationen wie <span class="emphasis">SELECT</span>-, <span class="emphasis">UPDATE</span>- und <span class="emphasis">DELETE</span>-Anweisungen beschleunigen. Bei Erstellung eines Index wird die Position und Verteilung der Werte ("Statistik" genannt) f&uuml;r die indizierte Spalte berechnet. Wie selektiv eine <span class="emphasis">WHERE</span>-Klausel ist, h&auml;ngt in der Regel von der Qualit&auml;t der Indizes f&uuml;r die betreffende Tabelle ab.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der Befehl <span class="emphasis">CREATE INDEX</span> ist von Hersteller zu Hersteller verschieden. Dies ist unter anderem darauf zur&uuml;ckzuf&uuml;hren, dass bei manchen DBMS der Befehl <span class="emphasis">CREATE INDEX</span> bestimmt, wie die Daten in einer indizierten Tabelle physisch sortiert und auf der Festplatte gespeichert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE INDEX index_name ON table_name (column_name [, ...n])</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Alle wichtigen Hersteller unterst&uuml;tzen <span class="emphasis">zusammengesetzte Indizes</span>,auch <span class="emphasis">verkettete Indizes</span> genannt. Diese Indizes werden verwendet, wenn zwei oder mehrere Spalten sinnvollerweise als Einheit zu durchsuchen sind, beispielsweise Nachname und Vorname.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX <span class="replaceable">index_name</span>
ON {<span class="replaceable">table | view}</span> <span class="replaceable">(column [ASC | DESC]</span> [,...n])
[WITH [PAD_INDEX]
   [[,] FILLFACTOR = fillfactor]
   [[,] IGNORE_DUP_KEY]
   [[,] DROP_EXISTING]
   [[,] STATISTICS_NORECOMPUTE] ]
[ON filegroup]
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server kennt einige wichtige Optionen. Zum Beispiel k&ouml;nnen aufsteigende oder absteigende Indizes f&uuml;r Tabellen sowie Indizes f&uuml;r Views und berechnete Spalten (wie <span class="emphasis">UPPER(book_name)</span> oder <span class="emphasis">((qty * amt) / royalty)</span>) erstellt werden. SQL Server unterst&uuml;tzt dar&uuml;ber hinaus noch weitere optionale Argumente: <span class="emphasis">UNIQUE</span>, <span class="emphasis">CLUSTERED</span> und <span class="emphasis">NONCLUSTERED</span> (Standard). <span class="emphasis">Bei eindeutigen Indizes</span> darf es in den indizierten Spalten keine identischen Werte geben. Jeder Versuch, einen Wert so einzuf&uuml;gen oder zu ver&auml;ndern, dass es zu einer Duplikation im Index kommt, w&uuml;rde einen Fehler ausl&ouml;sen. <span class="emphasis">Geclusterte Indizes</span> geben die physische Sortierreihenfolge der Daten auf der Festplatte an. <span class="emphasis">Nicht-geclustere Indizes</span> sorgen f&uuml;r eine logische Tabellensortierung, wodurch Datenmanipulationsoperationen beschleunigt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Weitere Syntax-Merkmale in SQL Server:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ol><li><span class="emphasis">PAD_INDEX</span> gibt an, dass auf jeder Indexdatenseite ein bestimmter Platz entsprechend der Einstellung <span class="emphasis">FILLFACTOR</span> freigelassen werden soll.</li><li><span class="emphasis">FILLFACTOR</span> ist ein Prozentwert (zwischen 1 und 100), der SQL Server mitteilt, welcher Teil einer 8&#160;KB gro&szlig;en Datenseite bei der Indexerstellung gef&uuml;llt werden soll. Dies ist n&uuml;tzlich, um das Aufbrechen von Seiten zu vermeiden, wenn eine 8&#160;KB gro&szlig;e Datenseite voll wird, und um I/O-intensive Festplattenoperationen auf ein Minimum zu reduzieren. Durch Erstellung eines geclusterten Index mit explizit definiertem F&uuml;llfaktor l&auml;sst sich u.&#160;U. der Index vergr&ouml;&szlig;ern und die Verarbeitung beschleunigen.</li><li>Mit <span class="emphasis">IGNORE_DUP_KEY</span> wird festgelegt, was passiert, wenn ein doppelter Datensatz im Zuge einer Einf&uuml;gungs- oder Aktualisierungsoperation in einen eindeutigen Index gelangt. Wenn dieser Wert f&uuml;r eine Spalte gesetzt ist, wird nur die doppelte Zeile von der Operation ausgeschlossen. Ist der Wert nicht gesetzt, werden alle betroffenen Datens&auml;tze (auch die nicht duplizierten) zur&uuml;ckgef&uuml;hrt.</li><li><span class="emphasis">DROP_EXISTING</span> ist ein n&uuml;tzliches Merkmal, mit dem SQL Server aufgefordert werden kann, bereits bestehende Indizes zu l&ouml;schen und den angegebenen Index neu anzulegen.</li><li>Mit <span class="emphasis">STATISTICS_NORECOMPUTE</span> wird SQL Server daran gehindert, die Indexstatistiken neu zu berechnen. Auf diese Weise kann die <span class="emphasis">CREATE INDEX</span>-Operation beschleunigt werden, was den Index jedoch weniger n&uuml;tzlich macht.</li><li>Mit <span class="emphasis">ON filegroup</span> wird ein Index in einer bereits vorhandenen Dateigruppe erzeugt. Auf diese Weise k&ouml;nnen Indizes auf eine bestimmte Festplatte oder ein RAID-Ger&auml;t gelegt werden.</li></ol>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Zur Erstellung eines Index ist in der Regel 1,2 bis 1,5 Mal mehr
Platz erforderlich als die Tabelle derzeit belegt. Der gr&ouml;&szlig;te Teil des Plattenspeichers wird wieder freigegeben, sobald der Index erstellt ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [UNIQUE] INDEX index_name ON table_name (column_name(length) [,...n])</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>MySQL unterst&uuml;tzt den grundlegenden ANSI-Standard f&uuml;r die Anweisung <span class="emphasis">CREATE INDEX</span>, einschlie&szlig;lich der M&ouml;glichkeit, einen
Index auf mehreren Spalten zu erstellen. Ein Index kann au&szlig;erdem als <span class="emphasis">UNIQUE</span> definiert werden, was bedeutet, dass dieser Index nur eindeutige Werte akzeptiert. Wird versucht, einen nichteindeutigen Wert in eine Tabelle mit einem Index vom Typ <span class="emphasis">UNIQUE</span> einzuf&uuml;gen, tritt ein Fehler auf.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Interessanterweise bietet MySQL auch die M&ouml;glichkeit, einen Index auf die ersten <span class="emphasis">(length)</span> Zeichen einer <span class="emphasis">CHAR</span>- oder <span class="emphasis">VARCHAR</span>-Spalte zu erstellen. Dies kann n&uuml;tzlich sein, wenn zum Beispiel die ersten 10 Zeichen einer Spalte aussagekr&auml;ftig genug sind, oder wenn der Festplattenplatz knapp ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [UNIQUE | BITMAP] INDEX [owner_name.]index_name
ON [schema.]{table ({column | expression} [ASC | DESC] [,...n])
   | CLUSTER cluster_name}
[physical_attributes_clause | {LOGGING | NOLOGGING} |
  | [ONLINE] | [COMPUTE [STATISTICS] ]
  | {TABLESPACE tablespace_name | DEFAULT}
  | {COMPRESS int | NOCOMPRESS}
  | {NOSORT |REVERSE} ],...
 [GLOBAL PARTITION BY RANGE (column_list)
   (PARTITION [partition_name] VALUES LESS THAN (value_list)
   [physical_attributes_clause | {LOGGING | NOLOGGING} ] ,...n )
| LOCAL [ (PARTITION [partition_name]
   [physical_attributes_clause | {LOGGING | NOLOGGING} ] ,...n ) ] ]
[PARALLEL [int] | NOPARALLEL]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle erm&ouml;glicht die Erstellung von Indizes, die nicht nur auf Spaltenwerten basieren, sondern auch auf berechneten Ausdr&uuml;cken wie <span class="emphasis">UPPER(book_name)</span> oder <span class="emphasis">((qty * amt) / royalty)</span>. Indizes k&ouml;nnen <span class="emphasis">UNIQUE</span> oder nichteindeutig sein. In Oracle k&ouml;nnen auch
 <span class="emphasis">BITMAP</span>-Indizes erzeugt werden, was n&uuml;tzlich ist bei Spalten mit nur wenigen unterschiedlichen Werten. Dar&uuml;ber hinaus k&ouml;nnen in Oracle sowohl aufsteigende (<span class="emphasis">ASC</span>) als auch absteigende (<span class="emphasis">DESC</span>) Indizes angelegt werden. Beachten Sie aber, dass Oracle <span class="emphasis">DESC</span>-Indizes wie funktionsbasierte Indizes behandelt. Es gibt einen funktionalit&auml;tsbezogenen Unterschied zwischen
<span class="emphasis">ASC</span>-Indizes und <span class="emphasis">DESC</span>-Indizes. Ein Cluster-Schl&uuml;ssel f&uuml;r den Index kann mit der Option <span class="emphasis">CLUSTER</span> ebenfalls angegeben werden. (Cluster werden mit dem Oracle-spezifischen Befehl <span class="emphasis">CREATE CLUSTER</span> erstellt. )</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle und SQL Server unterscheiden sich erheblich in ihren Definitionen eines geclusterten Index. In SQL Server gibt ein <span class="emphasis">geclusterter Index</span>
 die physische Sortierreihenfolge der Daten in der Tabelle an. In Oracle ist ein <span class="emphasis">Cluster</span> ein spezieller Index zwischen zwei oder mehr Tabellen, mit dem sich Join-Operationen erheblich beschleunigen lassen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">physical_attributes_clause</span> bezieht sich auf die folgenden Einstellungen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>[ PCTFREE int
| PCTUSED int
| INITRANS int
| MAXTRANS int
| STORAGE storage...]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">PCTFREE</span> ist vergleichbar mit <span class="emphasis">FILLFACTOR</span> in SQL Server und gibt in Prozent den Platz an, der f&uuml;r neue Eintr&auml;ge und Aktualisierungen freigelassen werden muss. <span class="emphasis">PCTFREE</span> kann nur f&uuml;r Indizes verwendet werden, die nicht <span class="emphasis">UNIQUE</span> sind. <span class="emphasis">PCTUSED</span> gibt in Prozent den Platz an, der in einem Block zur Verf&uuml;gung stehen muss, damit Oracle Einf&uuml;gungen in diesem Block zul&auml;sst. <span class="emphasis">PCTUSED</span> kann f&uuml;r Tabellen, aber nicht f&uuml;r Indizes verwendet werden. Erl&auml;uterungen zu <span class="emphasis">STORAGE</span>, <span class="emphasis">INITRANS</span> und <span class="emphasis">MAXTRANS</span> finden Sie unter der Anweisung <span class="emphasis">CREATE TABLE</span> in Abschnitt .</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">TABLESPACE</span> wird der Index einem bestimmten Tablespace zugewiesen. Wenn diese Klausel weggelassen wird, befindet sich der Index im Standard-Tablespace; dasselbe erreichen Sie auch mit dem Schl&uuml;sselwort <span class="emphasis">DEFAULT</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">LOGGING</span> wird Oracle angewiesen, die Erstellung eines Index in einer Redo-Log-Datei zu erfassen. Mit <span class="emphasis">NOLOGGING</span> hingegen wird eine solche Erfassung verhindert. Dieses Schl&uuml;sselwort legt auch das Standardverhalten f&uuml;r nachfolgendes Bulk-Loading mit dem Oracle Direct Loader fest. Im Zusammenhang mit dem Aufbau von Indexpartitionen gibt es noch einige Besonderheiten bei diesen Schl&uuml;sselw&ouml;rtern. Vor deren Anwendung sollten Sie sich daher in der Dokumentation des Herstellers informieren.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">ONLINE</span> wird Oracle mitgeteilt, dass w&auml;hrend der Erstellung des Index Datenmanipulationen zul&auml;ssig sind. Mit dem Befehl <span class="emphasis">COMPUTE STATISTICS</span> werden w&auml;hrend der Erstellung des Index Statistiken gesammelt, was relativ unaufw&auml;ndig ist.<span class="emphasis"> COMPRESS</span> aktiviert die Komprimierung von Schl&uuml;sseln in nichtpartitionierten Indizes. Daf&uuml;r wird weniger Platz ben&ouml;tigt, weil mehrfach auftretende Schl&uuml;sselwerte eliminiert werden. Der Integer in <span class="emphasis">COMPRESS</span> gibt an, wie viele Pr&auml;fixspalten komprimiert werden sollen. Mit <span class="emphasis">NOCOMPRESS</span>, dem Standard, wird die Komprimierung deaktiviert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle erm&ouml;glicht die Erstellung von


partitionierten Indizes und Tabellen mit Hilfe der Klausel <span class="emphasis">PARTITION</span>. Deshalb unterst&uuml;tzen Oracle-Indizes auch partitionierte Tabellen. Mit der Klausel <span class="emphasis">LOCAL</span> wird Oracle angewiesen, f&uuml;r jede Partition einer Tabelle einen eigenen Index zu erstellen. Mit der Klausel <span class="emphasis">GLOBAL</span> wird ein gemeinsamer Index f&uuml;r alle Partitionen erzeugt, wobei sich bestimmte Indexwertebereiche von den auf den Partitionen gespeicherten Wertebereichen unterscheiden k&ouml;nnen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Option<span class="emphasis">NOSORT</span> l&auml;sst sich schnell ein Index f&uuml;r eine Spalte erstellen, die bereits in aufsteigender Reihenfolge sortiert ist. Wenn die Werte der Spalte nicht perfekt aufsteigend sortiert sind, wird die Operation abgebrochen und kann ohne die Option <span class="emphasis">NOSORT</span>Option noch einmal versucht werden. Mit <span class="emphasis">REVERSE</span> werden dagegen die Indexbl&ouml;cke in umgekehrter Reihenfolge auf dem Speichermedium abgelegt; die Zeilensortierung ist davon jedoch nicht betroffen. <span class="emphasis">REVERSE</span> und <span class="emphasis">NOSORT</span> schlie&szlig;en sich gegenseitig aus. <span class="emphasis">REVERSE</span> kann nicht bei einem Bitmap-Index oder einer indexorganisierten Tabelle verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">PARALLEL</span> kann die Erstellung des Index auf mehrere CPUs verteilt und somit beschleunigt werden. Ein optionaler Integerwert gibt an, wie viele parallele Threads dabei zu verwenden sind. Mit <span class="emphasis">NOPARALLEL</span>, dem Standard, wird der Index seriell erzeugt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [UNIQUE] INDEX index_name ON table
[USING [BTREE | RTREE | HASH] ]
(function_name (column [operator_class] [, ...] ))</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In PostgreSQL k&ouml;nnen normale Indizes in aufsteigender Reihenfolge  wie auch <span class="emphasis">UNIQUE</span>-Indizes
 erstellt werden. Dar&uuml;ber hinaus erm&ouml;glicht die Implementierung mit der Klausel <span class="emphasis">WITH access_method</span> auch die Steigerung der Performanz. Mit Hilfe dieser Klausel kann eine von drei dynamischen Zugriffsmethoden zur Leistungsoptimierung angegeben werden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ul><li><i><span class="emphasis">BTREE</span></i><br>&#160;
						  Dies ist die Standardmethode, wenn nichts anderes angegeben ist. Sie beruht auf den Mehrweg-B-B&auml;umen nach Lehman/Yao.</li><li><i><span class="emphasis">RTREE</span></i><br>&#160;
						  Diese Methode verwendet normale R-B&auml;ume mit dem Split-Algorithmus mit quadratischem Aufwand nach Guttman.</li><li><i><span class="emphasis">HASH</span></i><br>&#160;
						  Diese Methode ist eine Implementierung des linearen Hashing von Litwin.</li></ul>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In PostgreSQL kann Spalten auch eine <span class="emphasis">Operatorklasse</span> zugewiesen werden, die sich nach dem Datentyp der Spalte richtet. Eine Operatorklasse gibt die Operatoren f&uuml;r einen bestimmten Index an. Der Benutzer kann zwar eine beliebige zul&auml;ssige Operatorklasse f&uuml;r eine Spalte definieren, aber die Standard-Operatorklasse ist die f&uuml;r den jeweiligen Feldtyp passendste.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In PostgreSQL haben Sie auch die M&ouml;glichkeit, einen Index f&uuml;r eine Funktion, eine benutzerdefinierte Funktion oder einen Ausdruck zu definieren. So kann zum Beispiel ein Index f&uuml;r <span class="emphasis">UPPER(book_name)</span> definiert werden, um eine Transformationsoperation zu beschleunigen, die regelm&auml;&szlig;ig mit den Daten, die dem Index zugrunde liegen, durchgef&uuml;hrt wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In diesem Beispiel aus MySQL wird ein einfacher aufsteigender Index f&uuml;r die Spalte <span class="emphasis">au_id</span> der Tabelle <span class="emphasis">authors</span> erstellt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE INDEX au_id_ind
ON authors (au_id);</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im Beispiel unten wird eine Tabelle mit dem Namen <span class="emphasis">housing_construction</span> erstellt (wie auch bei der Beschreibung von <span class="emphasis">CREATE FUNCTION</span> verwendet) und auf dieser ein geclusterter Index angelegt. Dieser Index sortiert die Daten physisch auf der Festplatte, da die Klausel <span class="emphasis">CLUSTERED</span> angegeben ist:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TABLE housing_construction
   (project_number      INT NOT NULL,
   project_date         DATETIME NULL,
   project_name         VARCHAR(50)
       COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
   construction_color   NCHAR(20)
       COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
   construction_height  DECIMAL(4, 1) NULL ,
   construction_length  DECIMAL(4, 1) NULL ,
   construction_width   DECIMAL(4, 1) NULL ,
   construction_volume  INT NULL
GO

CREATE UNIQUE CLUSTERED INDEX project_id_ind
ON housing_construction(project_id)
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oftmals braucht man Indizes, die mehrere Spalten abdecken, d.&#160;h. einen <span class="emphasis">zusammengesetzten Schl&uuml;ssel</span>. Dazu ein Beispiel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE UNIQUE INDEX project2_ind
ON housing_construction(project_name, project_date)
WITH PAD_INDEX, FILLFACTOR = 80
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Durch Hinzuf&uuml;gen der Klausel <span class="emphasis">PAD_INDEX</span> und durch Setzen des <span class="emphasis">FILLFACTOR</span> auf 80 wird SQL Server angewiesen, die Index- und Datenseiten nur zu 80&#160;% und nicht zu 100&#160;% zu f&uuml;llen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel wird derselbe Index in Oracle erzeugt, und zwar in einem bestimmten Tablespace zusammen mit Anweisungen, wie die Daten gespeichert werden sollen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE UNIQUE INDEX project2_ind
ON housing_construction(project_name, project_date)
STORAGE (INITIAL 10M NEXT 5M PCTINCREASE 0)
TABLESPACE construction;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn die Tabelle <span class="emphasis">housing_construction</span> als partitionierte Tabelle auf einem Oracle-Server erstellt wird, sollte auch ein partitionierter Index angelegt werden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE UNIQUE CLUSTERED INDEX project_id_ind
ON housing_construction(project_id)
GLOBAL PARTITION BY RANGE (project_id)
   (PARTITION part1 VALUES LESS THAN ('K')
      TABLESPACE construction_part1_ndx_ts,
   PARTITION part2 VALUES LESS THAN (MAXVALUE)
      TABLESPACE construction_part2_ndx_ts);</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CREATE PROCEDURE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CREATE PROCEDURE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>

Gespeicherte Prozeduren erm&ouml;glichen bedingte Verarbeitungs- und Programmierm&ouml;glichkeiten in der Datenbankserver-Umgebung. Gespeicherte Prozeduren sind in sich geschlossene Codest&uuml;cke, die &uuml;bergebene Parameter annehmen und komplizierte Aufgaben ausf&uuml;hren k&ouml;nnen. Gespeicherte Prozeduren sind au&szlig;erdem sehr n&uuml;tzlich, weil sie vorkompiliert sind: Sie f&uuml;hren die Aufgaben schnell und effizient aus, weil der Datenbankoptimierer bereits einen Ausf&uuml;hrungsplan f&uuml;r den Code hat.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt (siehe Befehl CREATE FUNCTION)</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wie bei vielen anderen <span class="emphasis">CREATE</span>-Anweisungen auch gibt es gro&szlig;e herstellerspezifische Unterschiede.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE PROCEDURE procedure_name
[parameter data_type attributes ][,...n]
AS
code block</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Eine umfassendere Beschreibung der SQL99-Syntax finden Sie unter <span class="emphasis">CREATE FUNCTION</span>. Die erweiterten M&ouml;glichkeiten von <span class="emphasis">CREATE FUNCTION</span> gelten auch f&uuml;r <span class="emphasis">CREATE PROCEDURE</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Weil jeder Hersteller eigene prozedurale Erweiterungen der SQL-Sprache implementiert hat, w&uuml;rde eine ausf&uuml;hrliche Beschreibung zur Programmierung von gespeicherten Prozeduren hier zu weit f&uuml;hren. Die Grundlagen der Programmierung von gespeicherten Prozeduren werden jedoch besprochen. Andere B&uuml;cher von O'Reilly wie <span class="emphasis">Transact-SQL Programming </span>von Kevin Kline, Lee Gould und Andrew Zanevsky (1999) und <span class="emphasis">Oracle PL/SQL Programming, Second Edition</span> von Steven Feuerstein und Bill Pribyl (1997) sind hervorragende Informationsquellen f&uuml;r die jeweiligen Programmiersprachen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE PROC[EDURE] <span class="replaceable">procedure_name </span>[;<span class="replaceable">number</span>]
[{@<span class="replaceable">parameter_name datatype</span>}<span class="replaceable"> </span>[VARYING] [= <span class="replaceable">default</span>] [OUTPUT]][,...<span class="replaceable">n</span>]
[WITH {RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}]
[FOR REPLICATION]
AS
Transact-SQL_block
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Neben dem Prozedurnamen k&ouml;nnen Sie in Microsoft SQL Server auch eine Versionsnummer im Format <span class="emphasis">procedure_name;1,</span> angeben, wobei 1 ein Ganzzahlwert ist, der die Versionsnummer angibt. Dies erm&ouml;glicht den Zugriff auf mehrere Versionen einer einzigen gespeicherten Prozedur.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wie bei Tabellen (siehe CREATE TABLE) k&ouml;nnen auch hier lokale und globale tempor&auml;re Prozeduren deklariert werden, indem dem Namen der Prozedur ein
Nummernzeichen (#) und   doppeltes Nummernzeichen (##) vorangestellt wird. Tempor&auml;re Prozeduren bestehen nur w&auml;hrend der Benutzer- oder Prozesssitzung, in der sie erzeugt wurden. Wenn die Sitzung endet, l&ouml;scht sich die tempor&auml;re Prozedur automatisch selbst.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Eine gespeicherte Prozedur in SQL Server kann bis zu 1024 Eingabeparameter haben, die mit einem at-Zeichen   (@) und einem beliebigen zul&auml;ssigen SQL Server-Datentyp gekennzeichnet werden. (Parameter vom Datentyp "Cursor" m&uuml;ssen sowohl auf <span class="emphasis">VARYING</span> als auch auf <span class="emphasis">OUTPUT</span> gesetzt sein.) Das Schl&uuml;sselwort <span class="emphasis">VARYING </span> wird nur bei Parametern vom Datentyp "Cursor" verwendet, um anzugeben, dass die Ergebnismenge von der Prozedur dynamisch aufgebaut wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Werte der Eingabeparameter m&uuml;ssen vom Benutzer oder dem aufrufenden Prozess &uuml;bergeben werden. Es kann aber auch ein Standardwert angegeben werden, damit die Prozedur ohne einen vom Benutzer oder aufrufenden Prozess angegebenen Wert ausgef&uuml;hrt werden kann. Der Standardwert muss eine Konstante oder NULL sein, kann aber Wildcard-Zeichen enthalten, die unter <span class="emphasis">LIKE</span> besprochen werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In &auml;hnlicher Weise kann ein Parameter mit dem Schl&uuml;sselwort <span class="emphasis">OUTPUT</span> als R&uuml;ckgabeparameter deklariert werden. Der im R&uuml;ckgabeparameter gespeicherte Wert wird &uuml;ber die R&uuml;ckgabevariablen des SQL-Server-Befehls <span class="emphasis">EXEC[UTE]</span> an die aufrufende Prozedur zur&uuml;ckgegeben. R&uuml;ckgabeparameter k&ouml;nnen jeden beliebigen Datentyp au&szlig;er <span class="emphasis">TEXT</span> und <span class="emphasis">IMAGE</span> annehmen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Optionen <span class="emphasis">WITH RECOMPILE</span>, <span class="emphasis">WITH ENCRYPTION</span> und <span class="emphasis">WITH RECOMPILE, ENCRYPTION</span> haben folgende Bedeutungen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ul><li><i>WITH RECOMPILE </i><br>&#160;
						  Teilt SQL Server mit, keinen Cacheplan f&uuml;r die gespeicherte Prozedur zu speichern, sondern statt dessen den Cacheplan bei jeder Ausf&uuml;hrung neu zu berechnen. Dies ist n&uuml;tzlich, wenn atypische oder tempor&auml;re Werte in der Prozedur verwendet werden.</li><li><i>WITH ENCRYPTION </i><br>&#160;
						  Verschl&uuml;sselt den Code der gespeicherten Prozedur in der <span class="emphasis">syscomments</span>-Tabelle von SQL Server.</li><li><i>WITH RECOMPILE, ENCRYPTION</i><br>&#160;
						  Erlaubt beide Optionen auf einmal.</li></ul>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">FOR REPLICATION</span>, die nicht zusammen mit der Klausel <span class="emphasis">WITH RECOMPILE</span> verwendet werden kann, wird die Ausf&uuml;hrung der gespeicherten Prozedur auf einem abonnierenden Server deaktiviert. Sie wird haupts&auml;chlich dazu verwendet, eine Filterprozedur zu schreiben, die nur von der eingebauten Replikationsengine in SQL Server ausgef&uuml;hrt wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">AS Transact-SQL_block</span> enth&auml;lt einen oder mehrere Transact-SQL-Befehle bis zu einer maximalen Gr&ouml;&szlig;e von 128&#160;MB. Microsoft SQL Server unterst&uuml;tzt die meisten zul&auml;ssigen Transact-SQL-Anweisungen, nicht aber <span class="emphasis">SET SHOWPLAN_TEXT</span> und <span class="emphasis">SET SHOWPLAN_ALL</span>. Einige andere Befehle k&ouml;nnen in gespeicherten Prozeduren nur eingeschr&auml;nkt verwendet werden. Dazu geh&ouml;ren <span class="emphasis">ALTER TABLE</span>, <span class="emphasis">CREATE INDEX</span>, <span class="emphasis">CREATE TABLE</span>, alle <span class="emphasis">DBCC</span>-Anweisungen, <span class="emphasis">DROP TABLE</span>, <span class="emphasis">DROP INDEX</span>, <span class="emphasis">TRUNCATE TABLE</span> und <span class="emphasis">UPDATE STATISTICS</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>SQL Server unterst&uuml;tzt  die verz&ouml;gerte Namensaufl&ouml;sung, was bedeutet, dass die gespeicherte Prozedur auch dann fehlerfrei kompiliert wird, wenn sie ein noch nicht erzeugtes Objekt referenziert. Sie erzeugt einen Ausf&uuml;hrungsplan und schl&auml;gt nur fehl, wenn das Objekt dann immer noch nicht existiert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Gespeicherte Prozeduren k&ouml;nnen in SQL Server leicht verschachtelt werden. Immer wenn eine gespeicherte Prozedur eine andere gespeicherte Prozedur aufruft, wird die Systemvariable <span class="emphasis">@@NESTLEVEL</span> um 1 erh&ouml;ht. Wenn die aufgerufene Prozedur beendet ist, wird die Variable wieder um 1 verringert. Mit <span class="emphasis">SELECT @@NESTLEVEL</span> l&auml;sst sich herausfinden, wie viele Verschachtelungsebenen in der aktuellen Sitzung auftreten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [OR REPLACE] PROCEDURE [owner_name.]procedure_name
[(parameter1 [IN | OUT | IN OUT] [NOCOPY] datatype][,...n)]]
[AUTHID {CURRENT_USER | DEFINER} ]
{IS | AS} {PL/SQL block | LANGUAGE {java_spec | C_spec}};</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle
sind benutzerdefinierte Funktionen und gespeicherte Prozeduren im Hinblick auf den Aufbau und die Struktur sehr &auml;hnlich. Der Hauptunterschied besteht darin, dass gespeicherte Prozeduren keinen Wert an den aufrufenden Prozess zur&uuml;ckgeben k&ouml;nnen, w&auml;hrend bei Funktionen ein einzelner Wert zur&uuml;ckgegeben werden kann.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In einer gespeicherten Prozedur in Oracle werden die Argumente und Parameter jemals mit <span class="emphasis">IN</span>, <span class="emphasis">OUT</span> und <span class="emphasis">IN OUT</span> gekennzeichnet. <span class="emphasis">IN</span> wird verwendet, wenn ein Wert an die Prozedur &uuml;bergeben wird, <span class="emphasis">OUT</span>, wenn ein Wert an den aufrufenden Prozess zur&uuml;ckgegeben wird. Mit anderen Worten, der Qualifier <span class="emphasis">IN</span> wird vom Benutzer oder von dem Prozess, der die Funktion aufruft, angegeben, w&auml;hrend das <span class="emphasis">OUT</span>-Argument von der Funktion zur&uuml;ckgegeben wird. <span class="emphasis">IN OUT</span> ist eine Kombination aus <span class="emphasis">IN</span> und <span class="emphasis">OUT</span>. Das Schl&uuml;sselwort <span class="emphasis">NOCOPY</span> wird verwendet, um die Leistung zu verbessern, wenn ein <span class="emphasis">OUT</span>- oder <span class="emphasis">IN OUT</span>-Argument sehr gro&szlig; ist, wie zum Beispiel ein Varray oder ein Datensatz.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">AUTHID CURRENT_USER</span> und <span class="emphasis">AUTHID DEFINER</span> kann dar&uuml;ber hinaus festgelegt werden, dass die Funktion im Zugriffsrechtekontext des aktuellen Benutzers oder des Benutzers, der die Funktion definiert hat, laufen soll.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle kann die die Prozedur mit dem Schl&uuml;sselwort <span class="emphasis">LANGUAGE</span> auch externe Programme aufrufen. Das externe Programm muss ein C- oder Java-Programm sein. Die Beschreibung der spezifischen Syntax f&uuml;r den Aufruf externer Programme w&uuml;rde &uuml;ber das Ziel dieses Buches hinausgehen. N&auml;here Informationen dazu finden Sie in der Dokumentation des Herstellers.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Gespeicherte Prozeduren in Microsoft SQL Server <span class="emphasis">k&ouml;nnen</span> Ergebnismengen zur&uuml;ckgeben, gespeicherte Prozeduren in Oracle <span class="emphasis">nicht</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die folgende gespeicherte Prozedur in Microsoft SQL Server erzeugt (basierend auf den Elementen des Systemdatums und der Systemzeit) einen eindeutigen 22-stelligen Wert und gibt diesen an den aufrufenden Prozess zur&uuml;ck:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>-- Gespeicherte Prozedur in Microsoft SQL Server
CREATE PROCEDURE get_next_nbr
   @next_nbr CHAR(22) OUTPUT
AS
BEGIN
  DECLARE @random_nbr INT
  SELECT @random_nbr = RAND(  ) * 1000000

SELECT @next_nbr =
  RIGHT('000000' + CAST(ROUND(RAND(@random_nbr)*1000000,0))AS CHAR(6), 6) +
  RIGHT('0000' + CAST(DATEPART (yy, GETDATE(  ) ) AS CHAR(4)), 2) +
  RIGHT('000'  + CAST(DATEPART (dy, GETDATE(  ) ) AS CHAR(3)), 3) +
  RIGHT('00'   + CAST(DATEPART (hh, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (mi, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (ss, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('000'  + CAST(DATEPART (ms, GETDATE(  ) ) AS CHAR(3)), 3)
END
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CREATE ROLE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CREATE ROLE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">CREATE ROLE</span>


 k&ouml;nnen benannte Mengen von Privilegien erstellt werden, die Benutzern der Datenbank zugewiesen werden. Wenn einem Benutzer eine Rolle zugeteilt wird, erh&auml;lt er alle Privilegien und Zugriffsrechte, die mit dieser Rolle verkn&uuml;pft sind.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt den Befehl <span class="emphasis">CREATE ROLE</span> nicht, stellt aber &uuml;ber die gespeicherte Systemprozedur <span class="emphasis">sp_add_role</span> eine &auml;hnliche Funktionalit&auml;t zur Verf&uuml;gung..</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE ROLE role_name [WITH ADMIN {CURRENT_USER | CURRENT_ROLE}]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Diese Anweisung erzeugt eine neue Rolle und unterscheidet diese Rolle von einem Benutzer des Host-DBMS. Mit der Klausel <span class="emphasis">WITH ADMIN</span> wird dem gerade aktiven Benutzer oder der gerade aktiven Rolle unmittelbar eine Rolle zugewiesen. Standard bei dieser Anweisung ist <span class="emphasis">WITH ADMIN CURRENT_USER</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE ROLE role_name [NOT IDENTIFIED | IDENTIFIED
   {BY password | EXTERNALLY | GLOBALLY}]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle wird zuerst die Rolle erzeugt, und dann werden mit dem Befehl <span class="emphasis">GRANT</span> die Privilegien und Zugriffsrechte zugewiesen. Wenn der Benutzer Zugriff auf die Zugriffsrechte einer kennwortgesch&uuml;tzten Rolle haben m&ouml;chte, muss er den Befehl <span class="emphasis">SET ROLE</span> verwenden. Bei einer Rolle mit Kennwortschutz muss der Benutzer, wenn er darauf zugreifen m&ouml;chte, dieses Kennwort mit dem Befehl <span class="emphasis">SET ROLE</span> angeben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle wird mit verschiedenen vorkonfigurierten Rollen geliefert. <span class="emphasis">CONNECT</span>, <span class="emphasis">DBA</span> und <span class="emphasis">RESOURCE</span> sind in allen Oracle-Versionen verf&uuml;gbar. <span class="emphasis">EXP_FULL_DATABASE</span> und <span class="emphasis">IMP_FULL_DATABASE</span> sind neuere Rollen, die f&uuml;r Import- und Exportoperationen verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel wird zun&auml;chst mit <span class="emphasis">CREATE</span> eine neue Rolle in Oracle definiert. Dann werden mit <span class="emphasis">GRANT</span> die Privilegien dieser Rolle zugewiesen, und mit <span class="emphasis">ALTER ROLE</span> wird ein Kennwort vergeben. Zum Schluss wird diese Rolle wiederum mit <span class="emphasis">GRANT</span> einer Reihe von Benutzern zugeteilt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE ROLE boss;

GRANT ALL ON employee TO boss;
GRANT CREATE SESSION, CREATE DATABASE LINK TO boss;

ALTER ROLE boss IDENTIFIED BY le_grande_fromage;

GRANT boss TO nancy, dale;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CREATE SCHEMA">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CREATE SCHEMA</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p><span class="emphasis"></span>

Mit dieser Anweisung wird ein <span class="emphasis">Schema</span>, d.&#160;h. eine benannte Gruppe von zusammengeh&ouml;renden Objekten, erzeugt. Ein Schema ist eine Sammlung von Tabellen, Views und den dazugeh&ouml;rigen Zugriffsrechten. Das Schema geh&ouml;rt einer bestehenden g&uuml;ltigen Benutzer-ID (dem <span class="emphasis">Eigent&uuml;mer</span>).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE SCHEMA [schema_name] [AUTHORIZATION owner_name]
[DEFAULT CHARACTER SET char_set_name]
[PATH schema_name [,...n] ]

   [ &lt;create_table_statement1&gt; [...n] ]
   [ &lt;create_view_statement1&gt;  [...n] ]
   [ &lt;grant statement1&gt; [...n] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Anweisung <span class="emphasis">CREATE SCHEMA</span> ist ein Container, in dem viele andere <span class="emphasis">CREATE</span>- und <span class="emphasis">GRANT</span>-Anweisungen Platz finden. Optional kann mit <span class="emphasis">DEFAULT CHARACTER SET</span> der Standardzeichensatz des Schemas festgelegt werden. Dar&uuml;ber hinaus kann <span class="emphasis">PATH</span> f&uuml;r alle Objekte angegeben werden, die sich im Dateisystem befinden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Syntax in Microsoft SQL Server und Oracle </span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE SCHEMA AUTHORIZATION owner_name
   [ &lt;create_table_statement1&gt; [...n] ]
   [ &lt;create_view_statement1&gt;  [...n] ]
   [ &lt;grant statement1&gt; [...n] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn eine der Anweisungen in der Anweisung <span class="emphasis">CREATE SCHEMA</span> fehlschl&auml;gt, schl&auml;gt die gesamte Anweisung fehl. Der Vorteil von <span class="emphasis">CREATE SCHEMA</span> ist, dass die Objekte nicht nach irgendwelchen Abh&auml;ngigkeiten geordnet sein m&uuml;ssen. Zum Beispiel k&ouml;nnte eine <span class="emphasis">GRANT</span>-Anweisung normalerweise nicht f&uuml;r eine Tabelle ausgef&uuml;hrt werden, die noch nicht existiert. In einer <span class="emphasis">CREATE SCHEMA</span>-Anweisung k&ouml;nnten jedoch alle <span class="emphasis">GRANT</span>-Anweisungen zuerst stehen, gefolgt von den <span class="emphasis">CREATE</span>-Anweisungen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Viele Implementierungen unterst&uuml;tzen den Befehl <span class="emphasis">CREATE SCHEMA</span> nicht explizit. Sie erstellen aber implizit ein Schema, wenn der Benutzer Datenbankobjekte erstellt. Auf der anderen Seite erzeugt Oracle immer dann ein Schema, wenn ein Benutzer angelegt wird. Mit dem Befehl <span class="emphasis">CREATE SCHEMA</span> k&ouml;nnen in einem Schritt alle Tabellen, Views und sonstigen Datenbankobjekte zusammen mit den jeweiligen Zugriffsrechten erstellt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle wird mit <span class="emphasis">CREATE</span>
<span class="emphasis">SCHEMA</span> kein Schema erstellt, dies ist nur mit <span class="emphasis">CREATE USER</span> m&ouml;glich. <span class="emphasis">CREATE SCHEMA</span> erm&ouml;glicht es dem Benutzer, in einer einzigen SQL-Anweisung mehrere Schritte auszuf&uuml;hren. Im folgenden Beispiel aus Oracle werden die Zugriffsrechte in der Anweisung <span class="emphasis">CREATE SCHEMA</span> festgelegt, bevor die Objekte erstellt werden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE SCHEMA AUTHORIZATION emily
   GRANT SELECT, INSERT ON view_1 TO sarah
   GRANT ALL ON table_1 TO sarah

   CREATE VIEW view_1 AS
      SELECT column_1, column_2
      FROM table_1
      ORDER BY column_2

   CREATE TABLE table_1(column_1 INT, column_2 CHAR(20));</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CREATE TABLE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CREATE TABLE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Wie der Name schon sagt, wird mit der Anweisung <span class="emphasis">CREATE TABLE</span>

 eine Tabelle erstellt. Bei den meisten Herstellern k&ouml;nnen jedoch mit der Anweisung <span class="emphasis">CREATE TABLE</span> viele weitere Operationen ausgef&uuml;hrt werden, darunter das Zuweisen von Schl&uuml;sseln, kaskadierende referenzielle Integrit&auml;t, Constraints und Standardwerte.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Dieser Befehl definiert einen Tabellennamen, die Spalten der Tabelle und alle Eigenschaften der Spalten und/oder der Tabelle. Der Erstellung einer Tabelle gehen in der Regel zahlreiche &Uuml;berlegungen im Hinblick auf den Aufbau voraus. Diesen Schritt bezeichnet man als <span class="emphasis">Datenbankdesign</span>
. Die Phase, die sich mit der Analyse der Beziehungen einer Tabelle zu ihren eigenen Daten und zu anderen Tabellen in derselben Datenbank befasst, hei&szlig;t <span class="emphasis">Normalisierung</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Programmierern und Entwicklern sei dringend empfohlen, sich intensiv mit dem Datenbankdesign und der Normalisierung auseinanderzusetzen, bevor sie den Befehl <span class="emphasis">CREATE TABLE</span> zum ersten Mal ausf&uuml;hren.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im Allgemeinen beginnt der Tabellenname immer mit einem Buchstaben. Die zul&auml;ssige L&auml;nge des Namens h&auml;ngt vom Hersteller ab. Oracle l&auml;sst nur 30 Zeichen zu, der Name kann jedoch um einiges l&auml;nger sein als 30 Zeichen, wenn n&ouml;tig. Im Tabellennamen k&ouml;nnen Zahlen verwendet werden, aber keine Symbole au&szlig;er dem
Unterstrich ( _ ). Manche Hersteller lassen noch viel mehr Symbole in Tabellennamen zu. Diese sollten jedoch nicht verwendet werden, weil das zu verwirrenden IDs f&uuml;hren kann.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Zur Definition von Spalteneigenschaften unterst&uuml;tzen alle Hersteller die Optionen <span class="emphasis">NULL</span>  und <span class="emphasis">NOT NULL</span>. (Eine allein stehende <span class="emphasis">NULL</span> wird vom SQL99-Standard nicht verlangt.) Wenn eine Spalte als <span class="emphasis">NULL</span> definiert wird, kann diese unabh&auml;ngig vom Datentyp Nullwerte enthalten. In der Regel belegen Spalten, die Nullwerte enthalten d&uuml;rfen, ein weiteres Bit pro Datensatz. Wenn <span class="emphasis">NOT NULL</span> angegeben ist, darf die Spalte nie Nullwerte enthalten. Bei einer <span class="emphasis">NOT NULL</span>-Spalte schl&auml;gt jeder Versuch, mit <span class="emphasis">INSERT</span> einen Nullwert einzuf&uuml;gen und mit <span class="emphasis">UPDATE</span> einen Wert auf Null zu setzen, fehl und wird zur&uuml;ckgef&uuml;hrt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Alle Hersteller unterst&uuml;tzen au&szlig;erdem die Deklaration <span class="emphasis">PRIMARY KEY</span>,  sowohl auf Spalten- als auch auf Tabellenebene. Ein <span class="emphasis">Prim&auml;rschl&uuml;ssel</span> ist eine besondere Bezeichnung, mit der sich jede Zeile einer Tabelle eindeutig identifizieren l&auml;sst. Der Prim&auml;rschl&uuml;ssel besteht aus einer oder mehreren Spalten in der Tabelle, die zusammengenommen eine eindeutige Identit&auml;t f&uuml;r jede Zeile liefern. Eine Tabelle kann nur einen Prim&auml;rschl&uuml;ssel haben. Alle Werte im Prim&auml;rschl&uuml;ssel m&uuml;ssen eindeutig und d&uuml;rfen nicht <span class="literal">null</span> sein. Es k&ouml;nnen anschlie&szlig;end Fremdschl&uuml;ssel f&uuml;r die Tabelle deklariert werden, die eine direkte Beziehung zum Prim&auml;rschl&uuml;ssel einer anderen Tabelle herstellen. Auf diese Weise k&ouml;nnen Parent/Child- bzw. Master/Detail-Beziehungen zwischen Tabellen aufgebaut werden. Dies kann mit kaskadierenden Aktionen erweitert werden. Ein Benutzer m&ouml;chte vielleicht verhindern, dass ein Datensatz aus der Tabelle <span class="emphasis">customer</span> gel&ouml;scht wird, wenn es f&uuml;r diesen Kunden noch Verkaufsdatens&auml;tze in der Tabelle <span class="emphasis">sales</span> gibt. Die Syntax zum Definieren von Fremdschl&uuml;sseln ist von Hersteller zu Hersteller unterschiedlich.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die meisten Hersteller unterst&uuml;tzen auch <span class="emphasis">DEFAULT</span>-Werte f&uuml;r bestimmte Spalten. Jedes Mal, wenn ein Datensatz in eine Tabelle eingef&uuml;gt wird und f&uuml;r die betreffende Spalte kein Wert angegeben ist, wird der Standardwert verwendet.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die grundlegende Syntax f&uuml;r <span class="emphasis">CREATE TABLE</span> ist nachstehend dargestellt. Diese Informationen reichen aus, um mit dem Erstellen von Tabellen beginnen und die Tabellen dann mit Daten f&uuml;llen zu k&ouml;nnen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TABLE table_name
   (
   column_name datatype[(length)] [NULL | NOT NULL],...n
   )</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Dazu ein einfaches Beispiel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TABLE housing_construction
   (project_number      INT NOT NULL,
   project_date         DATETIME NOT NULL,
   project_name         VARCHAR(50) NOT NULL,
   construction_color   NCHAR(20) NULL,
   construction_height  DECIMAL(4,1) NULL,
   construction_length  DECIMAL(4,1) NULL,
   construction_width   DECIMAL(4,1) NULL,
   construction_volume  INT NULL)
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Microsoft SQL Server wird mit dieser Anweisung eine Tabelle namens <span class="emphasis">housing_construction</span> definiert, die acht Spalten enth&auml;lt. Jede Spalte ist entweder als <span class="emphasis">NULL</span> oder <span class="emphasis">NOT NULL</span> definiert und hat einen zu den enthaltenen Informationen passenden Datentyp. Beachten Sie, dass die Liste der Spaltendefinitionen immer in runden Klammern stehen muss und
und nach jeder Spaltendefinition ein Komma kommt, sofern noch eine weitere Definition folgt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [GLOBAL TEMPORARY | LOCAL TEMPORARY] TABLE table_name
[ON COMMIT {PRESERVE ROWS | DELETE ROWS}
(column_name datatype attributes [,...n]
 | [LIKE  table_name]
 | [table_constraint][,...n] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der SQL99-Anweisung <span class="emphasis">CREATE TABLE</span> werden <span class="emphasis">tempor&auml;re</span>
 Tabellen angelegt, die beim Erstellen der Tabelle instanziiert und am Ende der aktuellen Benutzersitzung automatisch gel&ouml;scht werden. Tempor&auml;re Tabellen vom Typ <span class="emphasis">GLOBAL</span> stehen allen aktiven Benutzersitzungen zur Verf&uuml;gung, solche vom Typ <span class="emphasis">LOCAL</span> dagegen nur der Benutzersitzung, in der sie angelegt wurden. Es kann auch ein <span class="emphasis">ON COMMIT</span>-Wert f&uuml;r die tempor&auml;re Tabelle angegeben werden. Bei <span class="emphasis">ON COMMIT PRESERVE ROWS</span> bleiben alle Daten&auml;nderungen an einer tempor&auml;ren Tabelle bei einem <span class="emphasis">COMMIT</span> bestehen, w&auml;hrend die Tabelle bei <span class="emphasis">ON COMMIT DELETE ROWS</span> bei einem <span class="emphasis">COMMIT</span> geleert wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Option <span class="emphasis">LIKE table_name</span> wird eine neue Tabelle mit denselben Spaltendefinitionen und Tabellen-Constraints wie eine bereits bestehende Tabelle erzeugt. Wenn Sie <span class="emphasis">LIKE</span> verwenden, m&uuml;ssen die Spalten- und Tabellen-Constraints nicht definiert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Weil es keine einheitliche Implementierung von <span class="emphasis">CREATE TABLE</span> gibt, dieser Befehl aber sehr wichtig ist, werden alle Hersteller-Implementierungen einzeln und detailliert beschrieben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TABLE [<span class="replaceable">database_name</span>.[<span class="replaceable">owner</span>]. | <span class="replaceable">owner</span>.] <span class="replaceable">table_name</span>
({column_name datatype [ [DEFAULT default_value]
   | {IDENTITY [(seed,increment) [NOT FOR REPLICATION]]]
   [ROWGIDCOL] ]
   [NULL | NOT NULL]
   | [{PRIMARY KEY | UNIQUE}
        [CLUSTERED | NONCLUSTERED]
        [WITH FILLFACTOR = int] [ON {filegroup | DEFAULT}] ]
   | [[FOREIGN KEY]
        REFERENCES reference_table[<span class="emphasis">(</span>reference_column[,...n])]
        [ON DELETE {CASCADE | NO ACTION}]
        [ON UPDATE {CASCADE | NO ACTION}]
        [NOT FOR REPLICATION]
   | [CHECK [NOT FOR REPLICATION] (expression)
   | [COLLATE collation_name]
|column_name AS computed_column_expression
[,...n]
|[table_constraint][,...n] )
[ON {filegroup | DEFAULT} ]
[TEXTIMAGE_ON {filegroup | DEFAULT} ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>SQL Server bietet zahlreiche Optionen f&uuml;r die Definition einer Tabelle, ihrer Spalten und ihrer Contraints auf Tabellenebene. In SQL Server kann jeder Constraint auf Spaltenebene mit <span class="emphasis">CONSTRAINT constraint_name</span>. . ., gefolgt vom Text des Constraints, benannt werden. F&uuml;r eine einzelne Spalte k&ouml;nnen mehrere Constraints festgelegt werden, solange diese sich nicht gegenseitig ausschlie&szlig;en (wie zum Beispiel <span class="emphasis">PRIMARY KEY</span> und <span class="emphasis">NULL</span>).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In SQL Server k&ouml;nnen auch lokale <span class="emphasis"></span>tempor&auml;re Tabellen erstellt werden, die dann in der Datenbank <span class="emphasis">tempdb</span> gespeichert werden. Dazu muss dem Tabellennamen ein  Nummernzeichen (#) vorangestellt werden. Die lokale tempor&auml;re Tabelle kann nur von dem Benutzer oder dem Prozess, der sie erstellt hat, verwendet werden. Sie wird gel&ouml;scht, sobald sich die Person ausloggt oder der Prozess beendet ist. Eine


globale tempor&auml;re Tabelle, die von allen aktuell angemeldeten Benutzern und Prozessen verwendet werden kann, wird erstellt, indem man dem Namen der Tabelle zwei Nummernzeichen (##) voranstellt. Die globale tempor&auml;re Tabelle wird gel&ouml;scht, sobald der Prozess beendet ist oder sich der Benutzer, der die Tabelle angelegt hat, ausloggt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Weil SQL Server die integrierte Replikation unterst&uuml;tzt, k&ouml;nnen viele Eigenschaften einer Spalte als <span class="emphasis">NOT FOR REPLICATION</span> gekennzeichnet werden, was bedeutet, dass <span class="emphasis">IDENTITY</span>- und <span class="emphasis">FOREIGN KEY</span>-Werte nicht auf die beteiligten Server repliziert werden. Dies ist hilfreich in Situationen, in denen verschiedene Server dieselben Tabellenstrukturen, aber nicht genau dieselben Daten ben&ouml;tigen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Ebenso n&uuml;tzlich f&uuml;r die Replikation ist <span class="emphasis">ROWGUIDCOL</span>. Damit wird eine Spalte als globaler eindeutiger Identifier ausgewiesen, was sicherstellt, dass keine zwei Werte &uuml;ber alle Server hinweg jemals doppelt vorkommen. Pro Tabelle kann nur eine solche Spalte identifiziert werden. Der eindeutige Wert selbst wird durch diese Operation jedoch nicht erzeugt. Dieser muss mit der Funktion <span class="emphasis">NEWID</span> eingef&uuml;gt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn die Eigenschaft <span class="emphasis">IDENTITY</span> auf eine Integerspalte angewendet wird, ist sie vergleichbar mit <span class="emphasis">AUTO_INCREMENT</span> in MySQL, das die Spalten automatisch erstellt und mit monoton steigenden Zahlen f&uuml;llt. <span class="emphasis">IDENTITY</span>ist jedoch um einiges vielseitiger und flexibler. W&auml;hrend <span class="emphasis">AUTO_INCREMENT</span> immer bei 1 beginnt, beginnt <span class="emphasis">IDENTITY</span> mit dem Wert von <span class="emphasis">seed</span>. W&auml;hrend bei <span class="emphasis">AUTO_INCREMENT</span> der Wert jedes Mal um 1 erh&ouml;ht wird, wenn eine neue Zeile eingef&uuml;gt wird, wird bei <span class="emphasis">IDENTITY</span> der Wert jeweils um <span class="emphasis">increment</span> erh&ouml;ht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In SQL Server kann <span class="emphasis">DEFAULT</span> auf jede beliebige Spalte au&szlig;er auf solche mit dem Datentyp "Timestamp" oder der Eigenschaft <span class="emphasis">IDENTITY</span> angewendet werden. <span class="emphasis">DEFAULT</span> muss ein konstanter Wert wie zum Beispiel eine Zeichenfolge oder eine Zahl sowie eine Systemfunktion wie <span class="emphasis">GETDATE( )</span> oder <span class="emphasis">NULL</span> sein.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Pro Tabelle k&ouml;nnen dar&uuml;ber hinaus ein <span class="emphasis">PRIMARY KEY</span> namens "name per table" und mehrere Spalten vom Typ <span class="emphasis">UNIQUE</span> oder <span class="emphasis">FOREIGN KEY</span> angegeben werden. Diese k&ouml;nnen geclustert oder nicht-geclustert sein und mit einem anf&auml;nglichen F&uuml;llfaktor definiert werden. N&auml;here Informationen dazu finden Sie unter <span class="emphasis">CREATE INDEX</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn Sie einen <span class="emphasis">FOREIGN KEY</span> festlegen, k&ouml;nnen Sie die Tabelle und die Spalten, zu denen die referenzielle Integrit&auml;t erhalten bleiben soll, mit der Klausel <span class="emphasis">REFERENCES</span> angeben. Es k&ouml;nnen nur Spalten referenziert werden, die als <span class="emphasis">PRIMARY KEY</span>- oder <span class="emphasis">UNIQUE</span>-Index auf der referenzierenden Tabelle definiert wurden. Es kann auch eine referenzielle Aktion angegeben werden, die in der <span class="emphasis">reference_table</span> ausgef&uuml;hrt werden soll, wenn ein Datensatz gel&ouml;scht oder aktualisiert wird. Bei Angabe von <span class="emphasis">NO ACTION</span> passiert mit der referenzierenden Tabelle nichts, wenn ein Datensatz gel&ouml;scht oder aktualisiert wird. Bei Angabe von <span class="emphasis">CASCADE</span> dagegen bezieht sich die L&ouml;sch- oder Aktualisierungsoperation auch auf die referenzierte Tabelle, und zwar auf alle Datens&auml;tze, die vom Wert des <span class="emphasis">FOREIGN KEY</span> abh&auml;ngen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem <span class="emphasis">CHECK</span>-Constraint wird sichergestellt, dass ein Wert, der in die angegebene Tabellenspalte eingef&uuml;gt wird, laut <span class="emphasis">CHECK</span>-Ausdruck auch zul&auml;ssig ist. Im folgenden Beispiel ist eine Tabelle mit mehreren Constraints auf Spaltenebene zu sehen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TABLE people
    (people_id     CHAR(4)
        CONSTRAINT pk_dist_id PRIMARY KEY CLUSTERED
        CONSTRAINT ck_dist_id CHECK (dist_id LIKE '[A-Z][A-Z][A-Z][A-Z]'),
     people_name   VARCHAR(40) NULL,
     people_addr1  VARCHAR(40) NULL,
     people_addr2  VARCHAR(40) NULL,
     city          VARCHAR(20) NULL,
     state         CHAR(2)     NULL
        CONSTRAINT def_st DEFAULT ("CA")
        CONSTRAINT chk_st REFERENCES states(state_ID),
     zip           CHAR(5)     NULL
        CONSTRAINT ck_dist_zip
        CHECK(zip LIKE '[0-9][0-9][0-9][0-9][0-9]'),
     phone         CHAR(12)    NULL,
     sales_rep     empid       NOT NULL DEFAULT USER)
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem <span class="emphasis">CHECK</span>-Constraint f&uuml;r <span class="emphasis">people_id</span> wird sichergestellt, dass eine ID verwendet wird, die nur aus Buchstaben besteht, und mit dem Constraint f&uuml;r <span class="emphasis">zip</span> wird ein rein numerischer Wert gew&auml;hrleistet. Mit dem <span class="emphasis">REFERENCES</span>-Constraint f&uuml;r <span class="emphasis">state</span> wird eine Nachschlageoperation in der Tabelle <span class="emphasis">states</span> ausgef&uuml;hrt. Der Constraint <span class="emphasis">REFERENCES</span> ist im Prinzip mit dem <span class="emphasis">CHECK</span>-Constraint vergleichbar, au&szlig;er dass ersterer die Liste der zul&auml;ssigen Werte aus den Werten holt, die in einer anderen Spalte gespeichert sind. Das Beispiel zeigt, wie Spalten-Constraints mit der Syntax <span class="emphasis">CONSTRAINT constraint_name.</span>
<span class="emphasis">.</span> <span class="emphasis">.</span> angegeben werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Neu in SQL Server 2000 ist auch die Spalteneigenschaft <span class="emphasis">COLLATE</span>. Mit dieser Eigenschaft k&ouml;nnen Programmierer spaltenweise die Sortierreihenfolge und den Zeichensatz der Spalte festlegen. Da es sich hier um eine fortgeschrittene Technik handelt, sollten Sie in der Dokumentation des Herstellers nachschlagen, wenn die standardm&auml;&szlig;ige Sortierreihenfolge oder der Standardzeichensatz einer bestimmten Spalte ge&auml;ndert werden muss. Unter <span class="emphasis">CREATE FUNCTION</span> finden Sie ein Beispiel f&uuml;r diese Syntax.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>SQL Server erm&ouml;glicht auch die Erstellung von Tabellen mit Spalten, die einen berechneten Wert enthalten. Die Spalte selbst enth&auml;lt keine Daten. Vielmehr handelt es sich um eine virtuelle Spalte, die einen Ausdruck enth&auml;lt, der auf andere Spalten in der Tabelle zur&uuml;ckgreift. So k&ouml;nnte zum Beispiel eine berechnete Spalte einen Ausdruck wie <span class="emphasis">order_cost AS (price</span>
<span class="emphasis">*</span> <span class="emphasis">qty)</span> enthalten. Berechnete Spalten k&ouml;nnen auch Konstanten, Funktionen, Variablen, nicht-berechnete Spalten oder beliebige mit Operatoren verkn&uuml;pfte Kombinationen aus diesen Spaltentypen sein.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Jede der oben beschriebenen Spalten-Constraints k&ouml;nnen auch auf Tabellenebene deklariert werden. <span class="emphasis">PRIMARY KEY</span>-Constraints, <span class="emphasis">FOREIGN KEY</span>-Constraints, <span class="emphasis">CHECK</span>-Constraints und sonstige Constraints k&ouml;nnen also nach der Definition aller Spalten in der Anweisung <span class="emphasis">CREATE TABLE</span> deklariert werden. Dies ist sehr n&uuml;tzlich f&uuml;r Constraints, die sich auf mehrere Spalte beziehen sollen. Wenn zum Beispiel auf Spaltenebene ein <span class="emphasis">UNIQUE</span>-Constraint deklariert wird, kann dieser nur auf diese Spalten angewendet werden. Wird der Constraint hingegen auf Tabellenebene deklariert, erstreckt er sich &uuml;ber mehrere Spalten. Nachfolgend ein Beispiel f&uuml;r Constraints auf Spalten- und auf Tabellenebene:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>-- Constraint auf Spaltenebene
CREATE TABLE favorite_books
    (isbn          CHAR(100)    PRIMARY KEY NONCLUSTERED,
     book_name     VARCHAR(40)  UNIQUE,
     category      VARCHAR(40)  NULL,
     subcategory   VARCHAR(40)  NULL,
     pub_date      DATETIME     NOT NULL,
     purchase_date DATETIME     NOT NULL)
GO

-- Constraint auf Tabellenebene
CREATE TABLE favorite_books
    (isbn          CHAR(100)    NOT NULL,
     book_name     VARCHAR(40)  NOT NULL,
     category      VARCHAR(40)  NULL,
     subcategory   VARCHAR(40)  NULL,
     pub_date      DATETIME     NOT NULL,
     purchase_date DATETIME     NOT NULL,
        CONSTRAINT pk_book_id   PRIMARY KEY NONCLUSTERED (isbn)
           WITH FILLFACTOR=70,
        CONSTRAINT unq_book     UNIQUE CLUSTERED (book_name,pub_date))
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Ergebnisse dieser beiden Befehle sind nahezu gleich, au&szlig;er dass sich der Tabellen-Constraint <span class="emphasis">UNIQUE</span>auf zwei Spalten bezieht, der Spalten-Constraint <span class="emphasis">UNIQUE</span> dagegen nur auf eine Spalte.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server bietet au&szlig;erdem zwei separate Klauseln, mit denen gesteuert werden kann, wie die Tabelle (oder die Prim&auml;rschl&uuml;ssel- oder eindeutigen Indizes) physisch abgelegt werden soll: <span class="emphasis">[ON {filegroup | DEFAULT} ]</span> und <span class="emphasis">[TEXTIMAGE_ON {filegroup | DEFAULT}]</span>. Mit der Klausel <span class="emphasis">ON filegroup</span> wird die Tabelle oder der Index in der angegebenen Dateigruppe gespeichert, solange diese in der Datenbank existiert. Wenn <span class="emphasis">ON DEFAULT</span> angegeben ist oder die Klausel <span class="emphasis">ON</span> gar nicht verwendet wird, wird die Tabelle oder der Index in der Standarddateigruppe der betreffenden Datenbank abgespeichert. Die Klausel <span class="emphasis">TEXTIMAGE</span> funktioniert &auml;hnlich, au&szlig;er dass mit ihr die Unterbringung von <span class="emphasis">text</span>-, <span class="emphasis">ntext</span>- und <span class="emphasis">image</span>-Spalten gesteuert wird. Diese Spalten werden normalerweise in der Standarddateigruppe zusammen mit allen anderen Tabellen und Datenbankobjekten gespeichert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [TEMPORARY] TABLE [IF NOT EXISTS] table_name
<span class="emphasis">(</span>column_name datatype [NULL | NOT NULL] [DEFAULT default_value]
   [AUTO_INCREMENT]
   [PRIMARY KEY] [reference_definition] |
   [CHECK (expression) |
   [INDEX [index_name] index_col_name1[(length)],...n)] |
   [UNIQUE [INDEX] [index_name] (index_col_name1,...n)] |
   [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name1,...n)
      [REFERENCES table_name [(index_col_name,...)]
      [MATCH FULL | MATCH PARTIAL]
      [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
      [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}])
{[TYPE = {ISAM | MYISAM | HEAP} |
   AUTO_INCREMENT = int |
   AVG_ROW_LENGTH = int |
   CHECKSUM = {0 | 1} |
   COMMENT = "string" |
   DELAY_KEY_WRITE = {0 | 1} |
   MAX_ROWS = int |
   MIN_ROWS = int |
   PACK_KEYS = {0 | 1} |
   PASSWORD = "string" |
   ROW_FORMAT= { default | dynamic | static | compressed }] }
[[IGNORE | REPLACE] SELECT_statement]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>MySQL bietet viele n&uuml;tzliche Optionen f&uuml;r das Erstellen von Tabellen. Mit der Option <span class="emphasis">TEMPORARY</span> wird eine Tabelle erstellt, die so lange bestehen bleibt, bis die Verbindung, w&auml;hrend der sie angelegt wurde, getrennt wird. Sobald die Verbindung geschlossen wird, wird die tempor&auml;re Tabelle automatisch gel&ouml;scht. Die Option <span class="emphasis">IF NOT EXISTS</span> verhindert einen Fehler, wenn die Tabelle bereits existiert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn in MySQL eine Tabelle angelegt wird, werden in der Regel drei Betriebssystemdateien erstellt: eine Tabellendefinitionsdatei mit der Erweiterung <span class="emphasis">.frm</span>, eine Datendatei mit der Erweiterung <span class="emphasis">.myd</span> und eine Indexdatei mit der Erweiterung <span class="emphasis">.myi</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">AUTO_INCREMENT </span> wird eine Integerspalte so konfiguriert, dass sich ihr Wert automatisch um 1 erh&ouml;ht (beginnend mit dem Wert 1). MySQL erlaubt nur eine <span class="emphasis">AUTO_INCREMENT</span>-Spalte pro Tabelle zu. Wenn der h&ouml;chste Wert gel&ouml;scht wird, wird der Wert wiederverwendet. Wenn alle Datens&auml;tze gel&ouml;scht werden, beginnt die Z&auml;hlung der Werte von vorne.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Es k&ouml;nnen eine oder mehrere <span class="emphasis">PRIMARY KEY</span>-Spalten definiert werden, solange diese auch als <span class="emphasis">NOT NULL</span> definiert sind. Wenn eine Spalte die Eigenschaft <span class="emphasis">INDEX</span> aufweist, kann auch ein Name f&uuml;r den Index angegeben werden. (Ein Synonym f&uuml;r <span class="emphasis">INDEX</span> in MySQL ist <span class="emphasis">KEY</span>.) Wenn kein Name zugewiesen wird, verwendet MySQL den <span class="emphasis">index_column_name</span> und h&auml;ngt ein numerisches Suffix an ( _2, _3,. . . ), um diesen Namen eindeutig zu machen. Nur der Tabellentyp "MyISAM" unterst&uuml;tzt Indizes f&uuml;r <span class="emphasis">NULL</span>-Spalten oder Spalten des Datentyps <span class="emphasis">BLOB</span> oder <span class="emphasis">TEXT</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klauseln <span class="emphasis">FOREIGN KEY</span>, <span class="emphasis">CHECK</span> und <span class="emphasis">REFERENCES</span> haben keine Funktion. Sie werden nur unterst&uuml;tzt, um die Kompatibilit&auml;t mit anderen SQL-Datenbanken zu verbessern.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit den <span class="emphasis">TYPE</span>-Tabellenoptionen wird festgelegt, wie die Daten physisch gespeichert werden sollen. <span class="emphasis">ISAM</span> ist die urspr&uuml;ngliche Tabellendefinition. <span class="emphasis">MyISAM</span> ist eine neuere, bin&auml;re, portablere Speicherstruktur. Mit <span class="emphasis">HEAP</span> wird die Tabelle im Speicher abgelegt. Es gibt noch weitere Optionen, mit denen die Leistung einer Tabelle optimiert werden kann:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ul><li><i><span class="emphasis">AUTO_INCREMENT</span></i><br>&#160;
						  Legt den <span class="emphasis">auto_increment</span>-Wert f&uuml;r die Tabelle fest (nur bei MyISAM).</li><li><i><span class="emphasis">AVG_ROW_LENGTH</span></i><br>&#160;
						  Legt die ungef&auml;hre durchschnittliche Zeilenl&auml;nge f&uuml;r Tabellen mit Datens&auml;tzen variabler L&auml;nge fest. MySQL verwendet <span class="emphasis">avg_row_length</span> * <span class="emphasis">max_rows</span>, um festzulegen, wie gro&szlig; eine Tabelle sein darf.</li><li><i><span class="emphasis">CHECKSUM</span></i><br>&#160;
						  Wenn dieser Wert auf 1 gesetzt ist, wird f&uuml;r alle Zeile in der Tabelle eine Pr&uuml;fsumme gef&uuml;hrt (nur MyISAM). Dadurch wird zwar die Verarbeitung langsamer, aber das Risiko einer Datenkorruption ist geringer.</li><li><i><span class="emphasis">COMMENT</span></i><br>&#160;
						  Erm&ouml;glicht das Einf&uuml;gen eines bis zu 60 Zeichen langen Kommentars.</li><li><i><span class="emphasis">DELAY_KEY_WRITE</span></i><br>&#160;
						  Wenn dieser Wert auf 1 gesetzt ist, werden Aktualisierungen der Schl&uuml;sseltabellen verz&ouml;gert, bis die Tabelle geschlossen wird (nur bei MyISAM).</li><li><i><span class="emphasis">MAX_ROWS</span></i><br>&#160;
						  Legt die maximale Zeilenanzahl einer Tabelle fest. Der Standardwert ist 4 GB Festplattenspeicher.</li><li><i><span class="emphasis">MIN_ROWS</span></i><br>&#160;
						  Legt die minimale Anzahl an Zeilen fest, die in der Tabelle gespeichert werden sollen.</li><li><i><span class="emphasis">PACK_KEYS</span></i><br>&#160;
						  Wenn dieser Wert auf 1 gesetzt ist, werden die Indizes der Tabelle komprimiert, was das Lesen schneller, Aktualisierungen aber langsamer macht (nur bei MyISAM und ISAM). Standardm&auml;&szlig;ig werden nur Strings gepackt. Wenn der Wert auf 1 gesetzt ist, werden sowohl Strings als auch numerische Werte komprimiert.</li><li><i><span class="emphasis">PASSWORD</span></i><br>&#160;
						  Verschl&uuml;sselt die <span class="emphasis">.frm</span>-Datei, aber nicht die Tabelle, mit einem Kennwort.</li><li><i><span class="emphasis">ROW_FORMAT</span></i><br>&#160;
						  Legt fest, wie zuk&uuml;nftige Zeilen in der Tabelle gespeichert werden sollen.</li></ul>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">SELECT</span>_<span class="emphasis">statement</span> wird eine Tabelle erzeugt, deren Felder auf den Elementen in einer <span class="emphasis">SELECT</span>-Anweisung basieren. Sollte dies &#8211; wie bei manchen Implementierungen &#8211; nicht der Fall sein, kann die Tabelle mit den Ergebnissen der <span class="emphasis">SELECT</span>-Anweisung gef&uuml;llt werden. Beispiel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TABLE test_example
  (column_a INT NOT NULL AUTO_INCREMENT,
  PRIMARY KEY(column_a),
  INDEX(column_b))
TYPE=HEAP
SELECT column_b,column_c FROM samples;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Hiermit wird eine Heap-Tabelle mit drei Spalten erstellt: <span class="emphasis">column_a</span>, <span class="emphasis">column_b</span> und <span class="emphasis">column_c</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [GLOBAL TEMPORARY] TABLE [schema.]table_name
( column_name datatype [DEFAULT] {column_constraint [...]} [,...n]
| table_constraint [,...n] } )
[ON COMMIT {DELETE | PRESERVE} ROWS]
( physical_characteristics )
( table_characteristics )</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In diesem einfachen und kleinen Codeblock steckt mehr, als man denkt. Die extrem ausgefeilte Oracle-Implementierung der Anweisung <span class="emphasis">CREATE TABLE</span> hat das Potenzial, einer der komplexesten Einzelbefehle in irgendeiner Programmiersprache &uuml;berhaupt zu werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der Code der <span class="emphasis">CREATE TABLE</span>-Klausel in Oracle enth&auml;lt viele Unterklauseln. Wir zeigen diese hier nicht alle in einem Befehl, sondern zerlegen diesen in Unterklauseln, die selbst wiederum Unterklauseln enthalten. Der normale SQL-Programmierer wird manche dieser Unterklauseln wahrscheinlich nie verwenden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Beginnen wir mit den offensichtlichsten Unterschieden zwischen der SQL99-Version von <span class="emphasis">CREATE TABLE</span> und der Oracle-Version: Tabellen, die als <span class="emphasis">GLOBAL TEMPORARY</span> erzeugt werden, m&uuml;ssen einfache Tabellen sein. Globale tempor&auml;re Tabellen k&ouml;nnen die meisten von Oracle unterst&uuml;tzten Sondermerkmale wie Partitionierung, Indexorganisation oder geclusterte Tabellen nicht verwenden. Eine globale tempor&auml;re Tabelle steht allen Sitzungen zur Verf&uuml;gung, aber die in dieser Tabelle gespeicherten Daten sind nur in der Sitzung sichtbar, in der sie eingef&uuml;gt wurden. Mit der Klausel <span class="emphasis">ON COMMIT</span>, die nur bei der Erstellung tempor&auml;rer Tabellen erlaubt ist, wird Oracle aufgefordert, die Tabelle entweder nach jedem Festschreiben der Tabelle (<span class="emphasis">DELETE ROWS</span>) oder beim Beenden der Sitzung (<span class="emphasis">PRESERVE ROWS</span>) abzuschneiden. Beispiel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE GLOBAL TEMPORARY TABLE shipping_schedule
  (ship_date DATE,
   receipt_date DATE,
   received_by VARCHAR2(30),
   amt NUMBER)
ON COMMIT PRESERVE ROWS;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der oben gezeigten <span class="emphasis">CREATE TABLE</span>-Anweisung wird eine globale tempor&auml;re Tabelle namens <span class="emphasis">shipping_schedule</span> erstellt, bei der die eingef&uuml;gten Zeilen &uuml;ber mehrere Sitzungen hinweg bestehen bleiben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die physischen Eigenschaften einer Oracle-Tabelle werden mit den folgenden Codebl&ouml;cken und deren Unterbl&ouml;cken definiert:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>-- physical_characteristics
{[{[physical_attributes]
| TABLESPACE tablespace_name
| {LOGGING | NOLOGGING} }]
| {ORGANIZATION {HEAP [{[physical_attributes]
   | TABLESPACE tablespace_name
   | {LOGGING | NOLOGGING} }]
| INDEX indexed_table_clause)}
| CLUSTER cluster_name (column [,...n]) }
[special_storage_clause]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">physical_characteristics</span> wird festgelegt, wie die Daten physisch im Festplattensubsystem gespeichert werden sollen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">TABLESPACE</span> weist die Tabelle einem bestimmten, bereits vorhandenen Tablespace zu. Die Klausel <span class="emphasis">TABLESPACE</span> kann weggelassen werden, was zur Folge hat, dass der Index dem Standard-Tablespace zugeordnet wird. Das Gleiche erreicht man mit dem Schl&uuml;sselwort <span class="emphasis">DEFAULT</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit den Klauseln <span class="emphasis">LOGGING</span> und <span class="emphasis">NOLOGGING</span> wird definiert, ob die Tabelle, gro&szlig;e Objekte (LOB) oder Partitionen im Redo-Log gespeichert werden sollen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">ORGANIZATION HEAP</span> teilt Oracle mit, dass die Zeilen in der Tabelle physisch in einer beliebigen Reihenfolge gespeichert werden k&ouml;nnen. Optional kann auch noch die Klausel <span class="emphasis">segment_characteristic</span> angegeben werden. Alternativ k&ouml;nnen die Zeilen der Tabelle mit <span class="emphasis">ORGANIZATION INDEX index_name</span> physisch nach einem benannten Index sortiert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">physical_attributes</span> (siehe dazu den folgenden Codeblock) werden die Speichermerkmale der gesamten Tabelle oder, wenn die Tabelle partitioniert ist, einer bestimmten Partition definiert (dazu sp&auml;ter mehr):</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>-- physical_attributes
[{PCTFREE int | PCTUSED int | INITRANS int | MAXTRANS int | storage_
    clause}]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">PCTFREE</span> definiert, wie viel freier Platz in Prozent f&uuml;r jeden Datenblock in der Tabelle reserviert wird. So werden zum Beispiel bei dem Wert 10 10&#160;% des Datenplatzes f&uuml;r neu einzuf&uuml;gende Zeilen reserviert. Mit <span class="emphasis">PCTUSED</span> wird der minimale Prozentsatz an Speicherplatz definiert, der in einem Block zur Verf&uuml;gung stehen muss, damit dort neue Zeilen aufgenommen werden k&ouml;nnen. So besagt zum Beispiel der Wert 90, dass dann neue Zeilen in den Datenblock eingef&uuml;gt werden, wenn der verwendete Platz unter 90&#160;% f&auml;llt. Die Summe von <span class="emphasis">PCTFREE</span> und <span class="emphasis">PCTUSED</span> darf nicht &uuml;ber 100 liegen. <span class="emphasis">INITRANS</span> wird selten verwendet; hier werden zwischen 1 und 255 anf&auml;ngliche Transaktionen pro Datenblock definiert. <span class="emphasis">MAXTRANS</span> legt die maximale Anzahl gleichzeitiger Transaktionen in einem Datenblock fest.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">storage_clause</span> steuert eine Reihe von Attributen zur physischen Speicherung der Daten:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>-- storage_clause
STORAGE ( [ {INITIAL int [K | M]
            | NEXT int [K | M]
            | MINEXTENTS int
            | MAXEXTENTS {int | UNLIMITED}
            | PCTINCREASE int
            | FREELISTS int
            | FREELIST GROUPS int
            | OPTIMAL [{int [K | M] | NULL}]
            | BUFFER_POOL {KEEP | RECYCLE | DEFAULT} ] [...] )</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn Sie diese Attribute in mehr als einer Zeile angeben, setzen Sie sie in runde Klammern und trennen Sie sie mit Leerzeichen wie in <span class="emphasis">(INITIAL 32M NEXT8M)</span>. Mit <span class="emphasis">INITIAL int [K | M] </span> wird die anf&auml;ngliche Bereichsgr&ouml;&szlig;e der Tabelle in Byte, Kilobyte <span class="emphasis">(K)</span> oder Megabyte <span class="emphasis">(M) festgelegt. NEXT</span> <span class="emphasis">int [K | M]</span> gibt an, wie viel zus&auml;tzlicher Speicherplatz alloziert wird, wenn <span class="emphasis">INITIAL</span> gef&uuml;llt ist. Mit <span class="emphasis">PCTINCREASE int</span> wird die Wachstumsrate des Objekts nach dem ersten Anwachsen festgelegt. Der anf&auml;ngliche Bereich wird wie angegeben alloziert. F&uuml;r den zweiten Bereich gilt die mit <span class="emphasis">NEXT</span> angegebene Gr&ouml;&szlig;e. Der dritte Bereich hat die Gr&ouml;&szlig;e <span class="emphasis">NEXT + (NEXT * PCTINCREASE).</span> Wenn <span class="emphasis">PCTINCREASE</span> auf 0 gesetzt ist, wird immer <span class="emphasis">NEXT</span> verwendet. Ansonsten ist jeder zus&auml;tzliche Speicherbereich um <span class="emphasis">PCTINCREASE</span> gr&ouml;&szlig;er als der vorherige.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">MINEXTENTS int </span>wird Oracle angewiesen, die minimale Anzahl von Speicherbereichen zu verwenden. Standardm&auml;&szlig;ig wird nur ein Speicherbereich erzeugt, es k&ouml;nnen aber beim Initialisieren des Objekts noch weitere erzeugt werden. <span class="emphasis">MAXEXTENTS int </span>teilt Oracle mit, wie viele Speicherbereiche maximal erlaubt sind. Dieser Wert kann auf <span class="emphasis">UNLIMITED</span> gesetzt werden. (Geben Sie vorsichtig mit UNLIMITED um. Es gibt Situationen, in denen damit Datenbanksch&auml;den verursacht werden k&ouml;nnen.) Mit <span class="emphasis">FREELISTS int </span>wird die Anzahl der freien Listen (Freelists) f&uuml;r jede Gruppe festgelegt, der Standardwert ist 1. <span class="emphasis">FREELIST GROUPS int </span>gibt die Anzahl der Gruppen von freien Listen an, der Standardwert ist 1. Beispiel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TABLE book_sales
  (qty NUMBER,
   period_end_date DATE,
   period_nbr NUMBER)
TABLESPACE sales
STORAGE (INITIAL 8M NEXT 8M MINEXTENTS 1 MAXEXTENTS 8);</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Tabelle <span class="emphasis">books_sales</span> wird im Tablespace <span class="emphasis">sales</span> definiert, beansprucht anf&auml;nglich 8&#160;MB und w&auml;chst um mindestens 8&#160;MB, wenn der erste Speicherbereich voll ist. Die Tabelle hat mindestens 1 und maximal 8 Speicherbereiche, wodurch ihre Maximalgr&ouml;&szlig;e auf 64 MB beschr&auml;nkt ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">ORGANIZATION HEAP</span> teilt Oracle mit, dass die Zeilen in der Tabelle physisch in einer beliebigen Reihenfolge gespeichert werden k&ouml;nnen. Optional kann zus&auml;tzlich noch die Klausel <span class="emphasis">segment_characteristic</span> angegeben werden. Alternativ k&ouml;nnen die Zeilen der Tabelle physisch nach einem benannten <span class="emphasis">INDEX</span> sortiert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">CLUSTER</span> wird die Tabelle auf der Basis eines geclusterten Schl&uuml;ssels in ein bestehendes Cluster aufgenommen. (N&auml;heres dazu unter dem Oracle-Befehl <span class="emphasis">CREATE CLUSTER</span>.) Alle Tabellen im Cluster m&uuml;ssen Spalten enthalten, die den Spalten des geclusterten Schl&uuml;ssels entsprechen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">special_storage_clause</span> werden drei verschiedene Arten von Datenspeicher angegeben, die in einer Oracle-Tabelle m&ouml;glich sind: LOB (gro&szlig;e Objekte wie zum Beispiel Bilddateien), Varrays und verschachtelte Tabellen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>{LOB { (LOB_item [,n]) STORE AS {ENABLE | DISABLE} STORAGE IN ROW
      | (LOB_item) STORE AS
           {LOB_segment_name ({ENABLE | DISABLE} STORAGE IN ROW)
           | LOB_segment_name
           | ({ENABLE | DISABLE} STORAGE IN ROW)}
  | VARRAY varray_item STORE AS
  | NESTED TABLE nested_item STORE AS storage_table
      [(physical_characteristics)]
      [RETURN AS {LOCATOR | VALUE}] }</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">LOB</span> definiert die Speicherattribute des LOB-Datensegments. Das LOB-Element ist der Name der LOB-Spalte oder -Spalten, die in der Tabelle deklariert sind. Wird die Klausel <span class="emphasis">ENABLE STORAGE IN ROW</span> verwendet, werden die LOB-Objekte in der Zeile selbst gespeichert, sofern sie kleiner sind als 4000&#160;Byte. Bei <span class="emphasis">DISABLE STORAGE IN ROW</span> erfolgt die Speicherung unabh&auml;ngig von der Gr&ouml;&szlig;e au&szlig;erhalb der Zeile. N&auml;here Informationen &uuml;ber die Speicherung von LOB-Objekten mit <span class="emphasis">LOB_storage_clause</span> finden Sie in der Oracle-Dokumentation. Beispiel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TABLE large_objects
  (pretty_picture BLOB,
   interesting_text CLOB)
STORAGE (INITIAL 256M NEXT 256M)
LOG (pretty_picture, interesting_text)
   STORE AS (TABLESPACE large_object_segment
      STORAGE (INITIAL 512M NEXT 512M)
      NOCACHE LOGGING);</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Tabelle <span class="emphasis">large_objects</span> wird verwendet, um Bilder und Text zu speichern. Die Speichermerkmale sowie die Protokoll- und Caching-Merkmale werden ebenfalls angegeben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Ein Varray ist ein spezielles Oracle-Objekt. In Oracle kann man verschiedene Speicherparameter f&uuml;r LOBs, die in einem Varray gespeichert werden, angeben. Dabei wird im Prinzip dieselbe Syntax verwendet wie bei der Klausel <span class="emphasis">LOB</span>. N&auml;heres zu Varrays finden Sie in der Dokumentation des Herstellers.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle erm&ouml;glicht die Deklaration einer <span class="emphasis">NESTED TABLE</span>-Klausel, in der eine Tabelle virtuell in einer Spalte einer anderen Tabelle gespeichert wird. Mit der Klausel <span class="emphasis">STORE AS</span> kann ein Proxy-Name f&uuml;r die Tabelle in der Tabelle angegeben werden, aber die verschachtelte Tabelle muss zun&auml;chst als benutzerdefinierter Datentyp angelegt werden. Diese M&ouml;glichkeit ist sehr n&uuml;tzlich f&uuml;r sp&auml;rlich besetzte Arrays, ist jedoch f&uuml;r den allt&auml;glichen Gebrauch nicht zu empfehlen. Beispiel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TYPE prop_nested_tbl AS TABLE OF props_nt;

CREATE TABLE proposal_types
   (proposal_category VARCHAR2(50),
   proposals          PROPS_NT)
NESTED TABLE props_nt STORE AS props_nt_table;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle k&ouml;nnen f&uuml;r eine bestimmte Tabelle viele verschiedene Tabellenmerkmale definiert werden. Einige dieser Merkmale sind in der folgenden Liste aufgef&uuml;hrt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>-- table_characteristics
{ PARTITION characteristics }
[CACHE | NOCACHE] [MONITORING | NOMONITORING]
[{NOPARALLEL | PARALLEL [int] }]
[{ENABLE | DISABLE} [VALIDATE | NOVALIDATE]
  {UNIQUE (column [,...n] )
  | PRIMARY KEY
  | CONSTRAINT constraint_name}
[index_clause]
[EXCEPTION INTO [schema.]table_name]
[CASCADE] ]
[AS select_statement]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle verwendet die Klausel <span class="emphasis">PARTITION</span> zur Verbesserung der Leistung, indem die Tabelle &uuml;ber mehrere Partitionen verteilt wird. Die vollst&auml;ndige Syntax aller Permutationen einer Tabellenpartition ist jedoch viel zu lang, um hier wiedergegeben zu werden. Au&szlig;erdem wird sie von den meisten SQL-Programmierneulingen nicht verwendet. N&auml;here Informationen zur Tabellenpartitionierung finden Sie in der Oracle-Dokumentation.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">CACHE</span> wird eine Tabelle f&uuml;r rasch aufeinanderfolgende Lesevorg&auml;nge gepuffert, mit <span class="emphasis">NOCACHE</span> wird genau dies verhindert. <span class="emphasis">CACHE</span>-Verhalten gibt es bei indexorganisierten Tabellen. Mit <span class="emphasis">MONITORING</span> werden zur Leistungsoptimierung Statistiken &uuml;ber die Tabelle zusammengestellt, mit <span class="emphasis">NOMONITORING</span> wird diese Funktion deaktiviert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In der Anweisung <span class="emphasis">CREATE TABLE</span> steht die Klausel <span class="emphasis">INDEX</span> nur f&uuml;r den Prim&auml;rschl&uuml;ssel und die eindeutigen Indizes zur Verf&uuml;gung, die zusammen mit der Tabelle erzeugt werden. In der Oracle-Dokumentation finden Sie umfassende Informationen &uuml;ber die M&ouml;glichkeiten zur Bearbeitung eines Index mit dem Befehl <span class="emphasis">CREATE TABLE</span>. In den meisten F&auml;llen ist es am sinnvollsten, den Befehl <span class="emphasis">CREATE INDEX</span> zu verwenden. (Beachten Sie, dass Oracle f&uuml;r Tabellen mit einem Prim&auml;rschl&uuml;ssel-Constraint automatisch einen Index anlegt. In diesem Fall muss der Benutzer keinen Index erstellen.)</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">PARALLEL</span> erm&ouml;glicht das parallele Erstellen von Tabellen auf verschiedenen CPUs, um die Operation zu beschleunigen. Mit dieser Klausel kann auch festgelegt werden, dass Abfragen und Datenmanipulationsoperationen in der Tabelle parallel ausgef&uuml;hrt werden. Es kann ein optionaler Integerwert angegeben werden, der bestimmt, wie viele parallele Threads in der aktuellen Operation und in Zukunft ausgef&uuml;hrt werden d&uuml;rfen. (Oracle berechnet die optimale Anzahl an Threads f&uuml;r die betreffende parallele Operation selbst, dieses Merkmal ist somit optional.) Mit <span class="emphasis">NOPARALLEL</span>, dem Standard, werden die Tabellen seriell erstellt. Es sind somit auch in Zukunft keine parallelen Abfragen und Datenmanipulationsoperationen m&ouml;glich.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit den Klauseln <span class="emphasis">DISABLE</span> und <span class="emphasis">ENABLE</span> k&ouml;nnen die Constraints f&uuml;r eine Tabelle deaktiviert bzw. aktiviert werden. Im Prinzip kann mit der Klausel <span class="emphasis">DISABLE</span> jeder beliebige aktive Integrit&auml;ts-Contraint oder Trigger deaktiviert werden. Umgekehrt l&auml;sst sich mit <span class="emphasis">ENABLE</span> jeder deaktivierte Integrit&auml;ts-Constraint oder Trigger aktivieren. Die Syntax f&uuml;r diese Klausel sieht folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DISABLE | ENABLE {{UNIQUE(column[,...n] |
   PRIMARY KEY |
   CONSTRAINT constraint_name}
      [CASCADE]}
      [EXCEPTIONS INTO [owner.]table_name]
      [USING INDEX [INITRANS int][MAXTRANS int]
         [TABLESPACE tablespace_name][storage_characteristics]
         [PCTFREE int] |</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Das Schl&uuml;sselwort <span class="emphasis">CASCADE</span>, das nur bei <span class="emphasis">DISABLE</span> verwendet wird, deaktiviert einen kaskadierenden Constraint oder Trigger nicht, sondern kaskadiert das Deaktivieren/Aktivieren aller Integrit&auml;ts-Constraints, die von dem in der Klausel genannten Constraint abh&auml;ngen. Die Klausel <span class="emphasis">EXCEPTIONS INTO</span>, die nur bei <span class="emphasis">ENABLE</span> verwendet wird, fordert Oracle auf, Informationen &uuml;ber Verletzungen von Integrit&auml;ts-Constraints in einer bestehenden Exceptions-Tabelle zu speichern. Die Klausel <span class="emphasis">USING INDEX</span>, die ebenfalls nur bei <span class="emphasis">ENABLE</span> verwendet wird, besitzt einen Mechanismus, mit dem verschiedene Speichermerkmale f&uuml;r den angegebenen Index festgelegt werden k&ouml;nnen, insbesondere f&uuml;r Prim&auml;rschl&uuml;ssel und eindeutige Schl&uuml;ssel. Standardm&auml;&szlig;ig sind alle Constraints aktiviert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">AS SELECT_statement</span> wird die neue Tabelle mit Datens&auml;tzen aus einer g&uuml;ltigen <span class="emphasis">SELECT</span>-Anweisung gef&uuml;llt. Im Gegensatz zur PostgreSQL-Implementierung von <span class="emphasis">CREATE . . . AS SELECT</span> m&uuml;ssen die Spalten der Anweisung <span class="emphasis">CREATE TABLE</span> zu denen in der Anweisung <span class="emphasis">SELECT</span> passen. Das Protokollieren von <span class="emphasis">CREATE . . . AS SELECT</span> kann mit dem Schl&uuml;sselwort <span class="emphasis">NOLOGGING</span> deaktiviert werden. Standardm&auml;&szlig;ig erfolgt eine Protokollierung im Redo-Log.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle unterst&uuml;tzt eine Reihe objektorientierter Funktionsmerkmale, deren Beschreibung hier allerdings zu weit f&uuml;hren w&uuml;rde.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [TEMPORARY | TEMP] TABLE <span class="replaceable">table</span>
<span class="emphasis">(</span>column_name datatype [NULL | NOT NULL] [DEFAULT value]
<span class="emphasis">  </span>|<span class="emphasis"></span>[UNIQUE]
<span class="emphasis">  </span>| [PRIMARY KEY (column[,...n])]
   | [CHECK (expression) ]
   | REFERENCES reference_table (reference_column)
        [MATCH {FULL | PARTIAL | default}]
        [ON DELETE {CASCADE | NO ACTION | RESTRICT | SET NULL | SET
           DEFAULT}]
        [ON UPDATE {CASCADE | NO ACTION | RESTRICT | SET NULL | SET
           DEFAULT}]
        [[NOT] DEFERRABLE] [INITIALLY {DEFERRED | IMMEDIATE}] } [,...n]
|[table_constraint][,...n]
[INHERITS (inherited_table [,...n])]

| [ON COMMIT {DELETE | PRESERVE} ROWS]

| AS <span class="replaceable">SELECT</span>_statement</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL verwendet eine &auml;hnliche Syntax wie MySQL und erlaubt das Erstellen einer tempor&auml;ren Tabelle (<span class="emphasis">TEMPORARY</span>). Tempor&auml;re Tabellen bestehen nur w&auml;hrend der Sitzung, in der sie angelegt wurden. Sie l&ouml;schen sich automatisch selbst, wenn die Sitzung beendet ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Constraints wie <span class="emphasis">UNIQUE</span>, <span class="emphasis">PRIMARY KEY</span> und <span class="emphasis">CHECK</span> sind im Prinzip identisch mit denen in Microsoft SQL Server. Das Besondere bei PostgreSQL ist jedoch die M&ouml;glichkeit, Spalten-Constraints zu definieren, die sich &uuml;ber mehrere Spalten erstrecken. Da PostgreSQL auch normale Constraints auf Tabellenebene unterst&uuml;tzt, ist der ANSI-Standard-Ansatz nach wie vor zu empfehlen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der Constraint <span class="emphasis">REFERENCES</span> &auml;hnelt einem <span class="emphasis">CHECK</span>-Constraint, au&szlig;er dass ein Wert mit Werten in einer anderen Spalte einer anderen Tabelle verglichen wird. Er kann auch als Bestandteil einer <span class="emphasis">FOREIGN KEY</span>-Deklaration verwendet werden. Die <span class="emphasis">MATCH</span>-Optionen hei&szlig;en <span class="emphasis">FULL</span>, <span class="emphasis">PARTIAL</span> und Default (wobei es bei <span class="emphasis">MATCH</span> kein anderes Schl&uuml;sselwort gibt). Bei einer vollst&auml;ndigen &Uuml;bereinstimmung (<span class="emphasis">FULL</span>) m&uuml;ssen alle Spalten eines mehrspaltigen Fremdschl&uuml;ssels entweder <span class="literal">null</span> sein oder einen zul&auml;ssigen Wert enthalten. Standardm&auml;&szlig;ig sind Mischungen aus Nullwerten und anderen Werten zul&auml;ssig. Teilweise &Uuml;bereinstimmung (<span class="emphasis">PARTIAL</span>) ist zwar syntaktisch erlaubt, wird aber nicht unterst&uuml;tzt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">REFERENCES</span> k&ouml;nnen auch verschiedene Verhalten hinsichtlich der referenziellen Integrit&auml;t bei <span class="emphasis">ON DELETE</span> und/oder <span class="emphasis">ON UPDATE</span> deklariert werden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ul><li><i><span class="emphasis">NO ACTION</span></i><br>&#160;
						  Verursacht einen Fehler, wenn der Fremdschl&uuml;ssel verletzt wird (= Standard).</li><li><i><span class="emphasis">RESTRICT</span></i><br>&#160;
						  Ein Synonym f&uuml;r <span class="emphasis">NO ACTION</span>.</li><li><i><span class="emphasis">CASCADE</span></i><br>&#160;
						  Setzt den Wert der referenzierenden Spalte auf den Wert der referenzierten Spalte.</li><li><i><span class="emphasis">SET NULL</span></i><br>&#160;
						  Setzt den Wert der referenzierenden Spalte auf NULL.</li><li><i><span class="emphasis">SET DEFAULT</span></i><br>&#160;
						  Setzt die referenzierende Spalte auf ihren deklarierten Standardwert oder auf <span class="literal">null</span>, wenn ein solcher nicht vorhanden ist.</li></ul>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Option <span class="emphasis">DEFERRABLE</span> der Klausel <span class="emphasis">REFERENCES</span> wird PostgreSQL angewiesen, alle Constraints bis zum Ende der Transaktion zur&uuml;ckzustellen. <span class="emphasis">NOT DEFERRABLE</span> ist das Standardverhalten der Klausel <span class="emphasis">REFERENCES</span>. Die Klausel <span class="emphasis">INITIALLY</span> ist der Klausel <span class="emphasis">DEFERRABLE</span> sehr &auml;hnlich. Bei Angabe von <span class="emphasis">INITIALLY DEFERRED</span> werden die Constraints am Ende einer Transaktion &uuml;berpr&uuml;ft, bei Angabe von <span class="emphasis">INITIALLY IMMEDIATE</span> dagegen nach jeder Anweisung (Standardwert).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Beachten Sie, dass wie bei Microsoft SQL Server alle Constraints auf Spaltenebene auch als Constraints auf Tabellenebene deklariert werden k&ouml;nnen. <span class="emphasis">FOREIGN KEY</span>-Constraints k&ouml;nnen aber nur auf Tabellenebene deklariert werden. Alle Optionen der Klausel <span class="emphasis">REFERENCES</span> werden auch als Bestandteil der Klausel <span class="emphasis">FOREIGN KEYS</span> unterst&uuml;tzt. Die Syntax sieht folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>[FOREIGN KEY (column[,...n]) REFERENCES...]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">INHERITS inherited_table</span> gibt eine oder mehrere Tabellen an, von der die betreffende Tabelle alle Spalten erbt. Die neu erstellte Tabelle erbt auch Funktionen, die zu Tabellen geh&ouml;ren, die in der Hierarchie weiter oben stehen. Wenn eine vererbte Spalte mehrmals erscheint, schl&auml;gt die Anweisung fehl.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn eine tempor&auml;re oder globale tempor&auml;re Tabelle in PostgreSQL angelegt wird, kann die Klausel <span class="emphasis">ON COMMIT</span> an den Befehl angeh&auml;ngt werden. Mit dieser Klausel wird das Verhalten der tempor&auml;ren Tabelle festgelegt, nachdem Datens&auml;tze in dieser festgeschrieben worden sind. Bei <span class="emphasis">ON COMMIT DELETE ROWS</span> werden nach dem Festschreiben alle Zeilen in der tempor&auml;ren Tabelle gel&ouml;scht. Dies ist die Standardeinstellung. Bei <span class="emphasis">ON COMMIT PRESERVE ROWS</span> bleiben die Zeilen in der tempor&auml;ren Tabelle auch nach dem Festschreiben der Transaktion erhalten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">AS SELECT_statement</span> kann der Programmierer eine Tabelle erstellen und mit Daten aus einer zul&auml;ssigen <span class="emphasis">SELECT</span>-Anweisung f&uuml;llen. Es m&uuml;ssen keine Spalten, Datentypen oder Constraints definiert werden, da diese von der Abfrage geerbt werden. Diese Funktionalit&auml;t ist vergleichbar mit der von <span class="emphasis">SELECT . . . INTO</span>, aber die Syntax scheint leichter lesbar zu sein.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel wird der Beispieltabelle ein Fremdschl&uuml;ssel hinzugef&uuml;gt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>-- Constraint auf Spaltenebene
CREATE TABLE favorite_books
   (isbn         CHAR(100)    PRIMARY KEY NONCLUSTERED,
   book_name     VARCHAR(40)  UNIQUE,
   category      VARCHAR(40)  NULL,
   subcategory   VARCHAR(40)  NULL,
   pub_date      DATETIME     NOT NULL,
   purchase_date DATETIME     NOT NULL,
      CONSTRAINT fk_categories FOREIGN KEY (category)
         REFERENCES category(cat_name));</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der Fremdschl&uuml;ssel in der Spalte <span class="emphasis">categories</span> bezieht sich auf die Spalte <span class="emphasis">cat_name</span> in der Tabelle <span class="emphasis">category</span>. Diese Syntax wird von allen in diesem Buch behandelten Herstellern unterst&uuml;tzt. Der Fremdschl&uuml;ssel h&auml;tte auch als mehrspaltiger Schl&uuml;ssel deklariert werden k&ouml;nnen, der sowohl die Spalte <span class="emphasis">category</span> als auch die Spalte <span class="emphasis">subcategory</span> enth&auml;lt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>...
CONSTRAINT fk_categories FOREIGN KEY (category, subcategory)
         REFERENCES category(cat_name, subcat_name));</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Nachfolgend zwei weitere vollst&auml;ndige Beispiele aus der Datenbank <span class="emphasis">pubs</span> (<span class="emphasis">jobs </span>und <span class="emphasis">employee</span>):</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>-- F&uuml;r eine Microsoft SQL Server-Datenbank
CREATE TABLE jobs
   (job_id  SMALLINT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
   job_desc VARCHAR(50) NOT NULL DEFAULT 'New Position',
   min_lvl  TINYINT NOT NULL CHECK (min_lvl &gt;= 10),
   max_lvl  TINYINT NOT NULL CHECK (max_lvl &lt;= 250))

-- F&uuml;r eine MySQL-Datenbank
CREATE TABLE employee
   (emp_id INT AUTO_INCREMENT CONSTRAINT PK_emp_id PRIMARY KEY,
   fname VARCHAR(20) NOT NULL,
   minit CHAR(1) NULL,
   lname VARCHAR(30) NOT NULL,
   job_id SMALLINT NOT NULL DEFAULT 1
      REFERENCES jobs(job_id),
   job_lvl TINYINT DEFAULT 10,
   pub_id CHAR(4) NOT NULL DEFAULT ('9952')
      REFERENCES publishers(pub_id),
   hire_date DATETIME NOT NULL DEFAULT (CURRENT_DATE(  ));

CREATE TABLE publishers
   (pub_id char(4) NOT NULL
      CONSTRAINT UPKCL_pubind PRIMARY KEY CLUSTERED
      CHECK (pub_id IN ('1389', '0736', '0877', '1622', '1756')
      OR pub_id LIKE '99[0-9][0-9]'),
   pub_name varchar(40) NULL,
   city varchar(20) NULL,
   state char(2) NULL,
   country varchar(30) NULL DEFAULT('USA'))</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Nachfolgend ein Beispiel f&uuml;r eine <span class="emphasis">CREATE TABLE</span>-Anweisung in Oracle mit zahlreichen Speichereinstellungen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TABLE classical_music_cds
   (music_id        INT,
   composition      VARCHAR2(50),
   composer         VARCHAR2(50),
   performer        VARCHAR2(50),
   performance_date DATE DEFAULT SYSDATE,
   duration         INT,
   cd_name          VARCHAR2(100),
CONSTRAINT pk_class_cds PRIMARY KEY (music_id)
   USING INDEX TABLESPACE index_ts
   STORAGE (INITIAL 100K NEXT 20K),
CONSTRAINT uq_class_cds UNIQUE (composition, performer, performance_date)
   USING INDEX TABLESPACE index_ts
   STORAGE (INITIAL 100K NEXT 20K))
TABLESPACE tabledata_ts;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CREATE TRIGGER">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CREATE TRIGGER</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p><span class="emphasis"></span>

Ein Trigger ist eine spezielle Art von gespeicherter Prozedur, die automatisch ausgel&ouml;st wird, wenn eine Datenmodifizierungsanweisung ausgef&uuml;hrt wird. Trigger geh&ouml;ren zu einer bestimmten Datenmodifizierungsanweisung (<span class="emphasis">INSERT</span>, <span class="emphasis">UPDATE</span> oder <span class="emphasis">DELETE</span> ) f&uuml;r eine bestimmte Tabelle.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TRIGGER trigger_name
{BEFORE | AFTER} {[DELETE] | [INSERT] | [UPDATE] [OF column [,...n]}
ON table_name
[REFERENCING {OLD [ROW] [AS] old_name | NEW [ROW] [AS] new_name
  OLD TABLE [AS] old_name | NEW TABLE [AS] new_name}]
[FOR EACH { ROW | STATEMENT }]
[WHEN (conditions)]
code block</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Trigger werden standardm&auml;&szlig;ig einmal auf <span class="emphasis">Anweisungsebene</span> ausgel&ouml;st. Mit einer einzigen <span class="emphasis">INSERT</span>-Anweisung k&ouml;nnten also 500 Zeilen in eine Tabelle eingef&uuml;gt werden, ein Insert-Trigger f&uuml;r diese Tabelle wird aber trotzdem nur einmal ausgel&ouml;st. Manche Hersteller erm&ouml;glichen das Ausl&ouml;sen eines Triggers in jeder Zeile einer Datenmanipulationsoperation. In diesem Fall w&uuml;rde also eine Anweisung, die 500 Zeilen in eine Tabelle einf&uuml;gt und einen Trigger auf Zeilenebene hat, den Trigger 500 Mal ausl&ouml;sen, d.&#160;h. einmal pro eingef&uuml;gter Zeile.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Trigger sind nicht nur einer bestimmten Datenmodifizierungsanweisung (<span class="emphasis">INSERT</span>, <span class="emphasis">UPDATE</span> oder <span class="emphasis">DELETE</span>) f&uuml;r eine bestimmte Tabelle zugeordnet, sondern auch einem bestimmten <span class="emphasis">Ausl&ouml;sezeitpunkt</span>. Allgemein gesprochen k&ouml;nnen Trigger vor der Verarbeitung der Datenmanipulationsanweisung (<span class="emphasis">BEFORE</span>), danach (<span class="emphasis">AFTER</span>) oder (sofern dies vom Hersteller unterst&uuml;tzt wird) statt dessen (<span class="emphasis">INSTEAD OF</span>) ausgel&ouml;st werden. Trigger, die vor oder an Stelle der Datenmodifizierungsanweisung ausgel&ouml;st werden, sehen die &Auml;nderungen durch die Anweisung nicht, w&auml;hrend Trigger, die danach ausgel&ouml;st werden, die &Auml;nderungen sehen und mit diesen arbeiten k&ouml;nnen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TRIGGER trigger_name
ON {table_name | view_name}
[WITH ENCRYPTION]
{FOR | AFTER | INSTEAD OF} {[DELETE] [,] [INSERT] [,] [UPDATE]}
[WITH APPEND]
[NOT FOR REPLICATION]
AS
  {
  T-SQL_block
  |
  { IF UPDATE(column) [{AND | OR} UPDATE(column)] [...n]
    |
    IF (COLUMNS_UPDATED(  ) {bitwise_operator} updated_bitmask)
    { comparison_operator} column_bitmask [...n] }
    T-SQL_block [...n]
   }</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt eine Reihe interessanter Funktionsmerkmale in der Anweisung <span class="emphasis">CREATE TRIGGER</span>. Zun&auml;chst einmal erlaubt SQL Server mehrere Trigger f&uuml;r eine bestimmte Datenmanipulationsoperation in einer Tabelle oder einem <span class="emphasis">View</span>. So sind zum Beispiel drei <span class="emphasis">UPDATE</span>-Trigger in einer Tabelle m&ouml;glich.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">WITH ENCRYPTION</span> wird der Text des Triggers an der Stelle verschl&uuml;sselt, an der er in der <span class="emphasis">syscomments</span>-Systemtabelle gespeichert ist. Die Klausel <span class="emphasis">WITH APPEND</span> f&uuml;gt einer Tabelle oder einem View einen weiteren Trigger eines vorhandenen Typs hinzu. Diese Klausel gibt es aus Gr&uuml;nden der R&uuml;ckw&auml;rtskompatibilit&auml;t mit fr&uuml;heren Versionen des Produkts; sie kann nur zusammen mit <span class="emphasis">FOR</span>-Triggern verwendet werden. Mit der Klausel <span class="emphasis">NOT FOR REPLICATION</span> werden Trigger f&uuml;r Datenmanipulationsoperationen, die &uuml;ber die integrierten Replikationsfunktionen von SQL Server aufgerufen werden, deaktiviert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klauseln <span class="emphasis">FOR</span>, <span class="emphasis">AFTER</span> und <span class="emphasis">INSTEAD OF</span> teilen SQL Server mit, wann der Trigger ausgel&ouml;st werden soll. Die Schl&uuml;sselw&ouml;rter <span class="emphasis">FOR</span> und <span class="emphasis">AFTER</span> sind Synonyme und haben dieselbe Funktion. Sie geben an, dass der Trigger erst dann ausgel&ouml;st werden darf, wenn die ausl&ouml;sende Datenmodifizierungsanweisung (und alle kaskadierenden Aktionen und Constraint-&Uuml;berpr&uuml;fungen) erfolgreich ausgef&uuml;hrt wurde. F&uuml;r eine Tabelle sind viele <span class="emphasis">AFTER</span>-Trigger m&ouml;glich. Die Reihenfolge der Trigger ist nicht festgelegt, allerdings k&ouml;nnen der erste und der letzte Trigger mit der gespeicherten Systemprozedur <span class="emphasis">sp_settriggerorder</span> angegeben werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">AFTER</span>-Trigger k&ouml;nnen nicht f&uuml;r Views definiert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">INSTEAD OF </span>funktioniert genauso wie der <span class="emphasis">BEFORE</span>-Trigger in Oracle. Sie gibt an, dass der Trigger vor (und somit an Stelle) der ausl&ouml;senden Datenmodifizierungsanweisung ausgel&ouml;st werden soll. Es ist aber nur ein <span class="emphasis">INSTEAD OF</span>-Trigger pro <span class="emphasis">INSERT</span>-, <span class="emphasis">UPDATE</span>- oder <span class="emphasis">DELETE</span>-Anweisung in einer bestimmten Tabelle m&ouml;glich (mehrere <span class="emphasis">AFTER</span>-Trigger sind jedoch erlaubt). Diese Art von Trigger kann bei Views eingesetzt werden, aber nur, wenn die Klausel <span class="emphasis">WITH CHECK OPTION</span> nicht verwendet wird. <span class="emphasis">INSTEAD OF DELETE</span>-Trigger k&ouml;nnen nicht verwendet werden, wenn die L&ouml;schoperation kaskadiert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit den Spezifikationen <span class="emphasis">DELETE</span>, <span class="emphasis">INSERT</span> und <span class="emphasis">UPDATE</span> wird angegeben, welche Datenmodifizierungsanweisung den Trigger ausl&ouml;st. In SQL Server k&ouml;nnen diese Spezifikationen beliebig kombiniert werden, wobei die einzelnen Optionen mit einem Komma voneinander zu trennen sind. (In diesem Fall wird der gleiche Code f&uuml;r jede angegebene Anweisung ausgef&uuml;hrt.)</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">AS T-SQL_block</span> enth&auml;lt den prozeduralen Code, den der Trigger ausl&ouml;st, wenn die Datenmanipulationsoperation durchgef&uuml;hrt wird. Dieser Abschnitt sollte in die Transact-SQL-Klauseln <span class="emphasis">BEGIN</span> und <span class="emphasis">END</span> eingeschlossen werden. Traditionell enth&auml;lt er Kontrollflussbefehle und fragt die Art und Menge der ge&auml;nderten Daten ab.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>SQL Server instanziiert zwei wichtige Pseudotabellen, wenn ein Trigger ausgel&ouml;st wird: <span class="emphasis">deleted</span> und <span class="emphasis">inserted</span>. Diese Tabellen sind von der Struktur her identisch mit der Tabelle, f&uuml;r die die Trigger definiert sind, au&szlig;er dass sie die alten Daten vor dem Ausl&ouml;sen der Datenmodifizierungsanweisung enthalten (<span class="emphasis">deleted</span>) bzw. die neuen Werte nach dem Ausl&ouml;sen dieser Anweisung (<span class="emphasis">inserted</span>).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Nur <span class="emphasis">INSTEAD OF</span>-Trigger k&ouml;nnen auf <span class="emphasis">text</span>-, <span class="emphasis">ntext</span>- oder <span class="emphasis">image</span>-Spalten zugreifen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">AS IF UPDATE(column) </span>sucht speziell nach <span class="emphasis">INSERT</span>- oder <span class="emphasis">UPDATE</span>-Aktionen f&uuml;r eine oder mehrere bestimmte Spalten. Mehrere Spalten k&ouml;nnen durch Hinzuf&uuml;gen weiterer <span class="emphasis">UPDATE(column)</span>-Klauseln nach der ersten Klausel angegeben werden; danach kommt der Transact-SQL-Block <span class="emphasis">BEGIN . . . END</span> mit den Operationen, die ausgel&ouml;st werden sollen, wenn die Bedingung erf&uuml;llt ist. Diese Klausel funktioniert genau wie die Operation <span class="emphasis">IF . . . THEN . . . ELSE</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">AS IF (COLUMNS_UPDATE( ))</span> hat &Auml;hnlichkeit mit der Klausel <span class="emphasis">AS IF UPDATE( )</span>, weil auch sie nur bei <span class="emphasis">INSERT</span>- oder <span class="emphasis">UPDATE</span>-Operationen in der angegebenen Spalte ausgel&ouml;st wird. Sie gibt ein <span class="emphasis">varbinary</span>-Bitmuster zur&uuml;ck, aus dem hervorgeht, welche Spalten eingef&uuml;gt oder aktualisiert wurden. Dar&uuml;ber hinaus k&ouml;nnen mit Bitoperationen Spaltenwerte auf unterschiedliche Art und Weise verglichen werden. Die Vergleichsoperatoren sind das Gleichheitszeichen (=), mit dem &uuml;berpr&uuml;ft wird, ob alle Spalten in der aktualisierten Bitmaske ge&auml;ndert wurden, und das Gr&ouml;&szlig;er-als-Zeichen (&gt;), mit dem &uuml;berpr&uuml;ft wird, ob eine oder mehrere der Spalten ge&auml;ndert wurden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Trigger werden oft zur Steuerung der deklarativen referenziellen Integrit&auml;t verwendet. Prim&auml;r- und Fremdschl&uuml;sseldeklarationen mit einer <span class="emphasis">CREATE TABLE</span>- oder <span class="emphasis">ALTER TABLE</span>-Anweisung sind jedoch vorzuziehen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>SQL Server l&auml;sst die folgenden Anweisungen im Transact-SQL-Block eines Triggers <span class="emphasis">nicht zu</span>: <span class="emphasis">ALTER</span>, <span class="emphasis">CREATE</span>, <span class="emphasis">DROP</span>, <span class="emphasis">DENY</span>, <span class="emphasis">GRANT</span>, <span class="emphasis">REVOKE</span>, <span class="emphasis">LOAD</span>, <span class="emphasis">RESTORE</span>, <span class="emphasis">RECONFIGURE</span> und <span class="emphasis">TRUNCATE</span>. Dar&uuml;ber hinaus werden weder <span class="emphasis">DISK</span>-Anweisungen noch der Befehl <span class="emphasis">UPDATE STATISTICS</span> unterst&uuml;tzt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In SQL Server ist das <span class="emphasis">rekursive Ausl&ouml;sen von Triggern</span> mit der gespeicherten Systemprozedur <span class="emphasis">sp_dboption</span> m&ouml;glich. Rekursive Trigger l&ouml;sen sich durch ihren eigenen Code selbst erneut aus. Wenn zum Beispiel ein <span class="emphasis">INSERT</span>-Trigger f&uuml;r die Tabelle <span class="emphasis">T1</span> eine <span class="emphasis">INSERT</span>-Operation in der Tabelle <span class="emphasis">T1</span> ausf&uuml;hrt, kann dies zu einer rekursiven Operation f&uuml;hren. Da rekursive Trigger gef&auml;hrlich sind, ist diese Funktionalit&auml;t standardm&auml;&szlig;ig deaktiviert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>SQL Server erlaubt au&szlig;erdem <span class="emphasis">verschachtelte Trigger</span> bis zu einer Tiefe von 32 Ebenen. Wenn einer der verschachtelten Trigger eine <span class="emphasis">ROLLBACK</span>-Operation ausf&uuml;hrt, werden keine weiteren Trigger ausgel&ouml;st. Ein Beispiel f&uuml;r verschachtelte Trigger ist ein Trigger f&uuml;r Tabelle <span class="emphasis">T1</span>, mit dem eine Operation in Tabelle <span class="emphasis">T2</span> ausgel&ouml;st wird, f&uuml;r die wiederum ein Trigger definiert ist, der eine Operation in Tabelle <span class="emphasis">T3</span> ausl&ouml;st. Die Trigger werden abgebrochen, wenn sich eine Endlosschleife bildet. Verschachtelte Trigger werden durch eine Einstellung in der gespeicherten Systemprozedur <span class="emphasis">sp_configure</span> aktiviert. Wenn verschachtelte Trigger deaktiviert werden, werden rekursive Trigger ebenfalls deaktiviert, unabh&auml;ngig davon, was in <span class="emphasis">sp_dboption</span> festgelegt ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">CREATE</span>-Anweisungen in SQL Server erlauben eine <span class="emphasis">verz&ouml;gerte Namensaufl&ouml;sung</span>, was bedeutet, dass der Befehl auch dann verarbeitet wird, wenn er sich auf ein Datenbankobjekt bezieht, das noch nicht in der Datenbank vorhanden ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [OR REPLACE] TRIGGER [owner.]trigger_name
{BEFORE | AFTER | INSTEAD OF}
{[DELETE] [OR] [INSERT] [OR] [UPDATE [OF column [,...n] ]] [...n]}
ON {table_name | view_name}
[REFERENCING {OLD [AS] old_name | NEW [AS] new_name}]
[FOR EACH { ROW | STATEMENT }]
[WHEN (conditions)]
PL/SQL block</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wie f&uuml;r die Anweisung <span class="emphasis">CREATE TRIGGER</span> typisch, wird mit dem Befehl die Datenmodifizierungsoperation (<span class="emphasis">INSERT</span>, <span class="emphasis">UPDATE</span> oder <span class="emphasis">DELETE</span>) angegeben, die den PL/SQL-Codeblock ausf&uuml;hrt, und ob dies vor, nach oder an Stelle der Datenmodifizierungsoperation (<span class="emphasis">BEFORE</span>, <span class="emphasis">AFTER</span> oder <span class="emphasis">INSTEAD OF</span>) geschehen soll. Bei <span class="emphasis">UPDATE</span>-Operationen kann f&uuml;r eine oder mehrere Spalten <span class="emphasis">UPDATE OF</span> angegeben werden, um festzulegen, dass der Update-Trigger nur dann ausgel&ouml;st werden soll, wenn eine dieser Spalten ge&auml;ndert wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle sind <span class="emphasis">INSTEAD OF</span>-Trigger nur bei Views, aber nicht bei Tabellen m&ouml;glich.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle unterst&uuml;tzt auch das Ausl&ouml;sen von Triggern bei bestimmten Datenbankereignissen wie <span class="emphasis">DROP TABLE</span> oder <span class="emphasis">SHUTDOWN</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">REFERENCING</span> wird ein Name f&uuml;r die Pseudotabellen angegeben, die die alten (<span class="emphasis">OLD</span>) und neuen (<span class="emphasis">NEW</span>) Versionen der Tabelle enthalten. (SQL Server nennt diese Pseudotabellen automatisch <span class="emphasis">inserted</span> und <span class="emphasis">deleted.</span>) In Oracle lauten die Standardnamen f&uuml;r diese Pseudotabellen <span class="emphasis">OLD</span>und <span class="emphasis">NEW</span>. Pseudotabellen vergleichen Datensatzwerte, bevor diese von der Datenmanipulationsoperation ge&auml;ndert werden (&uuml;ber die Pseudotabelle <span class="emphasis">OLD</span>) und danach (&uuml;ber die Pseudotabelle <span class="emphasis">NEW</span>). Pseudotabellen f&uuml;hren auch bedingte Operationen im <span class="emphasis">PL/SQL_block</span> aus.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn Werte in den Pseudotabellen <span class="emphasis">OLD</span>  und <span class="emphasis">NEW</span> referenziert werden, muss dem Wert ein Doppelpunkt (:) vorangestellt werden, au&szlig;er in der WHEN-Klausel des Triggers, wo keine Doppelpunkte verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">FOR EACH ROW</span> wird der Trigger aufgefordert, jede einzelne Zeile zu bearbeiten (d.&#160;h. sich f&uuml;r jede von der Operation betroffene Zeile einmal auszul&ouml;sen), und nicht als impliziter Anweisungstrigger zu fungieren (der einmal f&uuml;r die gesamte Transaktion ausgel&ouml;st wird). Die Klausel <span class="emphasis">WHEN</span> gibt eine SQL-Bedingung an, die besagt, dass ein Trigger nur dann ausgef&uuml;hrt werden darf, wenn die Bedingung erf&uuml;llt ist. Die Klausel <span class="emphasis">WHEN</span> bietet auch die M&ouml;glichkeit, die Tabellen <span class="emphasis">OLD</span> und <span class="emphasis">NEW</span> zu vergleichen, ohne dass daf&uuml;r ein PL/SQL-Block erforderlich ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mehrere Trigger k&ouml;nnen zu einem einzigen Triggerbefehl zusammengefasst werden, wenn sie sich auf dieselbe Ebene (Zeile oder Anweisung) und dieselbe Tabelle beziehen. Wenn Trigger in einer Einzelanweisung zusammengefasst werden, k&ouml;nnen im PL/SQL-Block die Klauseln <span class="emphasis">IF INSERTING THEN</span>, <span class="emphasis">IF UPDATING THEN</span> und <span class="emphasis">IF DELETING THEN</span> verwendet werden, um die Codelogik in verschiedene Segmente aufzuteilen. Eine <span class="emphasis">ELSE</span>-Klausel kann in dieser Struktur ebenfalls verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TRIGGER trigger_name
{ BEFORE | AFTER }
{ {[DELETE] [OR | ,] [INSERT] [OR | ,] [UPDATE]} [OR ...] }
ON table_name
FOR EACH { ROW | STATEMENT }
EXECUTE PROCEDURE function_name (parameters)</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die PostgreSQL-Implementierung von <span class="emphasis">CREATE TRIGGER</span> funktioniert &auml;hnlich wie bei anderen Herstellern. Die Trigger k&ouml;nnen vor der Datenmodifizierungsoperation f&uuml;r den Datensatz (<span class="emphasis">BEFORE</span>) oder vor dem Ausl&ouml;sen von Constraints ausgel&ouml;st werden oder aber nachdem (<span class="emphasis">AFTER</span>) die Datenmanipulationsoperation verarbeitet wurde (und alle Constraints &uuml;berpr&uuml;ft wurden), was die in der Transaktion ausgef&uuml;hrten Operationen f&uuml;r den Trigger sichtbar macht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Statt einen prozeduralen Codeblock zu verarbeiten (wie bei Oracle und SQL Server), f&uuml;hrt PostgreSQL &uuml;ber die Klausel <span class="emphasis">EXECUTE PROCEDURE</span> eine mit <span class="emphasis">CREATE FUNCTION</span> erstellte Funktion aus. Andere Hersteller verarbeiten den Trigger dar&uuml;ber hinaus implizit bei allen Zeilen, die von der Transaktion betroffen sind, w&auml;hrend das bei PostgreSQL explizit f&uuml;r jede einzelne Zeile (<span class="emphasis">FOR EACH ROW</span>) oder einmal f&uuml;r die gesamte Transaktion (<span class="emphasis">FOR EACH STATEMENT</span> geschieht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Nachfolgend ein Beispiel f&uuml;r einen <span class="emphasis">BEFORE</span>-Trigger in PostgreSQL, der auf Zeilenebene &uuml;berpr&uuml;ft, ob der angegebene Distributorcode auch in der Tabelle <span class="emphasis">distributors</span> vorhanden ist, bevor eine Zeile in die Tabelle <span class="emphasis">sales</span> eingef&uuml;gt oder dort aktualisiert wird:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TRIGGER if_dist_exists
BEFORE INSERT OR UPDATE ON sales
FOR EACH ROW
EXECUTE PROCEDURE check_primary_key ('did', 'distributors', 'did');</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">BEFORE</span>-Trigger &auml;ndern die Werte, die durch eine Datenmodifizierungsoperation in der Tabelle festgeschrieben werden, da die Verarbeitung der betroffenen Datens&auml;tze stattfindet, bevor diese in der Tabelle ver&auml;ndert werden. <span class="emphasis">AFTER</span>-Trigger werden oft zum Auditing verwendet, weil sie erst dann ausgel&ouml;st werden k&ouml;nnen, wenn die Zeile in der Tabelle ge&auml;ndert wurde. Mit <span class="emphasis">INSTEAD OF</span> wird die Datenmodifizierungsoperation komplett &uuml;bergangen, zu Gunsten des Codes, den der Benutzer f&uuml;r die Transaktion angegeben hat.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Das folgende Beispiel enth&auml;lt einen <span class="emphasis">BEFORE</span>-Trigger in Oracle, der die Pseudotabellen <span class="emphasis">OLD</span> und <span class="emphasis">NEW</span> verwendet, um Werte zu vergleichen. (Zu demselben Zweck verwendet SQL Server die Pseudotabellen <span class="emphasis">DELETED</span> und <span class="emphasis">INSERTED</span>.) Dieser Trigger erzeugt einen Audit-Datensatz, bevor der Gehaltsdatensatz eines Mitarbeiters ge&auml;ndert wird:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TRIGGER if_emp_changes
BEFORE DELETE OR UPDATE ON employee
FOR EACH ROW
WHEN (new.emp_salary &lt;&gt; old.emp_salary)
BEGIN
  INSERT INTO employee_audit
  VALUES ('old', :old.emp_id, :old.emp_salary, :old.emp_ssn);
END;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel wird ein Insert- und Update-Trigger in Oracle erstellt, der die <span class="emphasis">IF INSERTED THEN</span>-Klauseln verwendet:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TRIGGER if_emp_changes
BEFORE DELETE OR UPDATE ON employee
FOR EACH ROW
BEGIN
  IF DELETING THEN
    INSERT INTO employee_audit
    VALUES ('DELETED', :old.emp_id, :old.emp_salary, :old.emp_ssn);
  ELSE
    INSERT INTO employee_audit
    VALUES ('UPDATED', :old.emp_id, :new.emp_salary, :old.emp_ssn);
  END IF;
END;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel f&uuml;r SQL Server wird der Datenbank eine neue Tabelle namens <span class="emphasis">contractor</span> hinzugef&uuml;gt. Alle Datens&auml;tze in der Tabelle <span class="emphasis">employee</span>, aus denen hervorgeht, dass der Mitarbeiter Freiberufler ist, werden in die Tabelle <span class="emphasis">contractor</span> kopiert. Jetzt landen alle neuen Mitarbeiter, die in die Tabelle <span class="emphasis">employee</span> eingef&uuml;gt werden sollen, aufgrund des <span class="emphasis">INSTEAD OF</span>-Triggers statt dessen in der Tabelle <span class="emphasis">contractor</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE TRIGGER if_emp_is_contractor
INSTEAD OF INSERT ON employee
BEGIN
  INSERT INTO contractor
  SELECT * FROM inserted WHERE status = 'CON'

  INSERT INTO employee
  SELECT * FROM inserted WHERE status = 'FTE'
END
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="CREATE VIEW">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">CREATE VIEW</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit dieser

Anweisung wird ein <span class="emphasis">View</span>, auch <span class="emphasis">virtuelle Tabelle</span> genannt, erzeugt. Ein View verh&auml;lt sich wie eine Tabelle, ist aber als Abfrage definiert. Nahezu jede zul&auml;ssige <span class="emphasis">SELECT</span>-Anweisung kann den Inhalt eines Views definieren, aber <span class="emphasis">ORDER BY</span>-Klauseln sind in der Regel nicht zul&auml;ssig.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn ein View in einer Anweisung referenziert wird, wird die Ergebnismenge der Abfrage f&uuml;r die Dauer dieser Anweisung zum Inhalt des Views. In manchen F&auml;llen k&ouml;nnen Views aktualisiert werden, was zur Folge hat, dass die &Auml;nderungen im View  auf die zugrunde liegenden Daten in den Basistabellen &uuml;bertragen werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Views k&ouml;nnen auch auf andere Views aufgesetzt werden. Davon raten wir jedoch ab, weil dies als schlechter Stil betrachtet wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE VIEW view_name [(column list)]
AS
(SELECT_statement
[WITH [CASCADED | LOCAL] CHECK OPTION] )</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Views sind normalerweise genauso effizient wie die Abfrage, auf der sie basieren. Aus diesem Grund muss die definierende <span class="emphasis">SELECT</span>-Anweisung schnell und gut geschrieben sein.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Nach dem Namen des Views kann auch eine <span class="emphasis">Spaltenliste</span> angegeben werden. Die optionale Spaltenliste enth&auml;lt Aliasnamen f&uuml;r die einzelnen Elemente in der Ergebnismenge der <span class="emphasis">SELECT</span>-Anweisung.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">WITH CHECK OPTION </span>wird <span class="emphasis">nur</span> f&uuml;r Views verwendet, die Aktualisierungen der Basistabelle erlauben. Sie stellt sicher, dass nur Daten, die vom View gelesen werden k&ouml;nnen, von diesem eingef&uuml;gt, aktualisiert oder gel&ouml;scht werden d&uuml;rfen. Wenn zum Beispiel ein View von <span class="emphasis">employees</span> nur Mitarbeiter mit Monatsgehalt anzeigt, aber nicht die stundenweise bezahlten Mitarbeiter, ist es nicht m&ouml;glich, stundenweise bezahlte Mitarbeiter &uuml;ber diesen View einzuf&uuml;gen, zu aktualisieren oder zu l&ouml;schen. Die Optionen <span class="emphasis">CASCADE</span> und <span class="emphasis">LOCAL</span> der Klausel <span class="emphasis">CHECK OPTION</span> werden f&uuml;r verschachtelte Views verwendet. Bei Angabe von <span class="emphasis">CASCADE</span> wird <span class="emphasis">CHECK OPTION</span> f&uuml;r den aktuellen View und f&uuml;r alle Views, auf denen er basiert, ausgef&uuml;hrt. Bei Angabe von <span class="emphasis">LOCAL</span> wird <span class="emphasis">CHECK OPTION</span> nur f&uuml;r den aktuellen View ausgef&uuml;hrt, auch wenn dieser auf anderen Views basiert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>ANSI SQL99-Views k&ouml;nnen die Basistabelle oder Basistabellen, auf denen sie basieren, aktualisieren, wenn die folgenden Bedingungen erf&uuml;llt sind:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ol><li>Die definierende <span class="emphasis">SELECT</span>-Anweisung basiert auf genau einer Tabelle.</li><li>Der View verwendet nicht die Operatoren <span class="emphasis">UNION</span>, <span class="emphasis">MINUS</span> oder <span class="emphasis">INTERSECT</span>.</li><li>Die definierende <span class="emphasis">SELECT</span>-Anweisung enth&auml;lt keine <span class="emphasis">GROUP BY</span>- oder <span class="emphasis">HAVING</span>-Klausel.</li><li>Die definierende <span class="emphasis">SELECT</span>-Anweisung enth&auml;lt keine Referenzen auf Pseudospalten wie <span class="emphasis">ROWNUM</span> oder <span class="emphasis">ROWGUIDCOL</span>.</li><li>Die definierende <span class="emphasis">SELECT</span>-Anweisung enth&auml;lt keine Gruppierungsfunktionen.</li><li>Die definierende <span class="emphasis">SELECT</span>-Anweisung enth&auml;lt keine <span class="emphasis">DISTINCT</span>-Klausel.</li></ol>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [owner_name.]VIEW view_name [(column [,...n])]
[WITH {ENCRYPTION | SCHEMABINDING | VIEW_METADATA} [,...n]]
AS
select_statement
[WITH CHECK OPTION]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt zwei neue Optionen, die in SQL99 nicht vorgesehen sind: <span class="emphasis">ENCRYPTION</span> und <span class="emphasis">SCHEMABINDING</span>. Mit der Option <span class="emphasis">ENCRYPTION</span> wird der Text des Views in der Tabelle <span class="emphasis">syscomments</span> verschl&uuml;sselt. Mit der Option <span class="emphasis">SCHEMABINDING</span> wird der View an ein bestimmtes Schema gebunden, was bedeutet, dass alle Objekte in dem View mit ihrem vollst&auml;ndigen Namen (sowohl Name des Eigent&uuml;mers als auch des Objekts) angegeben werden m&uuml;ssen. Wenn mit <span class="emphasis">SCHEMABINDING</span> erzeugte Views (und Tabellen, die diese Views referenzieren) gel&ouml;scht oder ge&auml;ndert werden sollen, muss vorher die Schemabindung (mit <span class="emphasis">ALTER VIEW</span>) gel&ouml;scht werden. Mit <span class="emphasis">VIEW_METADATA</span> wird festgelegt, dass SQL Server Metadaten &uuml;ber den View (und nicht &uuml;ber die Basistabelle) an Aufrufe aus den DBLIB- und OLEDB-APIs zur&uuml;ckgeben soll. In Views, die mit <span class="emphasis">VIEW_METADATA</span> erstellt oder ge&auml;ndert wurden, k&ouml;nnen die Spalten mit <span class="emphasis">INSERT</span>- und <span class="emphasis">UPDATE INSTEAD OF</span>-Triggern aktualisiert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In SQL Server k&ouml;nnen Indizes f&uuml;r Views erstellt werden (siehe <span class="emphasis">CREATE INDEX</span>). Bei Erstellung eines eindeutigen, geclusterten Index f&uuml;r einen View speichert SQL Server praktisch eine physische Kopie des Datenbank-Views. &Auml;nderungen der Basistabelle werden im indizierten View automatisch aktualisiert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Indizierte Views sollten nur mit der Klausel <span class="emphasis">SCHEMABINDING</span> auf Basistabellen aufgesetzt werden. Dies ist eine fortgeschrittene Technik, die nur von Experten angewendet werden sollte. N&auml;here Informationen zu dieser Technik finden Sie in der Dokumentation des Herstellers.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE [OR REPLACE] [FORCE | NO FORCE] VIEW [owner_name.]view_name
  [(column [,...n])]
AS
SELECT_statement
[WITH [READ ONLY | CHECK OPTION [CONSTRAINT constraint_name] ] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">OR REPLACE</span> wird Oracle angewiesen, einen bestehenden View mit demselben Namen durch den neuen View zu ersetzen. Mit der Klausel <span class="emphasis">FORCE</span> wird der View unabh&auml;ngig davon, ob die Basistabellen existieren oder der Benutzer, der den View erzeugt, Zugriffsrechte auf die entsprechenden Basistabellen hat, erstellt. Mit der Klausel <span class="emphasis">NO FORCE</span> wird der View nur dann erstellt, wenn die Basistabellen und die Zugriffsrechte vorhanden sind.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle erlaubt die Verwendung der Klausel <span class="emphasis">CHECK</span>
<span class="emphasis">OPTION</span>; au&szlig;erdem kann mit der Klausel <span class="emphasis">CONSTRAINT</span> ein Constraint benannt werden. Die Klausel <span class="emphasis">CHECK</span> <span class="emphasis">OPTION</span> kann f&uuml;r verschachtelte Views verwendet werden, allerdings nur, wenn <span class="emphasis">CHECK</span> <span class="emphasis">OPTION</span> auch beim obersten View in der Hierarchie verwendet wird. Wenn f&uuml;r den Constraint kein Name angegeben wird, verwendet Oracle den Namen <span class="emphasis">SYS_C</span><span class="emphasis">n</span>, wobei <span class="emphasis">n</span> eine Ganzzahl ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle erm&ouml;glicht Datenmodifizierungsoperationen &uuml;ber Views, sofern die Anforderungen des SQL99-Standards erf&uuml;llt und keine Ausdr&uuml;cke enthalten sind. Die Klausel <span class="emphasis">WITH READ ONLY</span> stellt sicher, dass mit dem View Daten nur gelesen werden k&ouml;nnen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE VIEW view_name AS SELECT_statement</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die <span class="emphasis">CREATE VIEW</span>-Implementierung von PostgreSQL unterst&uuml;tzt manche der komplexeren Optionen anderer Hersteller nicht. Es k&ouml;nnen aber Views f&uuml;r Tabellen und andere definierte Klassenobjekte aufgebaut werden. PostgreSQL-Views werden in der Regel nur auf Tabellen und nicht auf anderen Views aufgebaut und nicht f&uuml;r Datenmodifizierungsoperationen in den zugrunde liegenden Basistabellen verwendet.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der einfachste View basiert auf dem gesamten Inhalt einer einzigen Tabelle:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE VIEW employees
AS
SELECT *
FROM employee_tbl;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Das folgende Beispiel zeigt einen View namens <span class="emphasis">california_authors</span>, der Datenmodifzierungsoperationen erm&ouml;glicht, die nur Autoren in Kalifornien betreffen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE VIEW california_authors
AS
SELECT au_lname, au_fname, city, state
FROM authors
WHERE state = 'CA'
WITH CHECK OPTION
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="DECLARE CURSOR">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">DECLARE CURSOR</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Der Befehl <span class="emphasis">DECLARE CURSOR</span>

erm&ouml;glicht das zeilenweise Abrufen und Bearbeiten von Datens&auml;tzen in einer Tabelle. Damit ist eine zeilenbasierte Verarbeitung m&ouml;glich, die im Gegensatz zur herk&ouml;mmlichen mengenorientierten Verarbeitung in SQL steht. Wenn Sie dieses Verfahren anwenden m&ouml;chten, sollten Sie Folgendes tun:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ol><li>Den Cursor mit <span class="emphasis">DECLARE</span> deklarieren.<ul>
								</ul>
							</li><li>Den Cursor mit <span class="emphasis">OPEN</span> &ouml;ffnen.<ul>
								</ul>
							</li><li>Zeilen mit <span class="emphasis">FETCH</span> aus dem Cursor abrufen.<ul>
								</ul>
							</li><li>Zum Schluss den Cursor mit <span class="emphasis">CLOSE</span> schlie&szlig;en.<ul>
								</ul>
							</li></ol>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>MySQL unterst&uuml;tzt keine serverseitigen Cursor im ANSI SQL-Stil, daf&uuml;r aber umfangreiche C-Programmiererweiterungen, die dieselbe Funktionalit&auml;t bieten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Beim Befehl <span class="emphasis">DECLARE CURSOR</span> wird eine <span class="emphasis">SELECT</span>-Anweisung angegeben. Jede Zeile, die von der <span class="emphasis">SELECT</span>-Anweisung zur&uuml;ckgegeben wird, kann individuell abgerufen und bearbeitet werden. Mit dem Befehl <span class="emphasis">DECLARE CURSOR</span> werden auch die Eigenschaften eines serverseitigen Cursors definiert. Dazu geh&ouml;rt, wie der Cursor scrollt und welche <span class="emphasis">SELECT</span>-Anweisung zum Abrufen der Ergebnismenge verwendet wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server kennt auch die Optionen <span class="emphasis">INSENSITIVE</span>  und <span class="emphasis">SCROLL</span>. Mit dem Schl&uuml;sselwort <span class="emphasis">INSENSITIVE</span> wird angegeben, dass der Cursor eine tempor&auml;re Kopie der vom Cursor verwendeten Ergebnismenge anlegen soll. Alle Anforderungen an den Cursor werden anhand der tempor&auml;ren Tabelle, und nicht anhand der Basistabelle, beantwortet. Der Cursor erm&ouml;glicht keine Modifizierungen. Sp&auml;tere Abrufe durch den Cursor spiegeln keine durch den Cursor vorgenommenen &Auml;nderungen wider. Mit dem Schl&uuml;sselwort <span class="emphasis">SCROLL</span> werden alle <span class="emphasis">FETCH</span>-Optionen f&uuml;r den Cursor (<span class="emphasis">FIRST</span>, <span class="emphasis">LAST</span>, <span class="emphasis">PRIOR</span>, <span class="emphasis">NEXT</span>, <span class="emphasis">RELATIVE</span> und <span class="emphasis">ABSOLUTE</span>) aktiviert. N&auml;heres dazu finden Sie unter dem Befehl <span class="emphasis">FETCH</span>. Wenn <span class="emphasis">SCROLL</span> nicht angegeben ist, steht nur <span class="emphasis">NEXT</span> als <span class="emphasis">FETCH</span>-Option zur Verf&uuml;gung. Mit der Klausel <span class="emphasis">FOR READ ONLY</span> kann auch ein schreibgesch&uuml;tzter Cursor deklariert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle sind keine Variablen in der <span class="emphasis">WHERE</span>-Klausel der <span class="emphasis">SELECT</span>-Anweisung zul&auml;ssig, es sei denn, sie wurden vorher als Variablen deklariert. Die Parameter werden nicht von <span class="emphasis">DECLARE</span>, sondern von <span class="emphasis">OPEN</span> zugewiesen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die PostgreSQL-Implementierung ist der von Microsoft SQL Server sehr &auml;hnlich, au&szlig;er dass zus&auml;tzlich die Option <span class="emphasis">BINARY</span> unterst&uuml;tzt wird. <span class="emphasis">BINARY</span> zwingt den Cursor, bin&auml;rformatierte statt textformatierte Daten abzurufen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Syntax in Microsoft SQL Server</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title"> Syntax in Oracle</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DECLARE CURSOR cursor_name [parameter1 datatype1 [,...parameterN datatypeN]
IS select_statement
[FOR UPDATE [OF column_name [,...n]]}]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Syntax in PostgreSQL</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DECLARE cursor_name [BINARY] [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt das in diesem Kapitel bereits beschriebene Standardformat, bietet jedoch auch eine anspruchsvolle Erweiterung. Die Syntax daf&uuml;r sieht folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DECLARE cursor_name CURSOR
[LOCAL | GLOBAL] [FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC | FAST_FORWARD]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
[TYPE_WARNING]
FOR select_statement
[FOR UPDATE [OF column_name [,...n]]]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Diese Syntax funktioniert genauso wie die Cursor-Deklaration nach dem ANSI-Standard, beinhaltet jedoch viele neue Funktionsmerkmale. Zun&auml;chst einmal kann der G&uuml;ltigkeitsbereich des Cursors als <span class="emphasis">LOCAL</span> oder <span class="emphasis">GLOBAL</span> deklariert werden. Bei <span class="emphasis">LOCAL</span> steht der Cursor nur im aktuellen Transact-SQL-Stapel, in der aktuellen gespeicherten Prozedur oder im aktuellen Trigger, in dem er deklariert wurde, zur Verf&uuml;gung. Bei <span class="emphasis">GLOBAL</span> ist der Cursor w&auml;hrend der Verbindungsdauer &uuml;ber <span class="emphasis">OPEN</span> und <span class="emphasis">FETCH</span> verf&uuml;gbar.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Transact-SQL-Notation sollte nicht mit der Cursor-Deklaration nach dem ANSI-Standard in Microsoft SQL Server verwechselt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit den n&auml;chsten Optionen wird festgelegt, wie der Cursor die Datensatzmenge durchsucht. Mit <span class="emphasis">FORWARD_ONLY</span> wird, im Gegensatz zu <span class="emphasis">SCROLL</span>, festgelegt, dass der Cursor nur vom ersten bis zum letzten Datensatz scrollen kann. Es ist keine Kombination mit <span class="emphasis">STATIC</span>, <span class="emphasis">KEYSET</span> oder <span class="emphasis">DYNAMIC</span> m&ouml;glich. Der Cursor verh&auml;lt sich wie ein <span class="emphasis">DYNAMIC</span>-Cursor.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">STATIC</span> funktioniert &auml;hnlich wie das Schl&uuml;sselwort <span class="emphasis">INSENSITIVE</span>. <span class="emphasis">KEYSET</span> ist vergleichbar mit <span class="emphasis">STATIC</span> und <span class="emphasis">INSENSITIVE</span>, erm&ouml;glicht aber &Auml;nderungen der Ergebnismenge. Das Keyset kann die von anderen Benutzern nach dem &Ouml;ffnen des Cursors eingef&uuml;gten Datens&auml;tze nicht sehen. Datens&auml;tze, die von anderen Benutzern gel&ouml;scht wurden, haben den <span class="emphasis">@@FETCH_STATUS</span> &#8211;2 zur Folge. Neue Werte werden bei der Durchf&uuml;hrung von Aktualisierungen mit <span class="emphasis">WHERE CURRENT OF</span> sichtbar gemacht. <span class="emphasis">DYNAMIC</span> spiegelt alle Daten&auml;nderungen an der Ergebnismenge wider, die w&auml;hrend der Arbeit mit dem Cursor vorgenommen wurden. Die Ergebnismenge kann sich w&auml;hrend jedem <span class="emphasis">FETCH</span> ver&auml;ndern. <span class="emphasis">FETCH ABSOLUTE</span> wird von <span class="emphasis">DYNAMIC</span>-Cursorn nicht unterst&uuml;tzt. <span class="emphasis">FAST_FORWARD</span> ist eine Abk&uuml;rzung f&uuml;r <span class="emphasis">FORWARD_ONLY</span>, <span class="emphasis">READ_ONLY</span>, aktiviert aber auch zus&auml;tzliche Funktionen. <span class="emphasis">FAST_FORWARD</span> kann nicht in Verbindung mit <span class="emphasis">SCROLL</span>, <span class="emphasis">FOR_UPDATE</span>, <span class="emphasis">SCROLL_LOCKS</span>, <span class="emphasis">OPTIMISTIC</span> und <span class="emphasis">FORWARD_ONLY</span> verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Es k&ouml;nnen noch zwei weitere Optionen bei <span class="emphasis">READ_ONLY</span> verwendet werden: <span class="emphasis">SCROLL_LOCKS</span> und <span class="emphasis">OPTIMISTIC</span>. Mit <span class="emphasis">SCROLL_LOCKS</span> wird beim Abruf eines neues Datensatzes eine Datensatzsperre erzwungen. Auf diese Weise wird sichergestellt, dass Aktualisierungen und L&ouml;schungen durch den Cursor auch erfolgreich sind. Mit <span class="emphasis">OPTIMISTIC</span> wird angegeben, dass positionierte Aktualisierungen und L&ouml;schungen durch den Cursor fehlschlagen sollen, wenn die Zeile von einem anderen Benutzer ge&auml;ndert wurde.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Option <span class="emphasis">TYPE_WARNING</span> schlie&szlig;lich wird SQL Server mitgeteilt, dass eine Warnmeldung an den Client gesendet werden soll, wenn der Cursortyp ge&auml;ndert wird (zum Beispiel von <span class="emphasis">KEYSET</span> in <span class="emphasis">DYNAMIC)</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In diesem einfachen Beispiel aus Microsoft SQL Server wird ein Cursor auf der Tabelle <span class="emphasis">publishers</span> deklariert und ge&ouml;ffnet. Der Cursor ruft den ersten Datensatz aus der Tabelle <span class="emphasis">publisher</span> ab, der mit der <span class="emphasis">SELECT</span>-Anweisung &uuml;bereinstimmt, und f&uuml;gt diesen in eine andere Tabelle ein. Dann geht er zum n&auml;chsten Datensatz &uuml;ber usw., bis alle Datens&auml;tze verarbeitet sind. Abschlie&szlig;end wird der Cursor geschlossen und freigegeben (<span class="emphasis">deallocate</span> wird nur bei Microsoft SQL Server verwendet):</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DECLARE @publisher_name VARCHAR(20)

DECLARE pub_cursor CURSOR
FOR SELECT pub_name FROM publishers
    WHERE country &lt;&gt; 'USA'

OPEN pub_cursor
FETCH NEXT FROM pub_cursor INTO @publisher_name
WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO foreign_publishers VALUES(@publisher_name)
END

CLOSE pub_cursor
DEALLOCATE pub_cursor</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Oracle-Beispiel wird der Cursor zusammen mit anderen Variablen im Deklarationsblock definiert. Dann wird der Rest des Cursors verarbeitet:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DECLARE
   new_price NUMBER(10,2);
   CURSOR title_price_cursor IS
      SELECT title, price
      FROM titles
      WHERE price IS NOT NULL;
   title_price_val title_price_cursor%ROWTYPE;
BEGIN
   OPEN title_price_cursor;
   FETCH title_price_cursor INTO title_price_val;
   new_price := "title_price_val.price" * 1.25
   INSERT INTO new_title_price VALUES (title_price_val.title, new_price)
   CLOSE title_price_cursor;
END;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Da in diesem Beispiel viel PL/SQL verwendet wird, w&uuml;rde eine detaillierte Beschreibung des Codes &uuml;ber den Umfang dieses Buches hinausgehen. Der <span class="emphasis">DECLARE</span>-Block zeigt jedoch deutlich, wie der Cursor deklariert wird. Im PL/SQL-Ausf&uuml;hrungsblock wird der Cursor mit dem Befehl <span class="emphasis">OPEN</span> initialisiert. Die Werte werden mit dem Befehl <span class="emphasis">FETCH</span> abgerufen, und der Cursor wird zum Schluss mit dem Befehl <span class="emphasis">CLOSE</span> geschlossen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="DELETE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">DELETE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">DELETE</span>

 werden Datens&auml;tze aus einer oder mehreren Tabellen gel&ouml;scht. Es handelt sich dabei um eine protokollierte Operation, was bedeutet, dass sie mit dem Befehl <span class="emphasis">ROLLBACK</span> r&uuml;ckg&auml;ngig gemacht werden kann.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Eine <span class="emphasis">DELETE</span>-Anweisung wird selten ohne <span class="emphasis">WHERE</span>-Klausel verwendet, da ansonsten <span class="emphasis">alle</span> Zeilen aus der betreffenden Tabelle gel&ouml;scht werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DELETE [FROM] [owner.]table_name [WHERE clause]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Sollte es notwendig sein, alle Zeilen einer Tabelle zu entfernen, verwenden Sie am besten die Anweisung <span class="emphasis">TRUNCATE TABLE</span> . In Datenbanken, die diesen Befehl unterst&uuml;tzen, lassen sich alle Zeilen auf diesem Wege schneller physisch entfernen. Mit <span class="emphasis">TRUNCATE TABLE</span> geht es schneller als mit <span class="emphasis">DELETE</span>, weil <span class="emphasis">TRUNCATE</span> nicht protokolliert wird und somit ein R&uuml;ckg&auml;ngigmachen nicht m&ouml;glich ist. Durch den Wegfall des Protokollierens wird Zeit gespart, was sich besonders beim L&ouml;schen vieler Datens&auml;tze positiv auswirkt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DELETE [FROM] [owner.] {table_name | view_name}
[WITH (query_hint[,...n]]
[FROM table_source[,...n]]
[WHERE clause | [CURRENT OF [GLOBAL] cursor_name]]
[OPTION (query_hint[,...n])]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Microsoft SQL Server k&ouml;nnen Datens&auml;tze sowohl aus Tabellen als auch aus Views, die auf einer einzelnen Tabelle basieren, gel&ouml;scht werden. (Es gibt einige andere Sonderregeln, die das L&ouml;schen aus einem Mehrfachtabellen-View erm&ouml;glichen, diese sind jedoch recht komplex und w&uuml;rden den Rahmen dieses Buches sprengen.) An zwei Stellen im Befehl, d.&#160;h. nach dem ersten <span class="emphasis">FROM</span> und am Ende der Anweisung, kann das Standardverhalten des Optimierers in SQL Server &uuml;berschrieben werden. Dies sollte jedoch nur von Experten vorgenommen werden. Diese Hinweise geh&ouml;ren nicht zum ANSI-Standard, sind aber in der Dokumentation der meisten Hersteller zu finden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>SQL Server erlaubt dar&uuml;ber hinaus eine zweite <span class="emphasis">FROM</span>-Klausel. In dieser zweiten <span class="emphasis">FROM</span>-Klausel k&ouml;nnen <span class="emphasis">JOIN</span>-Anweisungen verwendet werden, so dass auf einfache Art und Weise Zeilen aus der Tabelle im ersten <span class="emphasis">FROM</span> (basierend auf den entsprechenden Zeilen in der im zweiten <span class="emphasis">FROM deklarierten Tabelle)</span> gel&ouml;scht werden k&ouml;nnen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">WHERE CURRENT OF</span> wird f&uuml;r das positionierte L&ouml;schen mit Hilfe eines Cursors verwendet. In Verbindung mit einem Cursor l&ouml;scht diese Form von <span class="emphasis">DELETE</span> nur die Zeile, die durch den Cursor ge&ouml;ffnet wurde.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DELETE [LOW_PRIORITY] FROM table_name [WHERE clause] [LIMIT rows]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>MySQL ist f&uuml;r Geschwindigkeit optimiert. Es besteht die M&ouml;glichkeit, die Option <span class="emphasis">LOW PRIORITY</span> anzugeben, wodurch die Ausf&uuml;hrung von <span class="emphasis">DELETE</span> verz&ouml;gert wird, bis keine anderen Clients mehr aus der Tabelle lesen. In MySQL kann mit der Klausel <span class="emphasis">LIMIT nbr_of_rows</span> auch eine beliebige Obergrenze f&uuml;r die Anzahl der Datens&auml;tze festgelegt werden, die gel&ouml;scht werden, bevor die Kontrolle an den Client zur&uuml;ckgegeben wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DELETE FROM [schema.]{table_name | view_name | snapshot_name}
   {PARTITION (partition_name) | SUBPARTITION (subpartition_name)} |
[WHERE clause]
[subquery WITH {READ ONLY | CHECK OPTION [CONSTRAINT constraint_name]} ]
[RETURNING expression[,...] INTO variable[,...]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle k&ouml;nnen Sie Zeilen aus Tabellen und Views sowie aus partitionierten Views und Tabellen l&ouml;schen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">PARTITION</span> und <span class="emphasis">SUBPARTITION</span> wird der Name der Partition bzw. der Subpartition in der zu l&ouml;schenden Tabelle angegeben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">WITH</span> wird in Verbindung mit einer Unterabfrage verwendet. Sie beschr&auml;nkt die Aktionen der <span class="emphasis">DELETE</span>-Anweisung. Mit der Option <span class="emphasis">WITH READ ONLY</span> wird festgelegt, dass keine der im Befehl verwendeten Unterabfragen aktualisiert werden kann. Mit <span class="emphasis">WITH CHECK OPTION</span> wird Oracle aufgefordert, alle Zeilen zu l&ouml;schen, die nicht in der Unterabfrage enthalten sind.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">RETURNING</span> werden die von dem Befehl betroffenen Zeilen abgerufen. Beim L&ouml;schen einer einzelnen Zeile werden die Werte der Zeile in PL/SQL-Variablen und Bindungsvariablen gespeichert. Beim L&ouml;schen mehrerer Zeilen werden die Werte der Zeilen dagegen in Bindungs-Arrays gespeichert. Mit dem Schl&uuml;sselwort <span class="emphasis">INTO</span> wird festgelegt, dass die gel&ouml;schten Werte in der Variablenliste gespeichert werden sollen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DELETE FROM [ONLY] <span class="replaceable">table</span>
[WHERE {clause | CURRENT OF cursor_name}]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL verwendet den Befehl <span class="emphasis">DELETE</span> zur Entfernung von Zeilen und definierten Unterklassen aus der Tabelle. Wenn Sie Zeilen nur aus der angegebenen Tabelle l&ouml;schen m&ouml;chten, verwenden Sie die Klausel <span class="emphasis">ONLY</span>. Mit der Klausel <span class="emphasis">WHERE CURRENT OF</span> wird PostgreSQL aufgefordert, nur die aktuell ge&ouml;ffnete Zeile des benannten, offenen Cursors zu l&ouml;schen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So l&ouml;schen Sie alle Datens&auml;tze aus der Tabelle <span class="emphasis">titles</span>:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DELETE titles</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So l&ouml;schen Sie alle Datens&auml;tze aus der Tabelle <span class="emphasis">authors</span>, bei denen der Nachname mit "Mc" beginnt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DELETE FROM authors
WHERE au_lname LIKE 'Mc%'</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So l&ouml;schen Sie alle Titel mit einer alten ID-Nummer:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DELETE titles WHERE title_id &gt;= 40</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So l&ouml;schen Sie alle Titel ohne Umsatz:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DELETE titles WHERE ytd_sales IS NULL</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So l&ouml;schen Sie alle Datens&auml;tze aus einer Tabelle anhand der Ergebnisse einer Unterabfrage einer anderen Tabelle (in diesem Fall werden die Datens&auml;tze der Tabelle <span class="emphasis">titleauthor</span> gel&ouml;scht, zu denen es einen passenden Eintrag zum Thema "Computer" in der Tabelle <span class="emphasis">titles</span> gibt):</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DELETE FROM titleauthor
WHERE title_id IN
  (SELECT title_id
  FROM titles
  WHERE title LIKE '%computers%')</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="DISCONNECT">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">DISCONNECT</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">DISCONNECT</span>

 wird die Verbindung zu einem DBMS beendet.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Einschr&auml;nkungen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DISCONNECT {CURRENT | ALL | connection_name}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Dieser Befehl sorgt f&uuml;r die Beendigung einer oder mehrere Verbindungen zwischen dem aktuellen SQL-Prozess und dem Datenbankserver. Mit der Klausel <span class="emphasis">CURRENT</span> wird die gegenw&auml;rtig aktive Benutzerverbindung geschlossen. Mit der Klausel <span class="emphasis">ALL</span> werden alle offenen Verbindungen des aktuellen Benutzers geschlossen. Es ist aber auch m&ouml;glich, nur eine bestimmte Verbindung zu schlie&szlig;en.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt <span class="emphasis">DISCONNECT</span> nur in Embedded-SQL (ESQL), nicht aber in dem Microsoft-Abfragetool SQL Query Analyzer. Es wird die volle SQL99-Syntax unterst&uuml;tzt. Beim Trennen der Verbindung zu Microsoft SQL Server in einem ESQL-Programm sollte der Befehl <span class="emphasis">DISCONNECT ALL</span> verwendet werden, um die Verbindung zum Datenbankserver sauber abzubauen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DISC[ONNECT]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im Gegensatz zu SQL Server erlaubt Oracle den Befehl <span class="emphasis">DISCONNECT</span> <span class="emphasis">nur</span> in seinem Abfragetool SQL*Plus. Hier wird mit dem Befehl die aktuelle Datenbankserversitzung beendet, ansonsten kann der Benutzer aber mit SQL*Plus weiterarbeiten. So kann ein Programmierer zum Beispiel weiter den Puffer bearbeiten, Protokolldateien speichern usw. Es muss jedoch eine neue Verbindung aufgebaut werden, wenn SQL-Befehle verwendet werden sollen. Mit dem Befehl <span class="emphasis">EXIT</span> verlassen Sie SQL*Plus und mit <span class="emphasis">QUIT</span> kehren Sie zu dem Dateisystem zur&uuml;ck.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle unterst&uuml;tzt diese Funktionalit&auml;t auch mit dem Befehl <span class="emphasis">ALTER SYSTEM DISCONNECT SESSION</span>. Es handelt sich dabei jedoch um einen privilegierten Befehl, der nur dem Datenbankadministrator zur Verf&uuml;gung steht, um eine (in der Regel illegitime) Sitzung zwangsweise von der Datenbank zu trennen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL unterst&uuml;tzt den Befehl <span class="emphasis">DISCONNECT</span> nicht explizit. Jede Programmierschnittstelle unterst&uuml;tzt jedoch eine Disconnect-Operation. So steht z.&#160;B. <span class="emphasis">SPI_FINISH</span> im Server Programming Interface und <span class="emphasis">PG_CONNECT</span> im PL/tcl-Programmierpaket zur Verf&uuml;gung.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So beenden Sie die aktuelle Verbindung zu einem Oracle-Server:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DISCONNECT;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt <span class="emphasis">DISCONNECT</span> nur in ESQL-Programmen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>EXEC SQL DISCONNECT new_york;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="DROP DATABASE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">DROP DATABASE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p><span class="emphasis">DROP DATABASE</span>

 macht alle &Auml;nderungen durch den Befehl <span class="emphasis">CREATE DATABASE</span> r&uuml;ckg&auml;ngig. Es werden alle bestehenden Datenbankobjekte gel&ouml;scht und der von ihnen beanspruchte Speicherplatz freigegeben. Bei den meisten Herstellern kann dieser Befehl nicht ausgef&uuml;hrt werden, wenn noch Benutzer (einschlie&szlig;lich Eigent&uuml;mer) in der Datenbank aktiv sind.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP DATABASE database_name</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Genau wie <span class="emphasis">CREATE DATABASE</span> wird auch <span class="emphasis">DROP DATABASE</span> von ANSI SQL nur als Erweiterung und nicht als Kernbefehl unterst&uuml;tzt. SQL99 bevorzugt Befehle im Zusammenhang mit <span class="emphasis">SCHEMA</span> und <span class="emphasis">DOMAIN</span>, um Bereiche abzudecken, die in den meisten Implementierungen grob als "Datenbankangelegenheiten" gelten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die vom Datenbankhersteller erstellten Systemdatenbanken d&uuml;rfen nie gel&ouml;scht werden. Das L&ouml;schen einer Datenbank erfordert explizite Zugriffsrechte, es sei denn, diese Operation wird vom Eigent&uuml;mer der Datenbank oder dem Systemadministrator durchgef&uuml;hrt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP DATABASE database_name [,...n]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In SQL Server k&ouml;nnen mehrere Datenbanken mit demselben Befehl gel&ouml;scht werden, wobei die einzelnen Datenbanknamen mit einem Komma voneinander zu trennen sind. Eine Datenbank kann nur von einem Benutzer in der Master-Datenbank, einem Benutzer mit Administratorrechten oder dem Datenbankeigent&uuml;mer gel&ouml;scht werden. Die Datenbank muss <span class="emphasis">ONLINE</span> sein, damit sie gel&ouml;scht werden kann.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL und PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In MySQL und PostgreSQL wird mit diesem Befehl eine gesamte Datenbank mit allen dazugeh&ouml;rigen Dateien entfernt. Die Datenbank sendet eine Meldung, die angibt, wie viele Dateien gel&ouml;scht wurden. In PostgreSQL kann eine Datenbank, die ge&ouml;ffnet ist und gerade verwendet wird, nicht gel&ouml;scht werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle unterst&uuml;tzt <span class="emphasis">DROP DATABASE</span> nicht. Eine Datenbank kann mit dem Befehl <span class="emphasis">CREATE DATABASE database_name</span> (ohne Parameter) gel&ouml;scht werden. Dabei wird derselbe Name verwendet wie derjenige der zu l&ouml;schenden Datenbank.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="DROP FUNCTION">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">DROP FUNCTION </td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>

Mit diesem Befehl wird eine benutzerdefinierte Funktion aus der aktuellen Datenbank gel&ouml;scht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP FUNCTION function_name {RESTRICT | CASCADE}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit diesem Befehl wird eine Funktion dauerhaft gel&ouml;scht. Die Klausel <span class="emphasis">RESTRICT</span> sorgt daf&uuml;r, dass der Befehl fehlschl&auml;gt, wenn andere Datenbankobjekte wie z.&#160;B. ein View von der Funktion abh&auml;ngig sind. Mit der Option <span class="emphasis">CASCADE</span> hingegen werden die Funktion, alle auf der Funktion basierenden Zugriffsrechte und alle abh&auml;ngigen Datenbankobjekte gel&ouml;scht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP FUNCTION [owner_name.]function_name [,...n]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wie auch bei anderen <span class="emphasis">DROP</span>-Befehlen in SQL Server kann mehr als ein Datenbankobjekt desselben Typs gel&ouml;scht werden, indem die Namen der einzelnen Datenbankobjekte durch Kommas getrennt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit diesem Befehl wird nicht die Datei gel&ouml;scht, die die Funktion enth&auml;lt. Vielmehr wird die Funktionsreferenz aus der Systemtabelle gel&ouml;scht, die sp&auml;ter mit der Anweisung <span class="emphasis">CREATE FUNCTION</span> erneut hinzugef&uuml;gt werden kann.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP FUNCTION [owner_name.]function_name</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wie bei anderen <span class="emphasis">DROP</span>-Befehlen in Oracle kann auch hier der Name des Funktionseigent&uuml;mers angegeben werden. Andernfalls geht Oracle vom Kontext des aktuellen Benutzers aus und sorgt daf&uuml;r, dass nur Funktionen gel&ouml;scht werden, die dem aktuellen Eigent&uuml;mer geh&ouml;ren. Alternativ haben Benutzer mit dem Systemprivileg <span class="emphasis">DROP ANY FUNCTION</span> die M&ouml;glichkeit, jede beliebige Funktion an jeder beliebigen Stelle zu l&ouml;schen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP FUNCTION name ( [ type [,...n] ] )</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In PostgreSQL k&ouml;nnen Funktionen unabh&auml;ngig von der Programmiersprache, in der sie deklariert wurden, gel&ouml;scht werden. <span class="emphasis">Type</span> ist das Eingabeargument der zu l&ouml;schenden Funktion. Dieses Argument muss angegeben werden, da nur die Funktion mit dem angegebenen Namen und den angegebenen Parametertypen gel&ouml;scht wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="DROP INDEX">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">DROP INDEX</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">DROP INDEX</span>

 werden ein oder mehrere Indizes in der aktuellen Datenbank gel&ouml;scht. Wenn ein Index gel&ouml;scht wird, wird sofort der gesamte vorher belegte Speicherplatz freigegeben. Mit <span class="emphasis">DROP INDEX</span> werden jedoch nicht die <span class="emphasis">PRIMARY KEY</span>- oder <span class="emphasis">UNIQUE</span>-Constraints gel&ouml;scht. Dies muss mit dem Befehl <span class="emphasis">ALTER TABLE . . . DROP</span> geschehen. N&auml;here Informationen zu diesen Constraints finden Sie unter dem Befehl <span class="emphasis">CREATE TABLE</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP INDEX table_name.index_name</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL folgt dem SQL99-Standard mit Variationen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP INDEX {table_name | view_name}.index_name [,...n]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Microsoft SQL Server k&ouml;nnen sowohl Indizes f&uuml;r Tabellen als auch f&uuml;r Views gel&ouml;scht werden. Wenn ein geclusterter Index f&uuml;r eine Tabelle, die nicht-geclusterte Indizes enth&auml;lt, gel&ouml;scht wird, werden alle nicht-geclusterten Indizes neu aufgebaut und erhalten neue Zeiger.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen </span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP INDEX table_name.index_name [,...n]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In &auml;lteren MySQL-Versionen ist dieser Befehl nur aus Gr&uuml;nden der Kompatibilit&auml;t enthalten. In neueren Versionen wird der angegebene Index tats&auml;chlich gel&ouml;scht. Diese Anweisung entspricht von der Funktionsweise her der MySQL-Anweisung <span class="emphasis">ALTER TABLE . . . DROP INDEX</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In MySQL k&ouml;nnen mehrere Indizes gleichzeitig gel&ouml;scht werden; dazu m&uuml;ssen die einzelnen Tabellen- und Indexnamen durch Kommas voneinander getrennt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP INDEX [owner_name.]index_name</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle k&ouml;nnen Indizes direkt unter Angabe ihres Namens gel&ouml;scht werden, ohne dass der Tabellenname angegeben werden muss. Oracle bietet auch die M&ouml;glichkeit, den Index anhand des Eigent&uuml;mernamens zu l&ouml;schen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="DROP PROCEDURE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">DROP PROCEDURE </td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>
 Mit diesem Befehl wird eine bestehende gespeicherte Prozedur aus der aktuellen Benutzerdatenbank gel&ouml;scht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP PROCEDURE procedure_name {RESTRICT | CASCADE}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Dieser Befehl entspricht im Wesentlichen <span class="emphasis">DROP FUNCTION</span>, wirkt sich aber auf gespeicherte Prozeduren aus statt auf Funktionen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP PROCEDURE [owner_name.]procedure_name [,...n]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server erm&ouml;glicht das L&ouml;schen mehrerer gespeicherter Prozeduren gleichzeitig. Dazu m&uuml;ssen die einzelnen Namen durch Kommas voneinander getrennt werden. Individuelle Versionen von gespeicherten Prozeduren k&ouml;nnen nicht gel&ouml;scht werden. Es muss stets die gesamte Gruppe von Versionen einer gespeicherten Prozedur gel&ouml;scht werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP PROCEDURE [owner_name.]procedure_name</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle bietet auch die M&ouml;glichkeit, Prozeduren anhand des Eigent&uuml;mernamens zu l&ouml;schen. Benutzer mit dem Systemprivileg <span class="emphasis">DROP ANY PROCEDURE</span> d&uuml;rfen Prozeduren anderer Benutzer l&ouml;schen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="DROP ROLE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">DROP ROLE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>

Mit diesem Befehl wird eine benannte Gruppe von Benutzerprivilegien aus der aktuellen Benutzerdatenbank gel&ouml;scht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP ROLE role_name</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">DROP ROLE</span> wird die angegebene Rolle gel&ouml;scht. Nur Benutzer mit <span class="emphasis">WITH ADMIN OPTION</span> d&uuml;rfen Rollen l&ouml;schen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP ROLE [owner_name.]role_name;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">DROP ROLE</span> wird die Rolle aus der aktuellen Benutzerdatenbank gel&ouml;scht. Sie kann dann nicht mehr von Benutzern oder anderen Rollen verwendet werden, denen die Rolle zugewiesen war.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="DROP TABLE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">DROP TABLE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>

Mit diesem Befehl k&ouml;nnen Sie eine Tabellendefinition und alle mit der Tabelle zusammenh&auml;ngenden Daten, Indizes, Trigger, Constraints und Zugriffsrechte l&ouml;schen. In Views und gespeicherten Prozeduren, die die gel&ouml;schte Tabelle referenzieren, entstehen Probleme, wenn diese nicht explizit ge&auml;ndert oder ebenfalls gel&ouml;scht werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Manche Hersteller lassen es nicht zu, dass eine Tabelle gel&ouml;scht wird, wenn nicht zuerst bestimmte Eigenschaften der Tabelle gel&ouml;scht werden. So muss die Tabelle in Microsoft SQL Server zun&auml;chst von der Replikation ausgeschlossen werden, und die <span class="emphasis">FOREIGN KEY</span>-Referenzen m&uuml;ssen gel&ouml;scht werden, bevor die Tabelle selbst gel&ouml;scht werden kann.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP TABLE table_name RESTRICT | CASCADE</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In der SQL99-Syntax wird mit <span class="emphasis">RESTRICT</span> verhindert, dass das DBMS den Befehl ausf&uuml;hrt, wenn die Tabelle noch von Views oder Constraints referenziert wird. Die Klausel <span class="emphasis">CASCADE</span> sorgt daf&uuml;r, dass zusammen mit der Tabelle auch alle referenzierenden Objekte gel&ouml;scht werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP TABLE [database_name.][owner_name.]table_name [,...n]
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Microsoft SQL Server k&ouml;nnen mehrere Tabellen auf einmal gel&ouml;scht werden. Dazu m&uuml;ssen die einzelnen Tabellennamen durch Kommas voneinander getrennt werden. Tabellen k&ouml;nnen auch in Datenbanken au&szlig;erhalb des aktuellen Kontexts gel&ouml;scht werden, indem der Datenbankname angegeben wird (vorausgesetzt, der Benutzer verf&uuml;gt &uuml;ber die erforderlichen Zugriffsrechte). Zusammen mit der Tabelle werden alle Constraints und Trigger gel&ouml;scht. Explizit deklarierte Regeln und Standardwerte verlieren ihre Bindungen, wenn die zugrunde liegende Tabelle gel&ouml;scht wird. Views und gespeicherte Prozeduren, die auf eine gel&ouml;schte Tabelle verweisen, verursachen einen Fehler, wenn sie ausgef&uuml;hrt werden und die Tabelle nicht mehr vorhanden ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP TABLE [IF EXISTS] table_name;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn dieser Befehl ausgef&uuml;hrt wird, l&ouml;scht MySQL die Tabelle und alle dazugeh&ouml;rigen Dateien vollst&auml;ndig und dauerhaft. Die Klausel <span class="emphasis">IF EXISTS</span> kann angegeben werden, um bei dem Versuch, eine nicht vorhandene Tabelle zu l&ouml;schen, die R&uuml;ckgabe von Fehlern zu verhindern.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP TABLE [owner_name.]table_name [CASCADE CONSTRAINTS];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Beim L&ouml;schen einer Tabelle in Oracle wird der von der Tabelle beanspruchte Speicherplatz freigegeben, und alle noch ausstehenden
&Auml;nderungen werden in der Datenbank festgeschrieben. Wenn eine Tabelle gel&ouml;scht wird, wird sofort der gesamte vorher belegte Speicherplatz frei. Alle mit der Tabelle verbundenen Indizes und Zugriffsrechte gehen verloren. Objekte wie Views, gespeicherte Prozeduren und Synonyme, die auf der Tabelle basieren, werden als ung&uuml;ltig gekennzeichnet und funktionieren nicht mehr.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Beachten Sie, dass in Oracle bei Ausf&uuml;hrung eines <span class="emphasis">ALTER</span>-, <span class="emphasis">CREATE</span>- oder <span class="emphasis">DROP</span>-Befehls alle noch ausstehenden Transaktionen festgeschrieben werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">CASCADE CONSTRAINTS</span> werden alle Integrit&auml;ts-Contraints, die sich auf Schl&uuml;ssel in der gel&ouml;schten Tabelle beziehen, gel&ouml;scht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP TABLE table_name;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL unterst&uuml;tzt nur die Basisfunktionalit&auml;t des Befehls <span class="emphasis">DROP TABLE</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="DROP TRIGGER">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">DROP TRIGGER</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">DROP TRIGGER</span>


 wird ein Trigger f&uuml;r eine Tabelle in der aktuellen Datenbank gel&ouml;scht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP TRIGGER trigger_name</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">DROP TRIGGER</span> wird ein Trigger aus der aktuellen Datenbank gel&ouml;scht. MySQL unterst&uuml;tzt diesen Befehl nicht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP TRIGGER [owner_name.]trigger_name [,...n]
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Microsoft SQL Server k&ouml;nnen mehrere Trigger auf einmal gel&ouml;scht werden, indem die einzelnen Triggernamen durch Kommas voneinander getrennt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP TRIGGER [owner_name.]trigger_name;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle l&ouml;scht den angegebenen Trigger und schreibt noch ausstehende &Auml;nderungen in der Datenbank fest, wenn dieser Befehl ausgef&uuml;hrt wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP TRIGGER trigger_name ON table_name;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL schreibt vor, dass die Tabelle, in der sich der Trigger befindet, angegeben wird. Wenn dieser Befehl ausgef&uuml;hrt wird, werden alle Referenzen auf einen vorhandenen Trigger gel&ouml;scht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="DROP VIEW">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">DROP VIEW</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>

Mit diesem
Befehl wird ein View dauerhaft aus der aktuellen Datenbank gel&ouml;scht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP VIEW view_name RESTRICT | CASCADE</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In der SQL99-Syntax wird dem DBMS mit <span class="emphasis">RESTRICT</span> mitgeteilt, dass der View nicht gel&ouml;scht werden darf, wenn andere Views oder Assertions, die gegenw&auml;rtig auf die Tabelle verweisen, gel&ouml;scht werden sollen. Die Klausel <span class="emphasis">CASCADE</span> sorgt daf&uuml;r, dass zusammen mit dem View auch alle referenzierenden Objekte gel&ouml;scht werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Dieser Befehl wird von MySQL derzeit nicht unterst&uuml;tzt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP VIEW [owner_name.]view_name [,...n]
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Microsoft SQL Server k&ouml;nnen mehrere Views auf einmal gel&ouml;scht werden, indem die einzelnen Viewnamen durch Kommas voneinander getrennt werden. Die Views m&uuml;ssen sich in derselben Datenbank befinden. Informationen &uuml;ber den View werden aus allen Systemtabellen entfernt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP VIEW [owner_name.]view_name;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wie bei anderen <span class="emphasis">DROP</span>-Befehlen in Oracle kann zusammen mit dem Namen des Views der Eigent&uuml;mer angegeben werden. Benutzer mit dem Systemprivileg <span class="emphasis">DROP ANY VIEW</span> d&uuml;rfen Views anderer Benutzer l&ouml;schen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DROP VIEW view_name;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In PostgreSQL k&ouml;nnen mit dem Befehl <span class="emphasis">DROP VIEW</span> Views aus der aktuellen Datenbank gel&ouml;scht werden. Nur der Eigent&uuml;mer des Views darf diesen l&ouml;schen. Mit dem PostgreSQL-Befehl <span class="emphasis">DROP TABLE</span>  k&ouml;nnen ebenfalls Views gel&ouml;scht werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="FETCH">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">FETCH</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Der Befehl <span class="emphasis">FETCH</span>

 ist einer von vier Befehlen, die im Zusammenhang mit Cursorn verwendet werden. Mit <span class="emphasis">FETCH</span> wird eine bestimmte Zeile aus einem serverseitigen Server abgerufen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">FETCH</span> wird ein Datensatz aus dem <span class="emphasis">cursor_name</span> (der mit der Anweisung <span class="emphasis">DECLARE CURSOR</span> erstellt wurde) abgerufen, basierend auf dem Schl&uuml;sselwort <span class="emphasis">NEXT</span>, <span class="emphasis">PRIOR</span>, <span class="emphasis">FIRST</span>, <span class="emphasis">LAST</span>, <span class="emphasis">ABSOLUTE</span> oder <span class="emphasis">RELATIVE</span>. Die mit der Anweisung <span class="emphasis">FETCH</span> abgerufenen Werte k&ouml;nnen optional in Variablen gespeichert werden. Es gibt folgende <span class="emphasis">FETCH</span>-Operationen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ul><li><i><span class="emphasis">NEXT </span></i><br>&#160;
						  Teilt dem Cursor mit, den Datensatz abzurufen, der unmittelbar auf die aktuelle Zeile folgt, und setzt die aktuelle Zeile auf die zur&uuml;ckgegebene Zeile. <span class="emphasis">FETCH NEXT</span> ist das Standardverhalten von <span class="emphasis">FETCH</span>. Hier wird der erste Datensatz abgerufen, wenn es sich um die erste <span class="emphasis">FETCH</span>-Operation bei dem Cursor handelt. (PostgreSQL verwendet das Schl&uuml;sselwort <span class="emphasis">FORWARD</span> oder den String <span class="emphasis">FETCH RELATIVE NEXT</span>.)</li><li><i><span class="emphasis">PRIOR </span></i><br>&#160;
						  Fordert den Cursor auf, den Datensatz abzurufen, der der aktuellen Zeile unmittelbar vorangeht, und setzt die aktuelle Zeile auf die zur&uuml;ckgegebene Zeile. <span class="emphasis">FETCH PRIOR</span> gibt keinen Datensatz zur&uuml;ck, wenn es sich um die erste <span class="emphasis">FETCH</span>-Operation bei dem Cursor handelt. (PostgreSQL verwendet das Schl&uuml;sselwort <span class="emphasis">BACKWARD</span> oder den String <span class="emphasis">FETCH RELATIVE PRIOR</span>.)</li><li><i><span class="emphasis">FIRST </span></i><br>&#160;
						  Fordert den Cursor auf, den ersten Datensatz im Cursor zur&uuml;ckzugeben, und macht ihn zur aktuellen Zeile. (Wird von PostgreSQL nicht unterst&uuml;tzt.)</li><li><i><span class="emphasis">LAST</span></i><br>&#160;
						  Fordert den Cursor auf, den letzten Datensatz im Cursor zur&uuml;ckzugeben, und macht ihn zur aktuellen Zeile. (Wird von PostgreSQL nicht unterst&uuml;tzt.)</li><li><i><span class="emphasis">ABSOLUTE</span> { n } </i><br>&#160;
						  Fordert den Cursor auf, den n-ten Datensatz aus der Ergebnismenge des Cursors vom Anfang her gesehen (wenn n positiv ist) oder vom Ende her gesehen (wenn n negativ ist) zur&uuml;ckzugeben. Der zur&uuml;ckgegebene Datensatz wird zum neuen aktuellen Datensatz des Cursors. Wenn n = 0 ist, werden keine Zeilen zur&uuml;ckgegeben. (Wird von PostgreSQL nicht unterst&uuml;tzt.)</li><li><i><span class="emphasis">RELATIVE</span> { n } </i><br>&#160;
						  Fordert den Cursor auf, den Datensatz zur&uuml;ckzugeben, der sich n Zeilen nach dem aktuellen Datensatz (wenn n positiv ist) oder n Zeilen vor dem aktuellen Datensatz (wenn n negativ ist) befindet. Der zur&uuml;ckgegebene Datensatz wird zur neuen aktuellen Zeile des Cursors. Wenn n = 0 ist, wird die aktuelle Zeile zur&uuml;ckgegeben. (Wird wie beschrieben von PostgreSQL unterst&uuml;tzt, sofern nicht n = 0 ist.)</li></ul>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem Schl&uuml;sselwort <span class="emphasis">INTO</span> k&ouml;nnen Daten aus jeder Spalte im <span class="emphasis">FETCH</span>-Befehl in lokale Variablen eingelesen werden. F&uuml;r jede Spalte im <span class="emphasis">FETCH</span>-Befehl muss es eine entsprechende Variable mit einem passenden Datentyp in der <span class="emphasis">INTO</span>-Klausel geben. (<span class="emphasis">INTO</span> wird von PostgreSQL nicht unterst&uuml;tzt.)</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL-Cursor k&ouml;nnen nur in explizit deklarierten Transaktionen mit Hilfe von <span class="emphasis">BEGIN</span>, <span class="emphasis">COMMIT</span> oder <span class="emphasis">ROLLBACK</span> verwendet werden. In PostgreSQL kann der Benutzer entweder eine bestimmte Anzahl an Datens&auml;tzen durch Angabe der entsprechenden Zahl oder alle Datens&auml;tze durch Angabe des Schl&uuml;sselworts <span class="emphasis">ALL</span> abrufen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>FETCH cursor_name
{INTO variable_name1 [,...n] ]
| BULK COLLECT INTO [collection_name [,...n] }</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle-Cursor sind vorw&auml;rts scrollende Cursor. Sie m&uuml;ssen die abgerufenen Werte entweder in passende Variablen schreiben oder mit der Klausel <span class="emphasis">BULK COLLECT</span> die gesamte Ausgabe binden, bevor sie an den PL/SQL-Parser zur&uuml;ckgegeben wird. <span class="emphasis">FETCH</span> wird oftmals mit einer PL/SQL-<span class="emphasis">FOR</span>-Schleife kombiniert, um alle Zeilen im Cursor zu verarbeiten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>FETCH [ FORWARD | BACKWARD | RELATIVE [ { [ # | ALL | NEXT | PRIOR ] } ]  ]
[ count ]
FROM <span class="replaceable">cursor_name</span></pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL-Cursor k&ouml;nnen nur in explizit deklarierten Transaktionen mit Hilfe von <span class="emphasis">BEGIN</span>, <span class="emphasis">COMMIT</span> oder <span class="emphasis">ROLLBACK</span> verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der Cursor kann vorw&auml;rts (<span class="emphasis">FORWARD</span>), r&uuml;ckw&auml;rts (<span class="emphasis">BACKWARD</span>) oder relativ (<span class="emphasis">RELATIVE</span>) scrollend sein. Die Klausel <span class="emphasis">RELATIVE</span> kann entweder die Anzahl der zur&uuml;ckzugebenden Datens&auml;tze oder das Schl&uuml;sselwort <span class="emphasis">ALL</span> (alle Datens&auml;tze) enthalten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Oracle-Beispiel werden verschiedene Elemente aus dem Cursor <span class="emphasis">employee_new_hires_cursor</span> abgerufen (siehe dazu das Beispiel unter <span class="emphasis">DECLARE CURSOR</span>) und in lokale Variablen gestellt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>FETCH FROM employee_new_hires_cursor
INTO : emp_id, :fname, :lname, :job_id</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem folgenden PostgreSQL-Befehl werden f&uuml;nf Datens&auml;tze aus der Tabelle <span class="emphasis">employee</span> abgerufen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>FETCH FORWARD 5 IN employee_new_hires_cursor;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="GRANT">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">GRANT</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>In SQL99 werden Benutzern und Rollen mit der Anweisung <span class="emphasis">GRANT</span>

  die entsprechenden Rechte zugewiesen, um auf Datenbankobjekte zugreifen und diese verwenden zu k&ouml;nnen. Die meisten Datenbankhersteller verwenden die Anweisung <span class="emphasis">GRANT</span> auch, um Benutzern und Rollen Berechtigungen zur Erstellung von Datenbankobjekten und zur Ausf&uuml;hrung gespeicherter Prozeduren, Funktionen usw. zu erteilen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>GRANT { ALL [PRIVILEGES] }
| SELECT
| INSERT [ (column_name [,...n]) ]
| DELETE
| UPDATE [ (column_name [,...n]) ]
| REFERENCES [ (column_name [,...n]) ]
| USAGE }[,...n]
ON { [TABLE] table_name
| DOMAIN domain_name
| COLLATION collation_name
| CHARACTER SET character_set_name
| TRANSLATION translation_name }
TO {grantee_name |  PUBLIC}
[WITH GRANT OPTION]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">GRANT</span> k&ouml;nnen einem Benutzer von einer dazu berechtigten Person ein oder mehrere Privilegien Privilegien &#8211; <span class="emphasis">SELECT</span>, <span class="emphasis">INSERT</span>, <span class="emphasis">UPDATE</span>, <span class="emphasis">DELETE</span>, <span class="emphasis">REFERENCES</span> oder <span class="emphasis">USAGE</span> &#8211; einger&auml;umt werden. Jedes Privileg erm&ouml;glicht es dem Benutzer, den angegebenen Befehl auszuf&uuml;hren; mit <span class="emphasis">REFERENCES</span> und <span class="emphasis">USAGE</span> hingegen werden andere Privilegien erteilt. Sie haben die M&ouml;glichkeit, mehrere Zugriffsprivilegien
anzugeben, wobei die einzelnen Privilegien durch Kommas voneinander zu trennen sind. Sie k&ouml;nnen auch mit <span class="emphasis">ALL</span> s&auml;mtliche Zugriffsrechte &uuml;bertragen. Das Schl&uuml;sselwort <span class="emphasis">PRIVILEGES </span> ist optional.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Das Privileg <span class="emphasis">USAGE</span> bezieht sich neben einer Tabelle auch auf alle Datenbankobjekte, w&auml;hrend die anderen Privilegien nur f&uuml;r Tabellen gelten. Mit dem Privileg <span class="emphasis">USAGE</span> kann der Benutzer Datenbankobjekte unter Verwendung der Definition eines anderen Objekts erstellen und zum Beispiel eine &Uuml;bersetzung zur Erzeugung einer Sortierung verwenden. Mit dem Privileg <span class="emphasis">REFERENCES</span> kann eine Tabelle in einem Constraint oder einem Fremdschl&uuml;ssel verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Privilegien <span class="emphasis">INSERT</span>, <span class="emphasis">UPDATE</span>und <span class="emphasis">REFERENCES</span> k&ouml;nnen bestimmten Spalten in einer Tabelle zugewiesen werden. Wenn keine Spalten angegeben sind, beziehen sie sich auf alle Spalten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">ON</span> wird die Tabelle oder das Datenbankobjekt deklariert, f&uuml;r die bzw. das der Benutzer Privilegien erh&auml;lt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">TO</span> gibt genau an, welcher Benutzer oder welche Rolle ein bestimmtes Zugriffsrecht erh&auml;lt. Mit <span class="emphasis">PUBLIC</span>hingegen wird das angegebene Privileg allen gegenw&auml;rtigen und zuk&uuml;nftigen Benutzern zugewiesen. Andere Benutzer k&ouml;nnen mit <span class="emphasis">WITH GRANT OPTION</span> autorisiert werden. Diese Klausel teilt der Datenbank mit, dass Benutzer, die ein Zugriffsrecht erhalten, dieses auch an andere Benutzer weitergeben d&uuml;rfen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Je nach Datenbankimplementierung k&ouml;nnen sich die Zugriffsrechte f&uuml;r Views von denen f&uuml;r die zugrunde liegenden Basistabellen unterscheiden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>GRANT { ALL [PRIVILEGES] }
| SELECT
| INSERT
| DELETE
| UPDATE
| REFERENCES
| EXECUTE
| CREATE {DATABASE | DEFAULT | FUNCTION | PROCEDURE | RULE | TABLE | VIEW}
| BACKUP {DATABASE | LOG} } [,...n]
ON { {table_name | view_name} [(column [,...n])]
| stored_procedure_name
| extended_stored_procedure_name
| user_defined_function_name
| [(column [,...n] ON {table_name | view_name} }
TO {grantee_name | PUBLIC} [,...n]
[WITH GRANT OPTION]
[AS {group | role}]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server bietet die M&ouml;glichkeit, einer Tabelle die Zugriffsrechte <span class="emphasis">SELECT</span>, <span class="emphasis">INSERT</span>, <span class="emphasis">UPDATE</span>, <span class="emphasis">DELETE</span> und <span class="emphasis">REFERENCES</span> zuzuweisen. Eine Spaltenliste kann nur f&uuml;r die Zugriffsberechtigungen <span class="emphasis">SELECT</span> und <span class="emphasis">UPDATE</span> angegeben werden. Standardm&auml;&szlig;ig werden allen Spalten die Zugriffsrechte <span class="emphasis">SELECT</span> und <span class="emphasis">UPDATE</span> gew&auml;hrt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Das Privileg <span class="emphasis">EXECUTE</span> kann nur f&uuml;r gespeicherte Prozeduren, erweiterte gespeicherte Prozeduren und benutzerdefinierte Funktionen gew&auml;hrt werden. Um einen <span class="emphasis">FOREIGN KEY</span>-Constraint erstellen zu k&ouml;nnen, muss der Benutzer &uuml;ber das Privileg <span class="emphasis">REFERENCES</span> verf&uuml;gen. Dieses Recht ist auch erforderlich, wenn eine Funktion oder ein View erstellt werden soll, die bzw. der von einem Objekt mit <span class="emphasis">SCHEMABINDING</span> abh&auml;ngig ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">AS</span> werden Privilegien wie in einem anderen Gruppen- oder Rollenkontext gew&auml;hrt. Da Gruppen und Rollen den Befehl <span class="emphasis">GRANT</span> nicht ausf&uuml;hren k&ouml;nnen, lassen sich auf diese Art und Weise schnell und einfach Privilegien an Personen au&szlig;erhalb der Gruppe oder Rolle zuweisen. Privilegien d&uuml;rfen nicht in einer anderen Datenbank als dem aktuellen Datenbankkontext gew&auml;hrt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Zun&auml;chst werden den Benutzern Emily und Sarah mit <span class="emphasis">CREATE DATABASE</span> und <span class="emphasis">CREATE TABLE</span> Zugriffsrechte erteilt. Als n&auml;chstes werden der Gruppe "editors" verschiedene Zugriffsrechte f&uuml;r die Tabelle <span class="emphasis">titles</span> gew&auml;hrt. Die Mitglieder dieser Gruppe k&ouml;nnen diese Rechte dann an andere weitergeben:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>GRANT CREATE DATABASE, CREATE TABLE TO emily, sarah
GO

GRANT SELECT, INSERT, UPDATE, DELETE ON titles
TO editors
WITH GRANT OPTION
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>GRANT { ALL PRIVILEGES
| SELECT
| INSERT [ (column_name [,...n]) ]
| DELETE
| UPDATE [ (column_name [,...n]) ]
| REFERENCES [ (column_name [,...n]) ]
| USAGE
| ALTER
| CREATE
| DROP
| FILE
| INDEX
| PROCESS
| RELOAD
| SHUTDOWN }[,...n]
ON {table_name | * | *.* | database_name.*}
TO grantee_name [IDENTIFIED BY 'password'] [,...n]
[WITH GRANT OPTION]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>MySQL bietet noch weitere Zugriffsprivilegien, insbesondere im Zusammenhang mit der Bearbeitung von Objekten in einer Datenbank. Wie bei den anderen Privilegien d&uuml;rfen die Benutzer den gleichnamigen Befehl (wie <span class="emphasis">ALTER</span>, <span class="emphasis">CREATE</span>, <span class="emphasis">INDEX</span> oder <span class="emphasis">RELOAD</span>) ausf&uuml;hren. <span class="emphasis">REFERENCES</span> wird unterst&uuml;tzt, hat aber keine Funktionalit&auml;t. Mit <span class="emphasis">USAGE</span> werden die Privilegien eines Benutzers <span class="emphasis">deaktiviert</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die folgenden Zugriffsrechte k&ouml;nnen bei Tabellen verwendet werden: <span class="emphasis">SELECT</span>, <span class="emphasis">INSERT</span>, <span class="emphasis">UPDATE</span>, <span class="emphasis">DELETE</span>, <span class="emphasis">CREATE</span>, <span class="emphasis">DROP</span>, <span class="emphasis">GRANT</span>, <span class="emphasis">INDEX</span> und <span class="emphasis">ALTER</span>. <span class="emphasis">INSERT</span>, <span class="emphasis">UPDATE</span> und <span class="emphasis">SELECT</span> k&ouml;nnen auch auf Spaltenebene eingesetzt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die MySQL-Implementierung der Klausel <span class="emphasis">ON</span> kennt einige interessante Optionen. Mit <span class="emphasis">ON *.*</span> k&ouml;nnen globale Privilegien eingestellt werden, die dann f&uuml;r alle Datenbanken auf dem Server gelten. Datenbankweite Privilegien k&ouml;nnen Sie mit <span class="emphasis">ON database_name.*</span> bzw. <span class="emphasis">ON *</span> f&uuml;r die aktuelle Datenbank festlegen. Host-, Tabellen-, Datenbank- und Spaltennamen d&uuml;rfen aus maximal 60 Zeichen bestehen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>MySQL erlaubt es, einem bestimmten Benutzer auf einem bestimmten Host Rechte zu gew&auml;hren, wenn der <span class="emphasis">grantee_name</span> das Format <span class="emphasis">USER@HOST</span> aufweist. In einem <span class="emphasis">grantee_name</span> k&ouml;nnen Wildcards verwendet werden, um mehreren Benutzer auf einmal Zugriffsrechte zu erteilen. Der <span class="emphasis">grantee_name</span> darf aus maximal 16 Zeichen bestehen. Wenn Sie den Benutzer angeben, k&ouml;nnen Sie mit der Klausel <span class="emphasis">IDENTIFIED BY</span> einen Kennwortschutz erzwingen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel werden zwei Benutzern mit Kennw&ouml;rtern Zugriffsrechte gew&auml;hrt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>GRANT SELECT ON employee TO Dylan IDENTIFIED BY 'porsche',
  kelly IDENTIFIED BY 'mercedes',
  emily IDENTIFIED BY 'saab';</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>GRANT { ALL [PRIVILEGES] }
{| GRANT ANY PRIVILEGE }
{| SELECT | INSERT  | DELETE | UPDATE | REFERENCES }
{| CREATE [ANY] {CLUSTER | CONTEXT | DATABASE| DATABASE LINK | DIMENSION
   | DIRECTORY | INDEXTYPE | INDEX | LIBRARY | OPERATOR | OUTLINE
   | PROCEDURE | PROFILE | ROLE | ROLLBACK SEGMENT | SEQUENCE | SESSION
   | SNAPSHOT | SYNONYM | TABLE | TABLESPACE | TRIGGER | TYPE |
   | USER | [MATERIALIZED] VIEW}
| DROP [ANY] {...as CREATE...}
| ALTER [ANYh] {...as CREATE...}
| AUDIT SYSTEM
| EXECUTE [ANY] {INDEXTYPE | OPERATOR | PROCEDURE | TYPE
| BACKUP [ANY] {TABLE | DATABASE | LOG} } [,...n] }
ON { [schema_name.]
{table_name | view_name} [ (column [,...n]) ]
| stored_procedure_name
| extended_stored_procedure_name
| user_defined_function_name
| DIRECTORY directory_name
| JAVA {SOURCE | RESOURCE} [schema_name.]object_name }
TO {{grantee_name | role_name} [,...n] | PUBLIC}
[WITH ADMIN OPTION];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Hier sieht man ganz deutlich, dass der Befehl <span class="emphasis">GRANT</span> in Oracle sehr umfangreich ist. Dabei zeigt die Syntax oben noch nicht einmal alle Permutationen dieser Anweisung. Beachten Sie, dass es bei<span class="emphasis">GRANT</span> zwei allgemeine Klassen von Privilegien gibt: Objektprivilegien (wie das Privileg, in einer bestimmten Tabelle <span class="emphasis">SELECT</span>- oder <span class="emphasis">DELETE</span>-Operationen auszuf&uuml;hren) und Systemprivilegien (wie <span class="emphasis">CREATE CLUSTER</span> oder <span class="emphasis">DROP ANY TABLE</span>).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle k&ouml;nnen Objekt- und Systemprivilegien nicht in einem <span class="emphasis">GRANT</span>-Befehl kombiniert werden. Es ist zwar m&ouml;glich, in einem <span class="emphasis">GRANT</span>-Befehl einem einzelnen Benutzer oder einer Rolle mehrere Objektprivilegien oder Systemprivilegien zuzuweisen, aber mit einem <span class="emphasis">GRANT</span>-Befehl k&ouml;nnen nicht Objekt- und Systemprivilegien gleichzeitig erteilt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In einem <span class="emphasis">GRANT</span>-Befehl ist nahezu jedes von Oracle unterst&uuml;tzte Funktionsmerkmal zul&auml;ssig. Privilegien k&ouml;nnen nicht nur f&uuml;r Datenbankobjekte (wie Tabellen und Views) und Systembefehle (wie <span class="emphasis">CREATE ANY TABLE</span>) gew&auml;hrt werden, sondern auch f&uuml;r Schemaobjekte (wie <span class="emphasis">DIRECTORY</span>, <span class="emphasis">JAVA SOURCE</span> und <span class="emphasis">RESOURCE</span>).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Option <span class="emphasis">ANY</span> wird das Privileg zur Ausf&uuml;hrung einer bestimmten Anweisung f&uuml;r Objekte eines bestimmten Typs erteilt, die einem beliebigen Benutzer im Schema geh&ouml;ren. Eine umfassendere Liste der Systemprivilegien in Oracle finden Sie in Tabelle 3.2.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Kategorie</th><th>Systemprivileg</th><th>Beschreibung</th></tr>
								<tr><td>CLUSTER</td><td>CREATE CLUSTER</td><td>Gew&auml;hrt das Privileg, ein Cluster im eigenen Schema erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANY CLUSTER</td><td>Gew&auml;hrt das Privileg, ein Cluster in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANY CLUSTER</td><td>Gew&auml;hrt das Privileg, Cluster in einem beliebigen Schema zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY CLUSTER</td><td>Gew&auml;hrt das Privileg, Cluster in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr><td>CONTEXT</td><td>CREATE ANY CONTEXT</td><td>Gew&auml;hrt das Privileg, beliebige Kontext-Namespaces zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY CONTEXT</td><td>Gew&auml;hrt das Privileg, beliebige Kontext-Namespaces zu l&ouml;schen.</td>
								</tr>
								<tr><td>DATABASE</td><td>ALTER DATABASE</td><td>Gew&auml;hrt das Privileg, die Datenbank zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>ALTER SYSTEM</td><td>F&uuml;hrt <span class="emphasis">ALTER SYSTEM</span>-Anweisungen aus.</td>
								</tr>
								<tr>
									<td /><td>AUDIT SYSTEM</td><td>F&uuml;hrt <span class="emphasis">AUDIT</span> <span class="emphasis">sql_statements</span>-Anweisungen aus.</td>
								</tr>
								<tr><td>DATABASE LINKS</td><td>CREATE DATABASE LINK</td><td>Gew&auml;hrt das Privileg, private Datenbankverkn&uuml;pfungen im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE PUBLICDATABASE LINK</td><td>Gew&auml;hrt das Privileg, &ouml;ffentlicheDatenbankverkn&uuml;pfungen zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>DROP PUBLICDATABASE LINK</td><td>Gew&auml;hrt das Privileg, &ouml;ffentlicheDatenbankverkn&uuml;pfungen zu l&ouml;schen.</td>
								</tr>
								<tr><td>DIMENSIONS</td><td>CREATE DIMENSION</td><td>Gew&auml;hrt das Privileg, Dimensionen im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANYDIMENSION</td><td>Gew&auml;hrt das Privileg, Dimensionen in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANYDIMENSION</td><td>Gew&auml;hrt das Privileg, Dimensionen in einem beliebigen Schema zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP ANYDIMENSION</td><td>Gew&auml;hrt das Privileg, Dimensionen in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr><td>DIRECTORIES</td><td>CREATE ANYDIRECTORY</td><td>Gew&auml;hrt das Privileg, Verzeichnisdatenbankobjekte zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>DROP ANYDIRECTORY</td><td>Gew&auml;hrt das Privileg, Verzeichnis-datenbankobj
ekte zu l&ouml;schen.</td>
								</tr>
								<tr><td>INDEXTYPES</td><td>CREATE INDEXTYPE</td><td>Gew&auml;hrt das Privileg, einen Indextyp im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANYINDEXTYPE</td><td>Gew&auml;hrt das Privileg, einen Indextyp in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANYINDEXTYPE</td><td>&Auml;ndert Indextypen in einem beliebigen Schema.</td>
								</tr>
								<tr>
									<td /><td>DROP ANYINDEXTYPE</td><td>Gew&auml;hrt das Privileg, einen Indextyp in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>EXECUTE ANYINDEXTYPE</td><td>Referenziert einen Indextyp in einem beliebigen Schema.</td>
								</tr>
								<tr><td>INDEXES</td><td>CREATE ANY INDEX</td><td>Gew&auml;hrt das Privileg, einen Domain-Index in einem beliebigen Schema oder einen Index f&uuml;r eine beliebige Tabelle in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANY INDEX</td><td>Gew&auml;hrt das Privileg, Indizes in einem beliebigen Schema zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY INDEX</td><td>Gew&auml;hrt das Privileg, Indizes in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>QUERY REWRITE</td><td>Aktiviert das Neuschreiben mit einem materialisierten View oder erstellt einen funktionsbasierten Index, wenn der materialisierte View oder Index auf Tabellen und Views im eigenen Schema des Benutzers verweist.</td>
								</tr>
								<tr>
									<td /><td>GLOBAL QUERY REWRITE</td><td>Aktiviert das Neuschreiben mit einem materialisierten View oder erstellt einen funktionsbasierten Index, wenn der materialisierte View oder Index auf Tabellen oder Views in einem beliebigen Schema verweist.</td>
								</tr>
								<tr><td>LIBRARIES</td><td>CREATE LIBRARY</td><td>Gew&auml;hrt das Privileg, externe Prozedur- oder Funktionsbibliotheken im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANY LIBRARY</td><td>Gew&auml;hrt das Privileg, externe Prozedur- oder Funktionsbibliotheken in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>DROP LIBRARY</td><td>Gew&auml;hrt das Privileg, externe Prozedur- oder Funktionsbibliotheken im eigenen Schema zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY LIBRARY</td><td>Gew&auml;hrt das Privileg, externe Prozedur- oder Funktionsbibliotheken in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr><td>MATERIALIZED VIEWS (identisch mit SNAPSHOTS)</td><td>CREATE MATERIALIZED VIEW</td><td>Gew&auml;hrt das Privileg, einen materialisierten View im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANY MATERIALIZED VIEW</td><td>Gew&auml;hrt das Privileg, materialisierte Views in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANY MATERIALIZED VIEW</td><td>Gew&auml;hrt das Privileg, materialisierte Views in einem beliebigen Schema zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY MATERIALIZED VIEW</td><td>Gew&auml;hrt das Privileg, materialisierte Views in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>GLOBAL QUERY REWRITE</td><td>Aktiviert das Neuschreiben mit einem materialisierten View oder erstellt einen funktionsbasierten Index, wenn der materialisierte View oder Index auf Tabellen oder Views in einem beliebigen Schema verweist.</td>
								</tr>
								<tr>
									<td /><td>QUERY REWRITE</td><td>Aktiviert das Neuschreiben mit einem materialisierten View oder erstellt einen funktionsbasierten Index, wenn der materialisierte View oder Index auf Tabellen und Views im eigenen Schema verweist.</td>
								</tr>
								<tr><td>OPERATORS</td><td>CREATE OPERATOR</td><td>Gew&auml;hrt das Privileg, einen Operator und dessen Bindungen im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANYOPERATOR</td><td>Gew&auml;hrt das Privileg, einen Operator und dessen Bindungen in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY OPERATOR</td><td>Gew&auml;hrt das Privileg, einen Operator in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>EXECUTE ANYOPERATOR</td><td>Referenziert einen Operator in einem beliebigen Schema.</td>
								</tr>
								<tr><td>OUTLINES</td><td>CREATE ANY OUTLINE</td><td>Gew&auml;hrt das Privileg, Outlines zu erstellen, die in einem beliebigen Schema, das Outlines benutzt, verwendet werden k&ouml;nnen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANY OUTLINE</td><td>Modifiziert Outlines.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY OUTLINE</td><td>Gew&auml;hrt das Privileg, Outlines zu l&ouml;schen.</td>
								</tr>
								<tr><td>PROCEDURES</td><td>CREATE PROCEDURE</td><td>Gew&auml;hrt das Privileg, gespeicherte Prozeduren, Funktionen und Packages im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANYPROCEDURE</td><td>Gew&auml;hrt das Privileg, gespeicherte Prozeduren, Funktionen und Packages in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANYPROCEDURE</td><td>Gew&auml;hrt das Privileg, gespeicherte Prozeduren, Funktionen oder Packages in einem beliebigen Schema zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP ANYPROCEDURE</td><td>Gew&auml;hrt das Privileg, gespeicherte Prozeduren, Funktionen oder Packages in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>EXECUTE ANYPROCEDURE</td><td>F&uuml;hrt Prozeduren oder Funktionen (alleine oder in einem Paket) aus.</td>
								</tr>
								<tr><td>PROFILES</td><td>CREATE PROFILE</td><td>Gew&auml;hrt das Privileg, Profile zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER PROFILE</td><td>Gew&auml;hrt das Privileg, Profile zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP PROFILE</td><td>Gew&auml;hrt das Privileg, Profile zu l&ouml;schen.</td>
								</tr>
								<tr><td>ROLES</td><td>CREATE ROLE</td><td>Gew&auml;hrt das Privileg, Rollen zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANY ROLE</td><td>Gew&auml;hrt das Privileg, eine beliebige Rolle in der Datenbank zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY ROLE</td><td>Gew&auml;hrt das Privileg, Rollen zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>GRANT ANY ROLE</td><td>Gew&auml;hrt eine beliebige Rolle in der Datenbank.</td>
								</tr>
								<tr><td>ROLLBACK SEGMENTS</td><td>CREATE ROLLBACK SEGMENT</td><td>Gew&auml;hrt das Privileg, Rollback-Segmente zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ROLLBACK SEGMENT</td><td>Gew&auml;hrt das Privileg, Rollback-Segmente zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP ROLLBACK SEGMENT</td><td>Gew&auml;hrt das Privileg, Rollback-Segmente zu l&ouml;schen.</td>
								</tr>
								<tr><td>SEQUENCES</td><td>CREATE SEQUENCE</td><td>Gew&auml;hrt das Privileg, Sequenzen im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANY SEQUENCE</td><td>Gew&auml;hrt das Privileg, Sequenzen in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANY SEQUENCE</td><td>Gew&auml;hrt das Privileg, eine beliebige Sequenz in der Datenbank zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY SEQUENCE</td><td>Gew&auml;hrt das Privileg, Sequenzen in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>SELECT ANY SEQUENCE</td><td>Referenziert Sequenzen in einem beliebigen Schema.</td>
								</tr>
								<tr><td>SESSIONS</td><td>CREATE SESSION</td><td>Stellt eine Verbindung zur Datenbank her.</td>
								</tr>
								<tr>
									<td /><td>ALTER RESOURCE COST</td><td>Legt die Kosten f&uuml;r Sitzungsressourcen fest.</td>
								</tr>
								<tr>
									<td /><td>ALTER SESSION</td><td>F&uuml;hrt <span class="emphasis">ALTER SESSION</span>-Anweisungen aus.</td>
								</tr>
								<tr>
									<td /><td>RESTRICTED SESSION</td><td>F&uuml;hrt eine Anmeldung durch, sobald die Instanz mit der SQL*Plus-Anweisung<span class="emphasis"> STARTUP RESTRICT</span> gestartet wurde.</td>
								</tr>
								<tr><td>SNAPSHOTS (identisch mit MATERIALIZED VIEWS)</td><td>CREATE SNAPSHOT</td><td>Gew&auml;hrt das Privileg, Snapshots im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANYSNAPSHOT</td><td>Gew&auml;hrt das Privileg, Snapshots in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANY SNAPSHOT</td><td>Gew&auml;hrt das Privileg, einen beliebigen Snapshot in der Datenbank zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY SNAPSHOT</td><td>Gew&auml;hrt das Privileg, Snapshots in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>GLOBAL QUERY REWRITE</td><td>Aktiviert das Neuschreiben mit einem Snapshot oder erstellt einen funktionsbasierten Index, wenn der Snapshot oder Index auf Tabellen oder Views in einem beliebigen Schema verweist.</td>
								</tr>
								<tr>
									<td /><td>QUERY REWRITE</td><td>Aktiviert das Neuschreiben mit einem Snapshot oder erstellt einen funktionsbasierten Index, wenn der Snapshot oder Index auf Tabellen und Views im eigenen Schema verweist.</td>
								</tr>
								<tr><td>SYNONYMS</td><td>CREATE SYNONYM</td><td>Gew&auml;hrt das Privileg, Synonyme im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANY SYNONYM</td><td>Gew&auml;hrt das Privileg, Synonyme in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE PUBLIC SYNONYM</td><td>Gew&auml;hrt das Privileg, &ouml;ffentliche Synonyme zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY SYNONYM</td><td>Gew&auml;hrt das Privileg, private Synonyme in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>DROP PUBLIC SYNONYM</td><td>Gew&auml;hrt das Privileg, &ouml;ffentliche Synonyme zu l&ouml;schen.</td>
								</tr>
								<tr><td>TABLES</td><td>CREATE ANY TABLE</td><td>Gew&auml;hrt das Privileg, Tabellen in einem beliebigen Schema zu erstellen. Der Eigent&uuml;mer des Schemas, das die Tabelle enth&auml;lt, muss &uuml;ber gen&uuml;gend Tablespace verf&uuml;gen, damit die Tabelle erstellt werden kann.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANY TABLE</td><td>Gew&auml;hrt das Privileg, eine beliebige Tabelle oder einen View im Schema zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>BACKUP ANY TABLE</td><td>Verwendet das Export-Dienstprogramm, um Objekte aus dem Schema anderer Benutzer zu exportieren.</td>
								</tr>
								<tr>
									<td /><td>DELETE ANY TABLE</td><td>L&ouml;scht Zeilen aus Tabellen, Tabellenpartitionen oder Views in einem beliebigen Schema.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY TABLE</td><td>Gew&auml;hrt das Privileg, Tabellen oder Tabellenpartitionen in einem beliebigen Schema zu l&ouml;schen oder zu leeren.</td>
								</tr>
								<tr>
									<td /><td>INSERT ANY TABLE</td><td>F&uuml;gt Zeilen in Tabellen und Views in einem beliebigen Schema ein.</td>
								</tr>
								<tr>
									<td /><td>LOCK ANY TABLE</td><td>Sperrt Tabellen und Views in einem beliebigen Schema.</td>
								</tr>
								<tr>
									<td /><td>UPDATE ANY TABLE</td><td>Aktualisiert Zeilen in Tabellen und Views in einem beliebigen Schema.</td>
								</tr>
								<tr>
									<td /><td>SELECT ANY TABLE</td><td>Fragt Tabellen, Views oder Snapshots in einem beliebigen Schema ab.</td>
								</tr>
								<tr><td>TABLESPACES</td><td>CREATE TABLESPACE</td><td>Gew&auml;hrt das Privileg, Tablespaces zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER TABLESPACE</td><td>Gew&auml;hrt das Privileg, Tablespaces zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP TABLESPACE</td><td>Gew&auml;hrt das Privileg, Tablespaces zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>MANAGE TABLESPACE</td><td>Arbeitet mit Tablespaces offline und online und startet und beendet die Sicherung (Backup) von Tablespaces.</td>
								</tr>
								<tr>
									<td /><td>UNLIMITED TABLESPACE</td><td>Erm&ouml;glicht die Verwendung beliebig gro&szlig;er Tablespaces. Dieses Privileg hat Vorrang vor eventuell zugewiesenen Speicherplatzquoten. Wenn Sie einem Benutzer dieses Privileg entziehen, bleiben die Schemaobjekte des Benutzers zwar bestehen, aber es wird nur dann zus&auml;tzlicher Tablespace zur Verf&uuml;gung gestellt, wenn dies durch die Tablespace-Quoten zugelassen wird. Rollen kann dieses Systemprivileg nicht zugeteilt werden.</td>
								</tr>
								<tr><td>TRIGGERS</td><td>CREATE TRIGGER</td><td>Gew&auml;hrt das Privileg, einen Datenbanktrigger im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANY TRIGGER</td><td>Gew&auml;hrt das Privileg, Datenbanktrigger in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANY TRIGGER</td><td>Aktiviert, deaktiviert oder kompiliert Datenbanktrigger in einem beliebigen Schema.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY TRIGGER</td><td>Gew&auml;hrt das Privileg, Datenbanktrigger in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>ADMINISTER DATABASE TRIGGER</td><td>Gew&auml;hrt das Privileg, einen Trigger f&uuml;r <span class="emphasis">DATABASE</span> zu erstellen. (Dazu m&uuml;ssen Sie auch &uuml;ber das Privileg <span class="emphasis">CREATE TRIGGER</span> oder <span class="emphasis">CREATE ANY TRIGGER</span> verf&uuml;gen.)</td>
								</tr>
								<tr><td>TYPES</td><td>CREATE TYPE</td><td>Gew&auml;hrt das Privileg, Objekttypen und deren R&uuml;mpfe im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANY TYPE</td><td>Gew&auml;hrt das Privileg, Objekttypen und deren R&uuml;mpfe in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>ALTER ANY TYPE</td><td>Gew&auml;hrt das Privileg, Objekttypen in einem beliebigen Schema zu &auml;ndern.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY TYPE</td><td>Gew&auml;hrt das Privileg, Objekttypen und deren R&uuml;mpfe in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr>
									<td /><td>EXECUTE ANY TYPE</td><td>Verwendet und referenziert Objekt- und Sammlungstypen in einem beliebigen Schema und ruft Methoden eines Objekttyps in einem beliebigen Schema auf, <span class="emphasis">wenn Sie dieses Privileg einem bestimmten Benutzer gew&auml;hren</span>. Wenn Sie einer Rolle das Privileg <span class="emphasis">EXECUTE ANY TYPE</span> zuweisen, k&ouml;nnen Benutzer, die &uuml;ber diese Rolle verf&uuml;gen, keine Methoden eines Objekttyps in einem beliebigen Schema aufrufen.</td>
								</tr>
								<tr><td>USERS</td><td>CREATE USER</td><td>Gew&auml;hrt das Privileg, Benutzer zu erstellen. Dieses Privileg gibt dem Ersteller auch die M&ouml;glichkeit:
										<ol><li>Quoten f&uuml;r <span class="emphasis">beliebige</span><span class="emphasis">
</span>Tablespaces zuzuweisen,</li><li>Standard- und tempor&auml;re Tablespaces festzulegen,</li><li>ein Profil als Bestandteil einer <span class="emphasis">CREATE USER </span>-Anweisung zuzuweisen.</li></ol>
									</td>
								</tr>
								<tr>
									<td /><td>ALTER USER</td><td>Gew&auml;hrt das Privileg, einen beliebigen Benutzer zu &auml;ndern. Mit diesem Privileg hat der Inhaber auch das Recht:
										<ol><li>das Kennwort oder die Authentifizierungsmethode eines anderen Benutzers zu &auml;ndern,</li><li>Quoten f&uuml;r <span class="emphasis">beliebige</span><span class="emphasis">
</span>Tablespaces zuzuweisen,</li><li>Standard- und tempor&auml;re Tablespaces festzulegen,</li><li>ein Profil und Standardrollen zuzuweisen.</li></ol>
									</td>
								</tr>
								<tr>
									<td /><td>BECOME USER</td><td>Sorgt daf&uuml;r, dass ein Benutzer zu einem anderen Benutzer wird (dies ist erforderlich, wenn ein Benutzer einen vollst&auml;ndigen Datenbankimport durchf&uuml;hren m&ouml;chte).</td>
								</tr>
								<tr>
									<td /><td>DROP USER</td><td>Gew&auml;hrt das Privileg, Benutzer zu l&ouml;schen.</td>
								</tr>
								<tr><td>VIEWS</td><td>CREATE VIEW</td><td>Gew&auml;hrt das Privileg, Views im eigenen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>CREATE ANY VIEW</td><td>Gew&auml;hrt das Privileg, Views in einem beliebigen Schema zu erstellen.</td>
								</tr>
								<tr>
									<td /><td>DROP ANY VIEW</td><td>Gew&auml;hrt das Privileg, Views in einem beliebigen Schema zu l&ouml;schen.</td>
								</tr>
								<tr><td>MISCELLANEOUS</td><td>ANALYZE ANY</td><td>Analysiert beliebige Tabellen, Cluster oder Indizes in einem beliebigen Schema.</td>
								</tr>
								<tr>
									<td /><td>AUDIT ANY</td><td>F&uuml;hrt einen Audit f&uuml;r ein beliebiges Objekt in einem beliebigen Schema mit der Anweisung <span class="emphasis">AUDIT</span>
<span class="emphasis">schema_objects</span> durch.</td>
								</tr>
								<tr>
									<td /><td>COMMENT ANY TABLE</td><td>Kommentiert eine beliebige Tabelle, einen View oder eine Spalte in einem beliebigen Schema.</td>
								</tr>
								<tr>
									<td /><td>FORCE ANYTRANSACTION</td><td>Erzwingt das Festschreiben (COMMIT) oder Zur&uuml;ckf&uuml;hren (ROLLBACK) einer beliebigen zweifelhaften verteilten Transaktion in der lokalen Datenbank; sorgt daf&uuml;r, dass die verteilte Transaktion fehlschl&auml;gt.</td>
								</tr>
								<tr>
									<td /><td>FORCE TRANSACTION</td><td>Erzwingt das Festschreiben (COMMIT) oder Zur&uuml;ckf&uuml;hren (ROLLBACK) der eigenen zweifelhaften verteilten Transaktionen in der lokalen Datenbank.</td>
								</tr>
								<tr>
									<td /><td>GRANT ANYPRIVILEGE</td><td>Gew&auml;hrt beliebige Systemprivilegien.</td>
								</tr>
								<tr>
									<td /><td>SYSDBA</td><td>Erm&ouml;glicht es dem Benutzer:
										<ol><li><span class="emphasis">STARTUP</span>- und <span class="emphasis">SHUTDOWN</span>-Operationen durchzuf&uuml;hren,</li><li><span class="emphasis">ALTER DATABASE</span><span class="literal"> auszuf&uuml;hren:</span> &Ouml;ffnen, Einh&auml;ngen, Sichern oder &Auml;ndern des Zeichensatzes,</li><li><span class="emphasis">CREATE DATABASE</span> auszuf&uuml;hren,</li><li><span class="emphasis">ARCHIVELOG</span> und <span class="emphasis">RECOVERY</span> auszuf&uuml;hren.</li><li>Beinhaltet das Privileg <span class="emphasis">RESTRICTED SESSION</span>.</li></ol>
									</td>
								</tr>
								<tr>
									<td /><td>SYSOPER</td><td>Erm&ouml;glicht es dem Benutzer:
										<ol><li><span class="emphasis">STARTUP</span>- und <span class="emphasis">SHUTDOWN</span>-Operationen durchzuf&uuml;hren,</li></ol>
										<ol><li><span class="emphasis">ALTER DATABASE OPEN/MOUNT/BACKUP &#8211; ARCHIVELOG </span>und <span class="emphasis">RECOVERY</span> auszuf&uuml;hren.</li></ol>
										<ol><li>Beinhaltet das Privileg <span class="emphasis">RESTRICTED SESSION</span>.</li></ol>
									</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>GRANT { ALL
| SELECT
| INSERT
| DELETE
| UPDATE
| RULE } [,...n]
ON { object_name }
TO {grantee_name | PUBLIC | GROUP group_name}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL unterst&uuml;tzt weder die Klausel <span class="emphasis">WITH GRANT OPTION</span> noch Zugriffsrechte auf Spaltenebene. Die PostgreSQL-Implementierung von <span class="emphasis">GRANT</span> verh&auml;lt sich so, als sei <span class="emphasis">WITH GRANT OPTION</span> immer aktiviert. Jeder Benutzer, dem ein Zugriffsrecht gew&auml;hrt wird, kann dieses Privileg an andere Benutzer &uuml;bertragen. In PostgreSQL haben Sie die M&ouml;glichkeit, einer <span class="emphasis">GROUP</span> Zugriffsrechte zuzuweisen, sofern es sich um einen g&uuml;ltigen, bereits bestehenden <span class="emphasis">group_name</span> handelt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im Gegensatz zu verschiedenen anderen Herstellern unterst&uuml;tzt PostgreSQL <span class="emphasis">GRANT</span> nicht in Verbindung mit Systembefehlen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die PostgreSQL-Unterst&uuml;tzung f&uuml;r die Anweisung <span class="emphasis">GRANT</span> geht nicht &uuml;ber die Grundfunktionalit&auml;t hinaus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>GRANT INSERT ON publishers TO PUBLIC;

GRANT SELECT, UPDATE ON sales TO emily;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="INSERT">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">INSERT</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">INSERT</span>


 k&ouml;nnen Sie einer Tabelle oder einem View Datenzeilen hinzuf&uuml;gen. Die Anweisung <span class="emphasis">INSERT</span> bietet mehrere M&ouml;glichkeiten, Datens&auml;tze in eine Tabelle einzugeben:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ol><li>Die erste Methode besteht darin, Datens&auml;tze mit den <span class="emphasis">DEFAULT</span>-Werten hinzuzuf&uuml;gen, die den Spalten mit der <span class="emphasis">CREATE TABLE</span>- oder <span class="emphasis">ALTER TABLE</span>-Anweisung zugewiesen wurden. (Diese Methode wird von Oracle nicht unterst&uuml;tzt.)</li><li>Bei der zweiten und gebr&auml;uchlichsten Methode werden die Werte, die in die einzelnen Spalten des Datensatzes eingef&uuml;gt werden sollen, explizit angegeben.</li><li>Die dritte Methode, die ein schnelles F&uuml;llen einer Tabelle mit zahlreichen Datens&auml;tzen erm&ouml;glicht, besteht darin, die Ergebnismenge einer <span class="emphasis">SELECT</span>-Anweisung in eine Tabelle einzuf&uuml;gen.</li></ol>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>INSERT [INTO] [[database_name.]owner.] {table_name | view_name} [(column_
    list)]
{[DEFAULT] VALUES | VALUES (value[,...]) | SELECT_statement }</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Um die Anweisung <span class="emphasis">INSERT</span> verwenden zu k&ouml;nnen, m&uuml;ssen Sie zun&auml;chst die Tabelle (oder den View) deklarieren, in die (bzw. den) die Daten eingef&uuml;gt werden sollen. Das Schl&uuml;sselwort <span class="emphasis">INTO</span> ist optional. Geben Sie die Spalten der Tabelle, in die die Daten kopiert werden sollen, in der <span class="emphasis">column_list</span> an, indem Sie sie in runde Klammern setzen und die Namen durch Kommas voneinander trennen.  Die <span class="emphasis">column_list</span> kann auch weggelassen werden, dann werden aber alle f&uuml;r die Tabelle definierten Spalten &uuml;bernommen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Methode <span class="emphasis">DEFAULT VALUES</span> kann nicht mit den Methoden <span class="emphasis">list_of_values</span> und <span class="emphasis">SELECT_statement</span>-kombiniert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">INSERT . . . VALUES</span> wird einer Tabelle eine einzelne Datenzeile hinzugef&uuml;gt, die aus den in der Anweisung angegebenen Literalwerten besteht. Wenn die <span class="emphasis">INSERT</span>-Anweisung zusammen mit einer verschachtelten <span class="emphasis">SELECT</span>-Anweisung verwendet wird, lassen sich in eine Tabelle schnell mehrere Zeilen einf&uuml;gen. Wenn Sie <span class="emphasis">INSERT . . . SELECT</span> &uuml;ber zwei Tabellen hinweg verwenden, m&uuml;ssen Sie darauf achten, dass die Tabellen kompatible Datentypen und Strukturen besitzen, auch wenn eventuelle Inkompatibilit&auml;ten zwischen den beiden Tabellen mit der <span class="emphasis">SELECT</span>-Anweisung ausgeglichen werden. <span class="emphasis"> INSERT . . . SELECT</span> wird auch von PostgreSQL unterst&uuml;tzt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>INSERT [INTO] [[database_name.]owner.]
    {table_name | view_name} [(column_list)]
{[DEFAULT] VALUES | list_of_values | SELECT_statement |
 EXEC[UTE] { procedure_name }
    [[@parameter_name=] {value [OUTPUT] | DEFAULT}[,...]}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Implementierung des Befehls <span class="emphasis">INSERT</span> in Microsoft SQL Server unterscheidet sich dadurch, dass sie das Schl&uuml;sselwort <span class="emphasis">DEFAULT</span> unterst&uuml;tzt. Mit <span class="emphasis">DEFAULT</span> kann der Anweisung <span class="emphasis">INSERT</span> mitgeteilt werden, dass einfach ein neuer Datensatz mit allen f&uuml;r die Tabelle deklarierten Standardwerten erstellt werden soll.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der wichtigste Unterschied zu den Implementierungen anderer Hersteller besteht im Schl&uuml;sselwort <span class="emphasis">EXECUTE</span>. Mit der Klausel <span class="emphasis">EXECUTE</span> wird SQL Server aufgefordert, die von einer dynamischen Transact-SQL-Anweisung, einer vom System oder vom Benutzer gespeicherten Prozedur, einem Remote Procedure Call (RPC) oder einer erweiterten gespeicherten Prozedur zur&uuml;ckgegebene Ergebnismenge in einer lokalen Tabelle zu speichern.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So wird zum Beispiel mit der nachfolgenden <span class="emphasis">INSERT</span>-Anweisung das Verzeichnis <span class="emphasis">C:\temp</span> ausgelesen und in der tempor&auml;ren Tabelle <span class="emphasis">#ins_exec_container</span> gespeichert:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>INSERT INTO #ins_exec_container
EXEC master..xp_cmdshell "dir c:\temp"
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] [[database_name.]owner.] {table_name | view_name} [(column_list)]
{VALUES (value[,...]) | SELECT_statement | SET column=value[,...n]}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Option <span class="emphasis">LOW_PRIORITY</span> wird MySQL angewiesen, die Ausf&uuml;hrung von <span class="emphasis">INSERT</span> so lange hinauszuz&ouml;gern, bis keine anderen Clients mehr aus der Tabelle lesen. Das kann zu langen Wartezeiten f&uuml;hren. Mit der Option <span class="emphasis">DELAYED</span> kann der Client sofort fortfahren, selbst wenn die <span class="emphasis">INSERT</span>-Anweisung noch nicht abgeschlossen ist. Das Schl&uuml;sselwort <span class="emphasis">IGNORE</span> bedeutet, dass MySQL keine Datens&auml;tze einf&uuml;gen darf, die zu einem doppelten Wert in einem Prim&auml;r- oder eindeutigen Schl&uuml;ssel f&uuml;hren w&uuml;rden. Ohne diese Klausel w&uuml;rde die <span class="emphasis">INSERT</span>-Anweisung fehlschlagen. Mit der Syntax <span class="emphasis">SET column=value</span> k&ouml;nnen die Spalten der Tabelle deklariert und Werte in diese eingef&uuml;gt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>INSERT [INTO] [[database_name.]owner.] {table_name | view_name}
   [PARTITION partition_name | SUBPARTITION subpartition_name]
[(column_list)]
{VALUES (value1[,...n]) RETURNING expression1 [,...n] INTO variable1
   [,...n]
 |
SELECT_statement
[WITH {READ ONLY | CHECK OPTION [CONSTRAINT constraint_name]} }</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Oracle-spezifische Implementierung der Anweisung <span class="emphasis">INSERT</span> unterst&uuml;tzt die Schl&uuml;sselw&ouml;rter <span class="emphasis">PARTITION</span> und <span class="emphasis">SUBPARTITION</span> und erm&ouml;glicht so das Einf&uuml;gen von Daten nicht nur in eine Tabelle, einen View oder einen Snapshot, sondern auch in eine Partition oder Subpartition in einer Tabelle.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn die Anweisung <span class="emphasis">INSERT</span> mit einer <span class="emphasis">SELECT</span>-Klausel in Beziehung steht, gelten einige zus&auml;tzliche Regeln. Wenn die <span class="emphasis">SELECT</span>-Klausel mit einer <span class="emphasis">VALUES</span>-Klausel verbunden ist, wird nur eine Zeile in die Tabelle eingef&uuml;gt, n&auml;mlich die erste Zeile, die von der <span class="emphasis">SELECT</span>-Klausel zur&uuml;ckgegeben wird. Wenn <span class="emphasis">SELECT</span> ohne <span class="emphasis">VALUES</span> verwendet wird, werden alle Zeilen, die von der Abfrage zur&uuml;ckgegeben werden, in die Tabelle eingef&uuml;gt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">RETURNING</span> werden die Werte nicht in eine Tabelle, sondern in Variablen eingef&uuml;gt. Zwischen den Ausdr&uuml;cken und Variablen der <span class="emphasis">RETURNING</span>-Klausel muss es eine Eins-zu-Eins-&Uuml;bereinstimmung geben. Die von der Klausel zur&uuml;ckgegebenen Ausdr&uuml;cke m&uuml;ssen nicht zwangsl&auml;ufig diejenigen sein, die in der <span class="emphasis">VALUES</span>-Klausel genannt sind. Mit der folgenden <span class="emphasis">INSERT</span>-Anweisung wird beispielsweise ein Datensatz in die Tabelle <span class="emphasis">sales</span> eingef&uuml;gt, wobei jedoch ein v&ouml;llig anderer Wert in einer Bindungsvariablen abgelegt wird:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>INSERT authors (au_id, au_lname, au_fname, contract )
VALUES ('111-11-1111', 'Rabbit', 'Jessica', 1)
RETURNING hire_date INTO :temp_hr_dt;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Beachten Sie, dass die <span class="emphasis">RETURNING</span>-Klausel den <span class="emphasis">hire_date</span>-Wert zur&uuml;ckgibt, auch wenn <span class="emphasis">hire_date</span> nicht zu den Werten geh&ouml;rt, die in der <span class="emphasis">VALUES</span>-Klausel angegeben sind. (In diesem Beispiel kann man davon ausgehen, dass ein Standardwert f&uuml;r die Spalte <span class="emphasis">hire_date</span> festgelegt wurde.) LONG-Datentypen k&ouml;nnen mit <span class="emphasis">RETURNING</span> nicht bearbeitet werden. <span class="emphasis">RETURNING</span> kann nicht auf Views mit <span class="emphasis">INSTEAD OF</span>-Triggern angewendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Zus&auml;tzlich kann die <span class="emphasis">SELECT</span>-Klausel die Option <span class="emphasis">WITH</span> verwenden. Mit <span class="emphasis">WITH READ ONLY</span> wird angegeben, dass die von der <span class="emphasis">SELECT</span>-Klausel zur&uuml;ckgegebene Ergebnismenge nicht mit der Anweisung <span class="emphasis">INSERT</span> ge&auml;ndert werden kann. Mit der Klausel <span class="emphasis">WITH CHECK OPTION</span> wird Oracle aufgefordert, Daten&auml;nderungen zu unterbinden, die zu Zeilen f&uuml;hren w&uuml;rden, die nicht in der Ergebnismenge der <span class="emphasis">SELECT</span>-Klausel enthalten sind.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL unterst&uuml;tzt den SQL99-Standard der Anweisung <span class="emphasis">INSERT</span>. Im Abschnitt vorher finden Sie n&auml;here Informationen zur Syntax und Verwendung nach dem SQL99-Standard.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel wird f&uuml;r die Autorin Jessica Rabbit eine neue Zeile in die Tabelle <span class="emphasis">authors</span> in einer Microsoft SQL Server-Datenbank eingef&uuml;gt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>INSERT INTO authors (au_id, au_lname, au_fname, phone, address, city,
     state, zip, contract )
VALUES ('111-11-1111', 'Rabbit', 'Jessica', DEFAULT, '1717 Main St', NULL,
    'CA', '90675', 1)</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Jeder Spalte wird ein bestimmter Literalwert zugewiesen. Dies gilt jedoch nicht f&uuml;r die Spalten <span class="emphasis">phone</span> und <span class="emphasis">city</span> &#8211; erstere erh&auml;lt den Standardwert (entsprechend der Anweisung <span class="emphasis">CREATE TABLE</span> oder <span class="emphasis">ALTER TABLE</span>), letztere den Wert Null.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel sehen Sie eine teilweise <span class="emphasis">INSERT</span>-Operation in einer Microsoft SQL Server-Datenbank mit denselben Daten:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>INSERT authors (au_id, au_lname, au_fname,  phone, contract )
VALUES ('111-11-1111', 'Rabbit', 'Jessica', DEFAULT, 1)</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Um Daten aus der Tabelle <span class="emphasis">sales</span> in die Tabelle <span class="emphasis">new_sales</span> zu laden, k&ouml;nnen Sie die Anweisung <span class="emphasis">INSERT . . . SELECT</span> verwenden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>INSERT sales
    (stor_id,
    ord_num,
    ord_date,
    qty,
    payterms,
    title_id)
SELECT
    CAST(store_nbr AS CHAR(4)),
    CAST(order_nbr AS VARCHAR(20)),
    order_date,
    quantity,
    SUBSTRING(payment_terms,1,12),
    CAST(title_nbr AS CHAR(1))
FROM new_sales
WHERE order_date &gt;= '01/01/2000'         -- retrieve only the newer records</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="LIKE-Operator">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">LIKE-Operator</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit dem <span class="emphasis">LIKE</span>-Operator   k&ouml;nnen bestimmte Stringmuster in <span class="emphasis">SELECT</span>-   , <span class="emphasis">INSERT</span>-, <span class="emphasis">UPDATE</span>- und <span class="emphasis">DELETE</span>-Anweisungen verglichen werden. Die angegebenen Suchmuster k&ouml;nnen sogar spezielle Wildcard-Zeichen enthalten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>WHERE expression [NOT] LIKE string_pattern</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der <span class="emphasis">LIKE</span>-Operator ist gerade wegen den unterst&uuml;tzten Wildcards so n&uuml;tzlich. <span class="emphasis">LIKE</span> gibt den Booleschen Wert <span class="emphasis">TRUE</span> zur&uuml;ck, wenn der Vergleich einen oder mehrere passende Werte ergibt. Beachten Sie, dass die standardm&auml;&szlig;ige Gro&szlig;-/Kleinschreibung des DBMS gro&szlig;e Auswirkungen auf das Verhalten von <span class="emphasis">LIKE</span> hat. In Microsoft SQL Server wird die Gro&szlig;-/Kleinschreibung normalerweise nicht ber&uuml;cksichtigt, auch wenn dies so eingestellt werden kann. Mit der Abfrage</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT *
FROM authors
WHERE lname LIKE 'LARS%'</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>w&uuml;rde man daher nur Autoren finden, deren Nachnamen als "larson" or "lars" gespeichert sind, auch wenn eigentlich nach "LARS%" in Gro&szlig;buchstaben gesucht wurde. Oracle ber&uuml;cksichtigt die Gro&szlig;-/Kleinschreibung bei den Wildcards "<span class="emphasis">%</span>" und "<span class="emphasis">_</span>" und verf&uuml;gt &uuml;ber weitere Operatoren au&szlig;er <span class="emphasis">LIKE</span> f&uuml;r Mustervergleiche mit regul&auml;ren Ausdr&uuml;cken. Die Wildcard-Operatoren sind in Tabelle 3.3 zusammengefasst.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Wildcard-Operator</th><th>Beispiel</th><th>Beschreibung</th></tr>
								<tr><td><span class="emphasis">%</span></td><td>Ruft alle Datens&auml;tze mit St&auml;dtenamen ab, die die Zeichenfolge "ville" enthalten (von allen Herstellern unterst&uuml;tzt).<pre>SELECT * FROM authors
WHERE city LIKE '%ville%'</pre>
									</td><td>Ist ein Platzhalter f&uuml;r jeden beliebigen String, &auml;hnelt dem * in DOS-Operationen.</td>
								</tr>
								<tr><td><span class="emphasis">[ ]</span></td><td>Ruft alle Autoren mit einem &auml;hnlich klingenden Nachnamen wie Carson, Carsen, Karson oder Karsen ab (von Oracle nicht unterst&uuml;tzt; von Microsoft SQL Server unterst&uuml;tzt.)<pre>SELECT * FROM authors
WHERE au_lname LIKE '[CK]ars[eo]n'</pre>
									</td><td>Sucht nach Zeichen, die mit den Werten in der angegebenen Menge (z.&#160;B. [abc]) oder im angegebenen Bereich (z.&#160;B. [k-n]) &uuml;bereinstimmen.</td>
								</tr>
								<tr><td><span class="emphasis">[^ ]</span></td><td>Ruft alle Autoren mit Nachnamen ab, die auf "arson" oder "arsen" enden, <span class="emphasis">aber nicht</span> Larsen oder Larson (von Microsoft SQL Server unterst&uuml;tzt).<pre>SELECT * FROM authors
WHERE au_lname LIKE '[A-Z^L]ars[eo]n'</pre>
									</td><td>Sucht nach Zeichen, die nicht in der angegebenen Menge oder im angegebenen Bereich vorkommen.</td>
								</tr>
								<tr><td><span class="emphasis">_ (Unterstrich)</span></td><td>Ruft alle Autoren ab, deren Vorname <span class="emphasis">weder</span> Sheryl <span class="emphasis">noch</span> Cheryl ist (von allen Herstellern unterst&uuml;tzt).<pre>SELECT * FROM authors
WHERE au_fname NOT LIKE '_heryl'</pre>
									</td><td>Steht f&uuml;r ein beliebiges einzelnes Zeichen.</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn Sie Stringvergleiche mit <span class="emphasis">LIKE</span> durchf&uuml;hren, sind alle Zeichen in dem Suchmuster entscheidend, einschlie&szlig;lich aller f&uuml;hrenden oder folgenden Leerzeichen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="OPEN">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">OPEN </td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">OPEN</span>

 wird ein serverseitiger Cursor ge&ouml;ffnet, der mit einer <span class="emphasis">DECLARE CURSOR</span>-Anweisung erstellt wurde. MySQL unterst&uuml;tzt keine serverseitigen Cursor vom Typ ANSI.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>OPEN { cursor_name }</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">cursor_name</span> ist der Name des Cursors gemeint, der mit dem Befehl <span class="emphasis">DECLARE CURSOR </span>erstellt wurde.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Neben den Standard-Servercursorn erlaubt Microsoft SQL Server auch die Deklaration globaler Cursor (im Format <span class="emphasis">OPEN GLOBAL cursor_name</span>), die von mehreren Benutzern verwendet werden k&ouml;nnen. Dar&uuml;ber hinaus k&ouml;nnen in Oracle Parameter direkt an den Cursor &uuml;bergeben werden, wenn dieser ge&ouml;ffnet ist (im Format <span class="emphasis">OPEN cursor_name parameter1 [,...n]</span>).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel f&uuml;r Microsoft SQL Server wird ein Cursor ge&ouml;ffnet und anschlie&szlig;end werden alle Zeilen ausgelesen. Dasselbe erreichen Sie in Oracle und PostgreSQL ohne die abschlie&szlig;ende <span class="emphasis">DEALLOCATAE</span>-Klausel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>DECLARE employee_cursor CURSOR FOR
  SELECT lname, fname
  FROM pubs.dbo.authors
  WHERE lname LIKE 'K%'

OPEN employee_cursor

FETCH NEXT FROM employee_cursor

WHILE @@FETCH_STATUS = 0
BEGIN
  FETCH NEXT FROM Employee_Cursor
END

CLOSE employee_cursor

DEALLOCATE employee_cursor
-- DEALLOCATE is specific to Microsoft SQL Server and non-ANSI
-- standard.</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="Operatoren">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">Operatoren</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Ein Operator ist ein Symbol, das eine Aktion f&uuml;r einen oder mehrere Ausdr&uuml;cke angibt. Operatoren werden meistens in <span class="emphasis">DELETE</span>-

, <span class="emphasis">INSERT</span>-, <span class="emphasis">SELECT</span>- oder <span class="emphasis">UPDATE</span>-Anweisungen verwendet, k&ouml;nnen aber auch bei der Erstellung von


Datenbankobjekten wie gespeicherten Prozeduren, Funktionen, Triggern und Views eingesetzt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Operatoren werden in der Regel in folgende logische Kategorien eingeteilt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ul><li><i><span class="emphasis">Arithmetische Operatoren</span></i><br>&#160;
						  in allen Datenbanken unterst&uuml;tzt</li><li><i><span class="emphasis">Zuweisungsoperatoren</span></i><br>&#160;
						  in allen Datenbanken unterst&uuml;tzt</li><li><i><span class="emphasis">Bitweise</span> <span class="emphasis">Operatoren</span></i><br>&#160;
						  unterst&uuml;tzt in Microsoft SQL Server</li><li><i><span class="emphasis">Vergleichs</span><span class="emphasis">operatoren</span></i><br>&#160;
						  in allen Datenbanken unterst&uuml;tzt</li><li><i><span class="emphasis">Logische</span> <span class="emphasis">Operatoren</span></i><br>&#160;
						  unterst&uuml;tzt in Oracle, Microsoft SQL Server und PostgreSQL</li><li><i><span class="emphasis">Un&auml;re Operatoren</span></i><br>&#160;
						  unterst&uuml;tzt in Oracle</li></ul>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Arithmetische Operatoren</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Arithmetische Operatoren f&uuml;hren mathematische Operationen f&uuml;r zwei Ausdr&uuml;cke aus, die aus beliebigen numerischen Datentypen bestehen. Die arithmetischen Operatoren sind in Tabelle 3.4 zusammengefasst.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Arithmetischer Operator</th><th>Bedeutung</th></tr>
								<tr><td><span class="emphasis">+</span>

</td><td>
Addition</td>
								</tr>
								<tr><td><span class="emphasis">- </span></td><td>Subtraktion</td>
								</tr>
								<tr><td><span class="emphasis">* </span></td><td>Multiplikation</td>
								</tr>
								<tr><td><span class="emphasis">/ </span></td><td>Division</td>
								</tr>
								<tr><td><span class="emphasis">% </span></td><td>Modula (nur in SQL Server); gibt den Rest einer Divisionsoperation als Ganzzahl zur&uuml;ck.</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle und SQL Server k&ouml;nnen die Operatoren + und &#8211; auch f&uuml;r arithmetische Operationen mit Datumswerten verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Zuweisungsoperatoren</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Au&szlig;er in Oracle wird mit dem  Zuweisungsoperator (<span class="emphasis">=</span>) der Wert einer Variablen oder dem Alias einer Spalten&uuml;berschrift zugewiesen. In Microsoft SQL Server kann das Schl&uuml;sselwort <span class="emphasis">AS</span> als Operator f&uuml;r Aliasnamen in Tabellen- oder Spalten&uuml;berschriften verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Bitweise Operatoren</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server stellt bitweise Operatoren als Schnellverfahren f&uuml;r die Bitmanipulation zwischen Ausdr&uuml;cken mit zwei Integerwerten zur Verf&uuml;gung (siehe Tabelle 3.5). Zu den Datentypen, die mit bitweisen Operatoren verwendet werden k&ouml;nnen, geh&ouml;ren <span class="emphasis">binary</span>, <span class="emphasis">bit</span>, <span class="emphasis">int</span>, <span class="emphasis">smallint</span>, <span class="emphasis">tinyint</span> und <span class="emphasis">varbinary</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Bitweise Operatoren</th><th>Bedeutung</th></tr>
								<tr><td><span class="emphasis">&amp; </span> </td><td>Bitweises UND (zwei Operanden)</td>
								</tr>
								<tr><td><span class="emphasis">| </span> </td><td>Bitweises ODER (zwei Operanden)</td>
								</tr>
								<tr><td><span class="emphasis">^ </span> </td><td>Bitweises Exklusiv-ODER (zwei Operanden)</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Vergleichsoperatoren</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>
Vergleichsoperatoren pr&uuml;fen, ob zwei Ausdr&uuml;cke gleich oder ungleich sind. Das Ergebnis einer Vergleichsoperation ist ein Boolescher Wert: <span class="emphasis">TRUE</span>, <span class="emphasis">FALSE</span> oder <span class="emphasis">UNKNOWN</span>. Der ANSI-Standard sieht vor, dass das Ergebnis eines Vergleichs, bei dem einer der beiden Ausdr&uuml;cke <span class="emphasis">NULL</span> ist, ebenfalls <span class="emphasis">NULL</span> ist. So gibt zum Beispiel der Ausdruck <span class="emphasis">23 + NULL</span> <span class="emphasis">NULL</span> zur&uuml;ck, ebenso der Ausdruck <span class="emphasis">Feb 23, 2002 + NULL</span>. Die Vergleichsoperatoren sind in Tabelle 3.6 zusammengefasst.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Vergleichsoperatoren</th><th>Bedeutung</th></tr>
								<tr><td><span class="emphasis">=</span>


</td><td>Gleich</td>
								</tr>
								<tr><td><span class="emphasis">&gt;</span></td><td>Gr&ouml;&szlig;er als</td>
								</tr>
								<tr><td><span class="emphasis">&lt;</span></td><td>Kleiner als</td>
								</tr>
								<tr><td><span class="emphasis">&gt;=</span>

</td><td>Gr&ouml;&szlig;er oder gleich</td>
								</tr>
								<tr><td><span class="emphasis">&lt;=</span></td><td>Kleiner oder gleich</td>
								</tr>
								<tr><td><span class="emphasis">&lt;&gt;</span></td><td>Ungleich</td>
								</tr>
								<tr><td><span class="emphasis">!=</span>     </td><td>Ungleich (nicht im ANSI-Standard)</td>
								</tr>
								<tr><td><span class="emphasis">!&lt;</span></td><td>Nicht kleiner als (nicht im ANSI-Standard)</td>
								</tr>
								<tr><td><span class="emphasis">!&gt;</span></td><td>Nicht gr&ouml;&szlig;er als (nicht im ANSI-Standard)</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Boolesche Vergleichsoperatoren werden meistens in einer
<span class="emphasis">WHERE</span>-Klausel verwendet, um die Zeilen herauszufiltern, die die Suchbedingungen erf&uuml;llen. Im folgenden Beispiel f&uuml;r Microsoft SQL Server ist ein Gr&ouml;&szlig;er-oder-Gleich-Vergleich enthalten:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT *
   FROM Products
   WHERE ProductID &gt;= @MyProduct</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Logische Operatoren</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Logische Operatoren werden h&auml;ufig in <span class="emphasis">WHERE</span>-Klauseln verwendet, um zu &uuml;berpr&uuml;fen, ob eine Bedingung wahr ist. Logische Operatoren geben einen Booleschen Wert zur&uuml;ck, d.&#160;h. entweder <span class="emphasis">TRUE</span> oder <span class="emphasis">FALSE</span>. Logische Operatoren werden unter der Anweisung <span class="emphasis">SELECT</span> n&auml;her erl&auml;utert. Nicht alle RDBMS unterst&uuml;tzen alle Operatoren. Die logischen Operatoren sind in Tabelle 3.7 zusammengefasst.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Logische Operatoren</th><th>Bedeutung</th></tr>
								<tr><td><span class="emphasis">ALL</span></td><td>TRUE, wenn alle Vergleiche aus einer Menge TRUE sind</td>
								</tr>
								<tr><td><span class="emphasis">AND </span>         </td><td>TRUE, wenn beide Boolesche Ausdr&uuml;cke TRUE sind</td>
								</tr>
								<tr><td><span class="emphasis">ANY</span></td><td>TRUE, wenn alle Vergleiche aus einer Menge TRUE sind</td>
								</tr>
								<tr><td><span class="emphasis">BETWEEN</span></td><td>TRUE, wenn der Operand im angegebenen Bereich liegt</td>
								</tr>
								<tr><td><span class="emphasis">EXISTS</span></td><td>TRUE<span class="emphasis"></span>, wenn eine Unterabfrage Zeilen enth&auml;lt</td>
								</tr>
								<tr><td><span class="emphasis">IN</span></td><td>TRUE, wenn der Operand gleich einem Ausdruck in einer Liste von Ausdr&uuml;cken ist</td>
								</tr>
								<tr><td><span class="emphasis">LIKE</span></td><td>TRUE, wenn der Operand mit dem Muster &uuml;bereinstimmt</td>
								</tr>
								<tr><td><span class="emphasis">NOT</span></td><td>Kehrt den Wert jedes anderen Booleschen Operators um</td>
								</tr>
								<tr><td><span class="emphasis">OR</span></td><td>TRUE, wenn einer der beiden Booleschen Ausdr&uuml;cke TRUE ist</td>
								</tr>
								<tr><td><span class="emphasis">SOME</span></td><td>TRUE, wenn einige Vergleiche aus einer Menge TRUE sind</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Un&auml;re Operatoren</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Un&auml;re Operatoren f&uuml;hren eine Operation f&uuml;r einen einzigen Ausdruck eines beliebigen numerischen Datentyps aus. Un&auml;re Operatoren k&ouml;nnen bei Integerdatentypen verwendet werden, + und - dagegen bei jedem beliebigen numerischen Datentyp (siehe Tabelle 3.8).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Un&auml;re Operatoren</th><th>Bedeutung</th></tr>
								<tr><td><span class="emphasis">+</span></td><td>Numerischer Wert ist positiv</td>
								</tr>
								<tr><td><span class="emphasis">-</span>  </td><td>Numerischer Wert ist negativ</td>
								</tr>
								<tr><td><span class="emphasis">~</span></td><td>Bitweises NICHT, gibt das Komplement einer Zahl zur&uuml;ck (nicht in Oracle)</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Rangfolge von Operatoren</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>
Manchmal sind Operatorausdr&uuml;cke ziemlich komplex. Wenn in einem Ausdruck mehrere Operatoren enthalten sind, bestimmt die <span class="emphasis">Rangfolge</span>, in welcher Reihenfolge die Operationen ausgef&uuml;hrt werden. Die Ausf&uuml;hrungsreihenfolge kann sich entscheidend auf den Ergebniswert auswirken.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>F&uuml;r Operatoren gelten die nachstehend genannten Rangstufen. Ein Operator einer h&ouml;heren Stufe wird vor einem Operator einer niedrigeren Stufe ausgewertet:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ol><li>( ) (Ausdr&uuml;cke in Klammern)</li><li>+, -, ~ (un&auml;re Operatoren)</li><li>*, /, % (mathematische Operatoren)</li><li>+, - (arithmetische Operatoren)</li><li>=, &gt;, &lt;, &gt;=, &lt;=, &lt;&gt;, !=, !&gt;, !&lt; (Vergleichsoperatoren)</li><li>^ (bitweises Exklusiv-ODER), &amp; (bitweises UND), | (bitweises ODER)</li><li><span class="emphasis">NOT </span></li><li><span class="emphasis">AND </span></li><li><span class="emphasis">ALL</span>, <span class="emphasis">ANY</span>, <span class="emphasis">BETWEEN</span>, <span class="emphasis">IN</span>, <span class="emphasis">LIKE</span>, <span class="emphasis">OR</span>, <span class="emphasis">SOME</span></li><li>= (Variablenzuweisung)</li></ol>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Operatoren mit gleicher Rangstufe werden von links nach rechts ausgewertet. Die Rangstufe eines Operators in einem Ausdruck kann jedoch ge&auml;ndert werden, indem dieser in runde Klammern gesetzt wird. Ausdr&uuml;cke in Klammern werden zuerst ausgewertet, dann erst kommen die Operatoren au&szlig;erhalb der Klammern.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die folgenden Ausdr&uuml;cke in einer Oracle-Abfrage geben beispielsweise sehr unterschiedliche Ergebnisse zur&uuml;ck:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT 2 * 4 + 5 FROM dual
-- Evaluates to 8 + 5 which yields an expression result of 13.

SELECT 2 * (4 + 5) FROM dual
-- Evaluates to 2 * 9 which yields an expression result of 18.</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Ausdr&uuml;cken mit
 verschachtelten Klammern wird der am tiefsten verschachtelte Ausdruck zuerst ausgewertet.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Das folgende Beispiel enth&auml;lt verschachtelte Klammern, wobei der Ausdruck <span class="emphasis">5 -3</span> am tiefsten verschachtelt ist. Dieser Ausdruck ergibt den Wert <span class="emphasis">2</span>. Der Additionsoperator (+) addiert dieses Ergebnis zu <span class="emphasis">4</span> hinzu, was <span class="emphasis">6</span> ergibt. Zum Schluss wird <span class="emphasis">6</span> mit <span class="emphasis">2</span> multipliziert, so dass das Ergebnis des Ausdrucks <span class="emphasis">12</span> ist:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT 2 * (4 + (5 - 3) ) FROM dual
-- Evaluates to 2 * (4 + 2) which further evaluates to 2 * 6, and
-- yields an expression result of 12.</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="RETURN">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">RETURN </td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">RETURN</span>
 wird die Verarbeitung einer von SQL (also nicht vom Host) aufgerufenen Funktion beendet und der Ergebniswert der Funktion zur&uuml;ckgegeben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>RETURNS return_parameter_value | NULL</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Funktion <span class="emphasis">RETURN</span> wird in einer Funktion verwendet, um deren Verarbeitung zu beenden. Mit der Klausel <span class="emphasis">NULL</span> wird die Funktion ohne R&uuml;ckgabe eines Wertes beendet. Ansonsten wird der angegebene Parameterwert entweder als Variable oder als Literalausdruck zur&uuml;ckgegeben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Obwohl die Anweisung <span class="emphasis">RETURN</span> als eigenst&auml;ndiger SQL-Befehl betrachtet wird, steht sie in engem Zusammenhang mit der Anweisung <span class="emphasis">CREATE FUNCTION</span> . N&auml;here Informationen &uuml;ber die herstellerspezifischen Implementierungen von <span class="emphasis">RETURN</span> finden Sie unter der Anweisung <span class="emphasis">CREATE FUNCTION</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel wird eine Funktion erstellt. Die Funktion gibt den in der Variablen <span class="emphasis">proj_rev</span> gespeicherten Wert an die aufrufende Sitzung zur&uuml;ck:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE FUNCTION project_revenue (project IN varchar2)
RETURN NUMBER
AS
   proj_rev NUMBER(10,2);
BEGIN
   SELECT SUM(DECODE(action,'COMPLETED',amount,0) -
          SUM(DECODE(action,'STARTED',amount,0)   +
          SUM(DECODE(action,'PAYMENT',amount,0)
   INTO proj_rev
   FROM construction_actions
   WHERE project_name = project;
   RETURN (proj_rev);
END;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel wird eine Funktion erstellt, die einen berechneten Wert an die aufrufende Sitzung zur&uuml;ckgibt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>CREATE FUNCTION metric_volume -- Input dimensions in centimeters.
   (@length decimal(4,1),
   @width decimal(4,1),
   @height decimal(4,1) )
RETURNS decimal(12,3) -- Cubic Centimeters.
AS
BEGIN
   RETURN ( @length * @width * @height )
END
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="REVOKE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">REVOKE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">REVOKE</span>



 werden einem Benutzer, einer Gruppe oder einer Rolle die Zugriffsrechte f&uuml;r ein bestimmtes Datenbankobjekt oder einen Systembefehl entzogen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>REVOKE [GRANT OPTION FOR]
{ ALL PRIVILEGES }
| SELECT
| INSERT
| DELETE
| UPDATE
| REFERENCES
| USAGE }[,...n]
ON { [TABLE] table_name
| DOMAIN domain_name
| COLLATION collation_name
| CHARACTER SET character_set_name
| TRANSLATION translation_name }
FROM {grantee_name | PUBLIC} [,...n]
{CASCADE | RESTRICT}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Ein bestimmtes Zugriffsrecht f&uuml;r ein bestimmtes Datenbankobjekt kann einem einzelnen Benutzer mit <span class="emphasis">REVOKE privilege_name ON object_name FROM grantee_name</span> entzogen werden. Ein bestimmtes Zugriffsrecht f&uuml;r ein bestimmtes Objekt k&ouml;nnen Sie s&auml;mtlichen Benutzern mit der Klausel <span class="emphasis">PUBLIC</span> entziehen. Alternativ dazu kann <span class="emphasis">WITH GRANT OPTION</span> verwendet werden, um Zugriffsrechte mit der Klausel <span class="emphasis">REVOKE GRANT OPTION FOR</span> zu entziehen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Option <span class="emphasis">RESTRICT</span> wird nur das angegebene Zugriffsrecht entzogen. Mit der Option <span class="emphasis">CASCADE</span> werden das angegebene Zugriffsrecht sowie alle davon anh&auml;ngigen Zugriffsrechte entzogen. Der kaskadierende Entzug von Zugriffsrechten kann von Datenbankplattform zu Datenbankplattform unterschiedlich sein. Sie sollte daher vorher in der Herstellerdokumentation nachlesen, wie diese Option richtig implementiert wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>REVOKE [GRANT OPTION FOR]
{ALL [ PRIVILEGES ]
| SELECT
| INSERT
| DELETE
| UPDATE
| REFERENCES
| EXECUTE
| CREATE {DATABASE | DEFAULT | FUNCTION | PROCEDURE | RULE | TABLE | VIEW}
| BACKUP {DATABASE | LOG} } [,...n]
ON { {table_name | view_name} [(column [,...n])]
| stored_procedure_name
| extended_stored_procedure_name
| user_defined_function_name
| [(column [,...n] ON {table_name | view_name} }
{TO | FROM} {grantee_name} [,...n]
[CASCADE]
[AS {group_name | role_name} ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Dieser Befehl ist im Wesentlichen SQL99-kompatibel, mit Ausnahme der mit dem Befehl <span class="emphasis">GRANT</span> eingef&uuml;hrten Erweiterungen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn einem Benutzer mit <span class="emphasis">WITH GRANT OPTION</span> die Ausf&uuml;hrung von Befehlen gew&auml;hrt wurde, sollte dieses Privileg sowohl mit <span class="emphasis">WITH GRANT OPTION</span> als auch <span class="emphasis">CASCADE</span> entzogen werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">REVOKE</span> kann nur in der aktuellen Datenbank verwendet werden. <span class="emphasis">REVOKE</span> wird auch verwendet, um <span class="emphasis">DENY</span>-Einstellungen zu deaktivieren.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt zus&auml;tzlich die Anweisung <span class="emphasis">DENY</span>. <span class="emphasis">DENY</span> ist <span class="emphasis">REVOKE</span> syntaktisch &auml;hnlich, unterscheidet sich aber konzeptionell dahingehend, dass <span class="emphasis">REVOKE</span> die Zugriffsrechte eines Benutzers neutralisiert, w&auml;hrend diese mit <span class="emphasis">DENY</span> explizit verboten werden. Mit der Anweisung <span class="emphasis">DENY</span> k&ouml;nnen Sie einen Benutzer oder eine Rolle von der Nutzung eines Privilegs ausschlie&szlig;en.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>REVOKE CREATE DATABASE, CREATE TABLE FROM emily, sarah
GO

REVOKE GRANT OPTION FOR
SELECT, INSERT, UPDATE, DELETE ON titles
TO editors
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>REVOKE { ALL PRIVILEGES
| SELECT
| INSERT [ (column_name [,...n]) ]
| UPDATE [ (column_name [,...n]) ]
| REFERENCES [ (column_name [,...n]) ]
| DELETE
| USAGE
| ALTER
| CREATE
| DROP
| FILE
| INDEX
| PROCESS
| RELOAD
| SHUTDOWN } [,...n]
ON {table_name | * | *.* | database_name.*}
FROM user_name [,...n]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">REVOKE</span> werden Zugriffsrechte, die einem oder mehreren Benutzern zuvor einger&auml;umt wurden, wieder entzogen. Zugriffsrechte k&ouml;nnen wie unter der Anweisung <span class="emphasis">GRANT</span> beschrieben global zur&uuml;ckgenommen werden. Au&szlig;erdem werden bei der MySQL-Implementierung von <span class="emphasis">REVOKE</span> nicht automatisch Zugriffsrechte f&uuml;r gel&ouml;schte Objekte entzogen. Aus diesem Grunde m&uuml;ssen Zugriffsrechte f&uuml;r eine gel&ouml;scht Tabelle explizit zur&uuml;ckgenommen werden. Ansonsten entspricht der MySQL-Befehl <span class="emphasis">REVOKE</span> dem SQL99-Standard.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem ersten Befehl werden Emily und Dylan alle Zugriffsrechte f&uuml;r die Tabelle <span class="emphasis">sales</span> entzogen, mit dem zweiten Befehl dagegen alle Rechte des Benutzers Kelly in der aktuellen Datenbank:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>REVOKE ALL PRIVILEGES ON sales FROM emily, dylan;

REVOKE * employee FROM kelly;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>REVOKE {ALL [PRIVILEGES] | [object_privilege] }
ON { [schema_name.][object] | [DIRECTORY directory_object_name] }
FROM {grantee_name | role | PUBLIC} [,...n]
[CASCADE [CONSTRAINTS] ] [FORCE];

REVOKE {system_privilege | role}
FROM {grantee_name | role | PUBLIC} [,...n];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">REVOKE</span> k&ouml;nnen nicht nur Objekt- und Systemprivilegien zur&uuml;ckgenommen werden, sondern die Rolle eines bestimmten Benutzers oder einer anderen Rolle. N&auml;here Informationen &uuml;ber Objekt- und Systemprivilegien, die der Befehl <span class="emphasis">REVOKE</span> unterst&uuml;tzt, finden Sie unter der Anweisung <span class="emphasis">GRANT</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die beiden Formen des <span class="emphasis">REVOKE</span>-Befehls, <span class="emphasis">REVOKE object_privilege</span> und <span class="emphasis">REVOKE system_privilege</span> schlie&szlig;en sich gegenseitig aus. Versuchen Sie nicht, beide Operationen in einer einzigen Anweisung zu verwenden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn einem Benutzer Zugriffsrechte entzogen werden, werden gleichzeitig auch die Zugriffsrechte aller anderen Benutzer, die ihre Rechte von diesem Benutzer erhalten haben, entzogen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Benutzer mit dem Systemprivileg <span class="emphasis">GRANT ANY ROLE</span> k&ouml;nnen auch beliebige Rollen entziehen. Mit dem Befehl <span class="emphasis">REVOKE</span> k&ouml;nnen nur Privilegien entzogen werden, die explizit mit dem Befehl <span class="emphasis">GRANT</span> gew&auml;hrt wurden, nicht solche, die &uuml;ber Rollen oder das Betriebssystem zur Verf&uuml;gung stehen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">ON DIRECTORY</span> wird ein Verzeichnisobjekt angegeben, bei dem Zugriffsrechte entzogen werden. Mit der Klausel <span class="emphasis">CASCADE CONSTRAINTS</span> werden alle von Benutzern erstellten referenziellen Integrit&auml;ts-Constraints gel&ouml;scht, wenn deren <span class="emphasis">REFERENCES</span>-Privileg entzogen wird. Mit der Klausel <span class="emphasis">FORCE</span> werden <span class="emphasis">EXECUTE</span>-Rechte f&uuml;r abh&auml;ngige benutzerdefinierte Tabellen und Typobjekte entzogen. In der Folge werden diese Objekte so lange als ung&uuml;ltig und nicht verwendbar gekennzeichnet, bis sie neu kompiliert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So entziehen Sie einem Benutzer eine Rolle:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>REVOKE read-only FROM sarah;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So entziehen Sie das Zugriffsrecht f&uuml;r Systembefehle:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>REVOKE CREATE ANY SEQUENCE, CREATE ANY DIRECTORY FROM read_only;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So entziehen Sie ein <span class="emphasis">REFERENCES</span>-Privileg:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>REVOKE REFERENCES
ON pubs_new_york.emp
FROM dylan
CASCADE CONSTRAINTS;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>REVOKE { ALL
| SELECT
| INSERT
| DELETE
| UPDATE
| RULE
| REFERENCES
| USAGE} [,...n]
ON {object_name}
TO {grantee_name | PUBLIC | GROUP group_name}
{CASCADE | RESTRICT}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In PostgreSQL k&ouml;nnen Sie Zugriffsrechte f&uuml;r Tabellen, Views und Sequenzen entziehen. Ansonsten ist der Befehl identisch mit dem SQL99-Befehl. N&auml;here Informationen dazu finden Sie in der Beschreibung der SQL99-Syntax von <span class="emphasis">REVOKE</span> und <span class="emphasis">GRANT</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="ROLLBACK">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">ROLLBACK</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">ROLLBACK</span>
  wird eine Transaktion an ihren Anfang oder einen zuvor deklarierten <span class="emphasis">SAVEPOINT</span> zur&uuml;ckgef&uuml;hrt. Sie schlie&szlig;t ge&ouml;ffnete Cursor und gibt genau wie <span class="emphasis">COMMIT</span> Sperren frei.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ROLLBACK [WORK]
[TO SAVEPOINT savepoint_name]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Neben dem Abschluss einer einzelnen oder mehrerer Datenmanipulationsoperationen k&ouml;nnen Sie mit der Anweisung <span class="emphasis">ROLLBACK</span> Transaktionen bis zur letzten ausgef&uuml;hrten <span class="emphasis">BEGIN</span>- oder <span class="emphasis">SAVEPOINT</span>-Anweisung r&uuml;ckg&auml;ngig machen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>SQL99 umfasst die neuen optionalen Schl&uuml;sselw&ouml;rter <span class="emphasis">AND CHAIN</span>. Bislang wird dieser Befehl noch von keinem der vier Hersteller unterst&uuml;tzt. Diese neue Syntax sieht folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ROLLBACK [WORK] [AND [NO] CHAIN]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Option <span class="emphasis">AND CHAIN</span> wird das DBMS aufgefordert, die aktuelle Transaktion zu beenden, aber die gemeinsame Transaktionsumgebung (wie z.&#160;B. die Isolationsebene der Transaktion) in der n&auml;chsten Transaktion weiter zu nutzen. Mit der Option <span class="emphasis">AND NO CHAIN</span> wird einfach eine einzelne Transaktion beendet. Der Befehl <span class="emphasis">ROLLBACK</span> ist von der Funktion dem Befehl <span class="emphasis">ROLLBACK WORK AND NO CHAIN</span> gleichwertig.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ROLLBACK [TRAN[SACTION] [transaction_name |
 @tran_name_variable |
savepoint_name | @savepoint_variable] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">ROLLBACK</span> werden alle Daten&auml;nderungen r&uuml;ckg&auml;ngig gemacht, die in der gerade ge&ouml;ffneten Transaktion oder ab einem bestimmten Savepoint vorgenommen wurden. Wenn <span class="emphasis">ROLLBACK</span> ohne sonstige Angaben ausgef&uuml;hrt wird, wird die aktuelle offene Transaktion zur&uuml;ckgef&uuml;hrt. Mit <span class="emphasis">ROLLBACK</span> werden normalerweise Sperren aufgehoben. Dies ist jedoch nicht der Fall, wenn bis zu einem Savepoint zur&uuml;ckgegangen wird. <span class="emphasis">ROLLBACK</span> verh&auml;lt sich &auml;hnlich wie <span class="emphasis">COMMIT</span>, was verschachtelte Trigger anbelangt, und verringert den Wert der Systemvariablen <span class="emphasis">@@TRANCOUNT</span> um eins.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn <span class="emphasis">ROLLBACK TRANSACTION</span> in einem Trigger verwendet wird, werden alle Daten&auml;nderungen, einschlie&szlig;lich der vom Trigger vorgenommenen, bis zur <span class="emphasis">ROLLBACK</span>-Anweisung zur&uuml;ckgenommen. Verschachtelte Trigger werden nicht ausgef&uuml;hrt, wenn sie auf eine <span class="emphasis">ROLLBACK</span>-Anweisung in einem Trigger folgen. Anweisungen im selben Trigger, die auf die <span class="emphasis">ROLLBACK</span>-Anweisung folgen, sind von dieser aber nicht betroffen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>ROLLBACK [WORK] [TO savepoint_name] [FORCE text];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">ROLLBACK</span> werden alle Daten&auml;nderungen r&uuml;ckg&auml;ngig gemacht, die in der gerade ge&ouml;ffneten Transaktion oder ab einem bestimmten Savepoint vorgenommen wurden. Die Implementierung in Oracle h&auml;lt sich eng an den SQL-Standard, mit Ausnahme der Option <span class="emphasis">FORCE</span>. Mit <span class="emphasis">ROLLBACK FORCE</span> k&ouml;nnen Sie zu einer zweifelhaften verteilten Transaktion zur&uuml;ckgehen. Diese Transaktionen sind in dem Oracle-Systemview <span class="emphasis">DBA_2PC_PENDING</span> beschrieben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>{ROLLBACK | ABORT} [WORK | TRANSACTION];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">ROLLBACK</span> werden alle Daten&auml;nderungen r&uuml;ckg&auml;ngig gemacht, die in der gerade ge&ouml;ffneten Transaktion oder ab einem bestimmten Savepoint vorgenommen wurden. PostgreSQL unterst&uuml;tzt die SQL99-Optionen <span class="emphasis">WORK</span> und <span class="emphasis">TRANSACTION</span>. Nicht unterst&uuml;tzt wird das Zur&uuml;ckf&uuml;hren auf einen Savepoint. Die Option <span class="emphasis">ABORT</span> ist ein Synonym f&uuml;r <span class="emphasis">ROLLBACK</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Nachfolgend sehen Sie einen Transact-SQL-Batch f&uuml;r Microsoft SQL Server, in dem <span class="emphasis">COMMIT</span> und <span class="emphasis">ROLLBACK</span> verwendet werden. Damit wird ein Datensatz in die Tabelle <span class="emphasis">sales</span> eingef&uuml;gt. Schl&auml;gt dieser Vorgang fehl, wird die Transaktion zur&uuml;ckgef&uuml;hrt, ansonsten wird sie festgeschrieben:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>BEGIN TRAN -- initializes a transaction

-- the transaction itself
INSERT INTO sales
VALUES('7896','JR3435','Oct 28 1997',25,'Net 60','BU7832')

-- some error-handling in the event of a failure
IF @@ERROR &lt;&gt; 0
BEGIN
    -- raises an error in the event log and skips to the end
    RAISERROR 50000 'Insert of sales record failed'
    ROLLBACK WORK
    GOTO end_of_batch
END

-- the transaction is committed if no errors are detected
COMMIT TRAN

-- the GOTO label that enables the batch to skip to the end without
-- committing
end_of_batch:
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="SAVEPOINT">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">SAVEPOINT </td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>
Mit diesem Befehl wird ein Savepoint in die aktuelle Transaktion eingef&uuml;gt. Transaktionen k&ouml;nnen mit dem Befehl <span class="emphasis">SAVEPOINT</span> in logische Abschnitte (Breakpoints) aufgeteilt werden. Sie k&ouml;nnen mehrere Savepoints in einer einzelnen Transaktion festlegen. Der Hauptvorteil des Befehls <span class="emphasis">SAVEPOINT</span> besteht darin, dass Transaktionen mit dem Befehl <span class="emphasis">ROLLBACK</span> teilweise auf einen eindeutigen Savepoint zur&uuml;ckgef&uuml;hrt werden k&ouml;nnen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SAVEPOINT savepoint_name</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Einige Hersteller erm&ouml;glichen die Mehrfachvergabe von Savepoint-Namen in einer Transaktion, davon sei jedoch abgeraten. Ersatz-Savepoint-Identifier (im Format :X) k&ouml;nnen ebenfalls verwendet werden, damit das DBMS die Savepoints anhand einer Ganzzahl anstatt eines Namens verwalten kann. Nicht alle Hersteller unterst&uuml;tzen dies, und besonders guter Stil ist es auch nicht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Beachten Sie, dass SQL99 die Anweisung <span class="emphasis">RELEASE SAVEPOINT savepoint_name</span> unterst&uuml;tzt, mit der ein Savepoint gel&ouml;scht werden kann. Diese Anweisung wird jedoch von keinem der in diesem Buch behandelten Hersteller unterst&uuml;tzt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SAVE TRAN[SACTION] {savepoint_name | @savepoint_variable}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt den Befehl <span class="emphasis">SAVEPOINT</span> nicht. Statt dessen k&ouml;nnen Sie den Befehl <span class="emphasis">SAVE</span> verwenden. Statt einen Literalnamen f&uuml;r den Savepoint zu deklarieren, k&ouml;nnen Sie eine Variable referenzieren, die den Namen des Savepoints enth&auml;lt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn der Befehl <span class="emphasis">ROLLBACK TRAN savepoint_name</span> ausgef&uuml;hrt wird, f&uuml;hrt SQL Server die Transaktion zu dem entsprechenden Savepoint zur&uuml;ck und macht mit der Verarbeitung des n&auml;chsten g&uuml;ltigen Transact-SQL-Befehls nach der Anweisung <span class="emphasis">ROLLBACK</span>
weiter. Zum Schluss muss die Transaktion mit einer <span class="emphasis">COMMIT</span>-  oder einer abschlie&szlig;enden <span class="emphasis">ROLLBACK</span>-Anweisung beendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SAVEPOINT savepoint_name</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle unterst&uuml;tzt die SQL99-Implementierung vollst&auml;ndig.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel werden zun&auml;chst verschiedene Datenmodifizierungen ausgef&uuml;hrt. Dann wird zu einem Savepoint zur&uuml;ckgegangen und anschlie&szlig;end die Transaktion vollst&auml;ndig zur&uuml;ckgef&uuml;hrt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>INSERT INTO sales VALUES('7896','JR3435','Oct 28 1997',25,'Net
60','BU7832');

SAVEPOINT after_insert;

UPDATE sales SET terms = 'Net 90'
WHERE sales_id = '7896';

SAVEPOINT after_update;

DELETE sales;

ROLLBACK TO after_insert;
ROLLBACK;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="SELECT">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name"> SELECT</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p><span class="emphasis"></span>


Mit der Anweisung <span class="emphasis">SELECT</span> werden Zeilen, Spalten und abgeleitete Werte aus einer oder mehreren Tabellen einer Datenbank abgerufen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen (ANSI-Joins werden unterst&uuml;tzt)</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen (ANSI-Joins werden teilweise unterst&uuml;tzt)</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen (ANSI-Joins werden nicht unterst&uuml;tzt)</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen (ANSI-Joins werden teilweise unterst&uuml;tzt)</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die vollst&auml;ndige Syntax der Anweisung <span class="emphasis">SELECT</span> ist m&auml;chtig und komplex, l&auml;sst sich aber in folgende Hauptklauseln aufteilen:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT [ALL | DISTINCT] select_list
FROM table_name1 [,..., table_nameN]
[JOIN join_condition]
[WHERE search_condition]
[GROUP BY group_by_expression]
[HAVING search_condition]
[ORDER BY order_expression [ASC | DESC] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Jede Klausel der Anweisung <span class="emphasis">SELECT</span> hat eine bestimmte Aufgabe. Man kann daher die Klauseln <span class="emphasis">FROM</span>, <span class="emphasis">WHERE</span> und <span class="emphasis">GROUP BY</span> getrennt voneinander betrachten. Allerdings ist nicht f&uuml;r jede Abfrage jede Klausel erforderlich. Zu einer Abfrage geh&ouml;ren als Mindestanforderung eine <span class="emphasis">SELECT</span>-Liste und eine <span class="emphasis">FROM</span>-Klausel. (Microsoft SQL Server und PostgreSQL unterst&uuml;tzen bestimmte Abfragetypen, bei denen keine <span class="emphasis">FROM</span>-Klausel erforderlich ist. N&auml;heres dazu in den Beispielen unten.)</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SELECT-Liste</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die <span class="emphasis">SELECT-Liste</span> enth&auml;lt im Wesentlichen alle Informationen, die ein Benutzer vom Server abrufen m&ouml;chte. In der <span class="emphasis">SELECT</span>-Liste k&ouml;nnen verschiedene Arten von Elementen vorkommen, wie zum Beispiel Literalstrings, Aggregatfunktionen und mathematische Berechnungen. In Microsoft SQL Server kann die <span class="emphasis">SELECT</span>-Liste auch eine Unterabfrage enthalten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Vorgabe ist <span class="emphasis">ALL</span>, d.&#160;h. es werden alle Datens&auml;tze, einschlie&szlig;lich der Standardwerte, zur&uuml;ckgegeben. <span class="emphasis">DISTINCT</span> ist ein Schl&uuml;sselwort, das daf&uuml;r sorgt, dass die Abfrage alle doppelten Datens&auml;tze herausfiltert. Die Ergebnismenge enth&auml;lt somit nur jeweils eine Instanz identischer Datens&auml;tze.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Es gibt noch weitere Regeln, die bestimmen, was in der <span class="emphasis">SELECT</span>-Liste enthalten sein darf:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ol><li>Die einzelnen Spalten sollten mit einem Komma voneinander getrennt werden.</li><li>Ein Sternchen (*) bezeichnet alle Spalten in allen Tabellen in der Klausel <span class="emphasis">FROM</span>, so wie sie in der Anweisung <span class="emphasis">CREATE TABLE</span> stehen.</li><li>Spalten-Aliasnamen k&ouml;nnen hinzugef&uuml;gt werden, um die voreingestellten Spalten&uuml;berschriften in den Ergebnissen zu ersetzen. Verwenden Sie das Format <span class="emphasis">spalte AS "alias"</span> oder <span class="emphasis">spalte alias</span>. Dies ist besonders n&uuml;tzlich, wenn eine Spalten&uuml;berschrift zu kryptisch oder zu lang ist, um leicht verstanden zu werden. Beispiel:</li><li>Sofern dies unterst&uuml;tzt wird, k&ouml;nnen auch lokale und globale Variablen in der SELECT-Liste stehen.</li><li>In der gesamten SQL- oder Transact-SQL-Anweisung k&ouml;nnen Kommentare stehen, die mit einem doppelten Gedankenstrich (<span class="emphasis">&#8212;</span>) oder einer Schr&auml;gstrich-Sternchen-Folge (<span class="emphasis"> /* ... */</span> ) markiert werden m&uuml;ssen. Der doppelte Gedankenstrich sorgt daf&uuml;r, dass die Abfrage s&auml;mtlichen Text nach dem doppelten Gedankenstrich bis zum Zeilenende ignoriert. Bei der Schr&auml;gstrich-Sternchen-Folge wird s&auml;mtlicher Text zwischen der Schr&auml;gstrich-Sternchen-Folge und der Sternchen-Schr&auml;gstrich-Folge ignoriert.</li><li>In einer Abfrage &uuml;ber mehrere Tabellen hinweg sollte dem Spaltennamen der Tabellenname vorangestellt werden. Genaugenommen muss sich der Tabellenname auf alle Spalten in <span class="emphasis">beiden</span> Tabellen beziehen. Es gilt jedoch als guter Stil, diese Angabe immer zu machen. Im folgenden Beispiel ist die Spalte <span class="emphasis">job_id</span> sowohl in der Tabelle <span class="emphasis">jobs</span> als auch <span class="emphasis">employee</span> enthalten:</li><li>Wenn eine Spalte aus einem Kontext au&szlig;erhalb des aktuellen Benutzers stammt, sollte der Spalte der Name des Schemas oder des Eigent&uuml;mers vorangestellt werden. Geh&ouml;rt die Tabelle einem anderen Benutzer, muss der Benutzername in der Spaltenreferenz angegeben werden. Angenommen, die folgende Beispielabfrage l&auml;uft in der Datenbank <span class="emphasis">PUBS</span>, ruft gleichzeitig aber auch Daten aus der Datenbank <span class="emphasis">SALES</span> ab:</li><li>In der SELECT-Liste k&ouml;nnen auch Literalausdr&uuml;cke verwendet werden.</li><li>Mathematische Berechnungen k&ouml;nnen in der SELECT-Liste ebenfalls eingegeben werden. In Microsoft SQL Server ist daf&uuml;r keine <span class="emphasis">FROM</span>-Anweisung erforderlich. In Oracle sollte die Berechnung unter Verwendung der Systemtabelle <span class="emphasis">DUAL</span> ausgef&uuml;hrt werden. Diese Tabelle erm&ouml;glicht es dem SELECT-Befehl, auch dann Werte abzurufen, wenn keine Tabelle vorhanden ist. Beispiel:</li></ol>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">FROM-Klausel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die <span class="emphasis">FROM</span>-Klausel dient im Wesentlichen zwei Zwecken: Auflistung der Tabellen und Views (durch Kommas voneinander getrennt), aus denen Daten abgerufen werden, und Zuweisung eines Aliasnamens f&uuml;r lange Tabellennamen, was das Programmieren langer Abfragen um einiges leichter macht. Ein Aliasname kann in der <span class="emphasis">FROM</span>-Klausel auf zwei verschiedene Arten zugewiesen werden: entweder durch Eingabe des Tabellennamens, eines Leerzeichens und des Aliasnamens oder durch Eingabe des Tabellennamens, <span class="emphasis">AS</span> und des Aliasnamens. Im Beispiel unten werden beide Techniken gezeigt. Dieses Beispiel zeigt eine Abfrage, mit der Daten aus mehreren Tabellen abgerufen werden. Achten Sie dabei vor allem auf die Klauseln <span class="emphasis">FROM</span> und <span class="emphasis">WHERE</span>:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT   e.emp_id,
         e.fname,
         e.lname,
         j.job_desc
FROM     employee e,
         jobs AS  j
WHERE    e.job_id = j.job_id
ORDER BY e.fname,
         e.lname</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn in einer Abfrage ein Aliasnamen zugewiesen wurde, sollten Sie nur diesen f&uuml;r Tabellenreferenzen in dieser Abfrage verwenden. Benutzen Sie <span class="emphasis">nicht</span> sowohl den vollst&auml;ndigen Tabellennamen als auch den Aliasnamen in einer Abfrage.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dieser Abfrage wird die <span class="emphasis">emp_id</span> (Vor- und Nachname der in der Tabelle <span class="emphasis">employee</span> gespeicherten Mitarbeiter) abgerufen, und die <span class="emphasis">job_id</span> des Mitarbeiters, eine Codenummer, mit der vollst&auml;ndigen Jobbeschreibung in der Tabelle <span class="emphasis">JOBS</span> verkn&uuml;pft.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">JOIN-Klausel </span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Implementierungen, die nicht dem ANSI-Standard folgen, wird die Join-Operation in der <span class="emphasis">WHERE</span>-Klausel ausgef&uuml;hrt (siehe Beschreibung im Abschnitt &uuml;ber <span class="emphasis">WHERE</span>-Klauseln). Im ANSI SQL-92-Standard werden Joins in der <span class="emphasis">JOIN</span>-Klausel der Abfrage durchgef&uuml;hrt. Diese beiden Join-Methoden werden als <span class="emphasis">Theta-Joins</span> bzw. <span class="emphasis">ANSI-Joins</span> bezeichnet.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Um korrelierte Daten aus zwei oder mehreren Tabellen abrufen zu k&ouml;nnen, m&uuml;ssen die Tabellen eine sinnvolle Beziehung zueinander haben. <span class="emphasis">Die zu verbindenden Tabellen m&uuml;ssen eine oder mehrere Spalten besitzen, die eine gemeinsame Menge von Werten enthalten. Nur dann k&ouml;nnen die Tabellen sinnvoll verkn&uuml;pft werden.</span> Diese Spalte oder Spalten werden <span class="emphasis">Join-Schl&uuml;ssel</span> oder <span class="emphasis">gemeinsame Schl&uuml;ssel</span> genannt. Meistens, wenn auch nicht immer, ist der Join-Schl&uuml;ssel der Prim&auml;rschl&uuml;ssel der einen Tabelle und ein Fremdschl&uuml;ssel in der anderen Tabelle. Wenn die Daten in den Spalten zueinander passen, kann eine Verkn&uuml;pfung erfolgen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In der Datenbank <span class="emphasis">PUBS</span> enth&auml;lt sowohl die Tabelle <span class="emphasis">employee</span> als auch die Tabelle <span class="emphasis">jobs</span> eine Spalte namens <span class="emphasis">job_id</span>. Somit ist die Spalte <span class="emphasis">job_id</span> der gemeinsame Schl&uuml;ssel der Tabellen <span class="emphasis">employee</span> und <span class="emphasis">jobs</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Um eine Abfrage mit einem ANSI-Join durchzuf&uuml;hren, geben Sie die erste Tabelle und das Schl&uuml;sselwort <span class="emphasis">JOIN</span> an, gefolgt von der zu verkn&uuml;pfenden Tabelle. Geben Sie anschlie&szlig;end das Schl&uuml;sselwort <span class="emphasis">ON</span> und die Join-Bedingung an, die Sie auch in der traditionellen Abfrage verwendet h&auml;tten. Das folgende Beispiel zeigt die obige Abfrage nun im ANSI-Stil:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT   e.emp_id,
         e.fname,
         e.lname,
         j.job_desc
FROM     employee AS e
JOIN     jobs AS j ON e.job_id = j.job_id
ORDER BY e.fname,
         e.lname</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Join-Typen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Unterscheidung zwischen verschiedenen Joins erfolgt durch die Join-Typen im ANSI-Stil und die

Gleichheitszeichen-Sternchen-Kombination ("<span class="emphasis">=*</span>") in Microsoft SQL Server bzw.
Pluszeichen-Sternchen ("<span class="emphasis">+*</span>") in Oracle f&uuml;r Theta-Joins. Nachfolgend sind die einzelnen Join-Typen und ihr Verhalten beschrieben:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ul><li><i>Cross Join</i><br>&#160;
						  Vollst&auml;ndiges Kreuzprodukt zweier Tabellen. F&uuml;r jeden Datensatz in der ersten Tabelle werden alle Datens&auml;tze der zweiten Tabelle verkn&uuml;pft, was zu einer <span class="emphasis">riesigen</span> Ergebnismenge f&uuml;hrt. Dieser Befehl hat dieselben Auswirkungen wie das Weglassen der Join-Bedingungen und wird auch "Kartesisches Produkt" genannt. Die Verwendung von Cross Joins ist weder ratsam noch empfehlenswert (wird derzeit von Microsoft SQL Server unterst&uuml;tzt):</li><li><i><span class="emphasis">Inner Join</span></i><br>&#160;
						  Legt fest, dass nicht zusammenpassende Zeilen aus beiden Tabellen verworfen werden. Wenn kein Join-Typ im ANSI-Stil angegeben wird, sieht der Standard folgenderma&szlig;en aus (wird derzeit von Microsoft SQL Server, PostgreSQL und MySQL unterst&uuml;tzt):</li><li><i><span class="emphasis">Left [Outer] Join</span></i><br>&#160;

Hier werden alle Datens&auml;tze aus der Tabelle auf der linken Seite der Join-Anweisung zur&uuml;ckgegeben. Wenn es zu einem Datensatz aus der linken Tabelle kein passendes Gegenst&uuml;ck in der rechten Tabelle gibt, wird dieser trotzdem zur&uuml;ckgegeben. Die Spalten aus der rechten Tabelle erhalten dann NULL-Werte. (In diesem Fall werden alle Mitarbeiter zur&uuml;ckgegeben, unabh&auml;ngig davon, ob es f&uuml;r diese eine Jobbeschreibung gibt oder nicht.) Viele Programmierprofis raten, Outer Joins aus Konsistenzgr&uuml;nden als Left Joins zu konfigurieren, sofern dies m&ouml;glich ist (wird derzeit von Microsoft SQL Server unterst&uuml;tzt):</li><li><i><span class="emphasis">Right [Outer] Join</span></i><br>&#160;
						  Alle Datens&auml;tze aus der Tabelle auf der rechten Seite der Join-Anweisung werden zur&uuml;ckgegeben, auch wenn es in der Tabelle auf der linken Seite keinen passenden Datensatz gibt. Die Spalten aus der linken Tabelle erhalten dann NULL-Werte. Im Beispiel werden alle Datens&auml;tze aus der Tabelle <span class="emphasis">jobs</span> zur&uuml;ckgegeben, unabh&auml;ngig davon, ob es in der Tabelle <span class="emphasis">employee</span> einen entsprechenden Datensatz gibt (wird derzeit von Microsoft SQL Server unterst&uuml;tzt):</li><li><i><span class="emphasis">Full Join</span></i><br>&#160;
						  Alle Zeilen aus allen Tabellen werden zur&uuml;ckgegeben, unabh&auml;ngig davon, ob es in der anderen Tabelle dazu passende Datens&auml;tze gibt. In den F&auml;llen, in denen die Verkn&uuml;pfung keine Daten enth&auml;lt, besteht die Ergebnismenge aus NULL-Werten (wird derzeit von Microsoft SQL Server unterst&uuml;tzt):</li></ul>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Joins im ANSI-Format sind leichter verst&auml;ndlich als Theta-Joins, weil in der Abfrage selbst genau angegeben ist, welche Tabelle bei einem <span class="emphasis">LEFT JOIN</span> auf der linken Seite steht und welche bei einem <span class="emphasis">RIGHT JOIN</span> auf der rechten Seite.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Syntax zur Durchf&uuml;hrung einer &auml;hnlichen Abfrage mit mehrteiligen Schl&uuml;sseln und mehreren verkn&uuml;pften Tabellen ist im Wesentlichen eine Erweiterung derselben Technik.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel f&uuml;r einen Join mit mehreren Tabellen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>--Theta-Abfrage mit mehreren Tabellen
SELECT   a.au_lname,
         a.au_fname,
         t2.title
FROM     authors a,
         titleauthor t1,
         titles t2
WHERE    a.au_id     = t1.au_id
  AND    t1.title_id = t2.title_id
ORDER BY t2.title

-- ANSI-Abfrage mit mehreren Tabellen
SELECT   a.au_lname,
         a.au_fname,
         t2.title
FROM     authors a
JOIN     titleauthor AS t1 ON a.au_id     = t1.au_id
JOIN     titles      AS t2 ON t1.title_id = t2.title_id
ORDER BY t2.title</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel f&uuml;r einen Join mit mehrteiligem Schl&uuml;ssel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>--Theta-Abfrage mit mehrteiligem Schl&uuml;ssel
SELECT   s1.store_id,
         s1.title_id,
         s2.qty
FROM     sales s1,
         sales_projections s2
WHERE    s1.store_id = s2.store_id
  AND  s1.title_id = s2.title_id
ORDER BY s1.store_id, s2.title_id

-- ANSI-Abfrage mit mehrteiligem Schl&uuml;ssel
SELECT   s1.store_id,
         s1.title_id,
         s2.qty
FROM     sales s1
JOIN     sales_projections s2 ON s1.store_id = s2.store_id
   AND   s1.title_id = s2.title_id
ORDER BY s1.store_id, s2.title_id</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">WHERE-Klausel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die <span class="emphasis">WHERE</span>-Klausel  ist ein extrem m&auml;chtiger Bestandteil der <span class="emphasis">SELECT</span>-Anweisung. Sie enth&auml;lt die meisten der Suchbedingungen, mit denen unerw&uuml;nschte Daten aus der Abfrage entfernt werden. Die restlichen Suchbedingungen sind dann Gegenstand der weiter unten erl&auml;uterten <span class="emphasis">HAVING</span>-Klausel.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Eine schlecht geschriebene <span class="emphasis">WHERE</span>-Klausel kann eine ansonsten sch&ouml;ne <span class="emphasis">SELECT</span>-Anweisung ruinieren. Setzen Sie sich daher <span class="emphasis">eingehend</span> mit der <span class="emphasis">WHERE</span>-Klausel auseinander. Nachfolgend ein Beispiel f&uuml;r eine typische Abfrage und eine mehrteilige <span class="emphasis">WHERE</span>-Klausel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT   a.au_lname,
         a.au_fname,
         t2.title,
         convert(char,t2.pubdate)
FROM     authors a
JOIN     titleauthor t1 ON a.au_id = t1.au_id
JOIN     titles t2 ON t1.title_id = t2.title_id
WHERE    (t2.type = 'business' OR t2.type = 'popular_comp')
  AND    t2.advance &gt; $5500
ORDER BY t2.title</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Beachten Sie, dass die runden Klammern die Reihenfolge beeinflussen, in der die <span class="emphasis">WHERE</span>-Kriterien verarbeitet werden (<span class="emphasis">Rangfolge der Operatoren</span>).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Standard-<span class="emphasis">Sortierreihenfolge</span> wird festgelegt, wie die <span class="emphasis">WHERE</span>-Klausel die Ergebnismengen f&uuml;r eine Abfrage abruft. In Microsoft SQL Server zum Beispiel ist standardm&auml;&szlig;ig <span class="emphasis">dictionary-order</span> und <span class="emphasis">case-insensitive</span> eingestellt, was bewirkt, dass keine Unterscheidung zwischen "Smith", "smith" und "SMITH" getroffen wird. In Oracle dagegen wird <span class="emphasis">dictionary-order</span> und <span class="emphasis">case-sensitive</span> verwendet, so dass die Werte "Smith", "smith" und "SMITH" nicht gleich sind.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die <span class="emphasis">WHERE</span>-Klausel bietet noch weitere spezielle Funktionen, die &uuml;ber dieses Beispiel hinausgehen. In Tabelle 3.9 finden Sie eine Zusammenfassung der gebr&auml;uchlichsten Funktionen der <span class="emphasis">WHERE</span>-Klausel.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Suchbedingung in Kurzform</th><th>Syntax</th><th>Beispiel</th><th>Verwendung und Beschreibung</th></tr>
								<tr><td>Einfache Boolesche Abfrage</td>
									<td><pre>WHERE [NOT] expression
comparison_operator  expression</pre>
									</td>
									<td><pre>SELECT au_id
FROM   authors
WHERE  au_id = '172-32-1176'

SELECT au_id
FROM   authors
WHERE  au_lname NOT LIKE 'John%'</pre>
									</td><td>Die Operatoren &lt;, &gt;, &lt;&gt;, &gt;=, &lt;= und = k&ouml;nnen f&uuml;r den Vergleich von Ausdr&uuml;cken verwendet werden. Es gibt auch eine Reihe speziellerer Vergleichsoperatoren wie <span class="emphasis">LIKE</span>, die weiter unten in dieser Tabelle beschrieben sind. Mit dem Schl&uuml;sselwort <span class="emphasis">NOT</span> wird das Gegenteil jeder Booleschen Bedingung abgefragt, basierend auf den normalen Operatoren &lt;, &gt;, &lt;&gt;, &gt;=, &lt;= und = sowie den speziellen Operatoren wie <span class="emphasis">LIKE</span>, <span class="emphasis">NULL</span>, <span class="emphasis">BETWEEN</span>, <span class="emphasis">IN</span>, <span class="emphasis">EXISTS</span>, <span class="emphasis">ANY</span> und <span class="emphasis">ALL</span>.</td>
								</tr>
								<tr><td>Mehrfache Suchbedingungen</td>
									<td><pre>WHERE [NOT] expression
comparison_operator expression
{AND | OR}
expression comparison_operator
expression</pre>
									</td>
									<td><pre>SELECT au_id
FROM   authors
WHERE  au_id = '172-32-1176'
  AND  au_lname = 'White'</pre>
									</td><td><span class="emphasis">AND</span> fasst mehrere Suchbedingungen zusammen und gibt Ergebnisse zur&uuml;ck, wenn <span class="emphasis">beide</span> Bedingungen wahr sind. <span class="emphasis">AND</span> hat Vorrang vor anderen Operatoren.Dar&uuml;ber hinaus l&auml;sst sich mit runden Klammern in der <span class="emphasis">WHERE</span>-Klausel die Rangfolge der Operatoren beeinflussen. <span class="emphasis">OR</span> fasst mehrere Bedingungen zusammen und gibt Ergebnisse zur&uuml;ck, wenn <span class="emphasis">mindestens eine der beiden</span> Bedingungen wahr ist. <span class="emphasis">OR</span> hat eine niedrigere Priorit&auml;t als <span class="emphasis">AND</span>.</td>
								</tr>
								<tr><td><span class="emphasis">NULL</span>-Abfrage</td>
									<td><pre>WHERE [NOT] column_name IS [NOT]
NULL</pre>
									</td>
									<td><pre>SELECT *
FROM   titles
WHERE  price IS NULL</pre>
									</td><td>Mit <span class="emphasis">IS NULL</span> und <span class="emphasis">IS NOT NULL</span> wird der Abfrage mitgeteilt, dass sie Nullwerte (bzw. alle Werte au&szlig;er Null) suchen soll.</td>
								</tr>
								<tr><td><span class="emphasis">JOIN</span>-Abfrage</td><td><pre>WHERE [NOT] column_value(s)
[(+)]=[(+)] column_value(s)</pre> Oder<pre>WHERE [NOT] column_value(s)
[*]=[*] column_value(s)</pre>
									</td>
									<td><pre>SELECT a.au_lname,
       a.au_fname,
       t2.title
FROM  authors a,
      titleauthor t1,
      titles t2
WHERE a.au_id = t1.au_id
  AND t1.title_id = t2.title_id
ORDER BY t2.title</pre>
									</td><td><span class="emphasis">JOIN</span>-Abfragen k&ouml;nnen durch Auswerten des gemeinsamen Schl&uuml;ssels zweier oder mehrerer Tabellen durchgef&uuml;hrt werden. Outer Joins werden in PostgreSQL durchgef&uuml;hrt, indem die Seite, auf der alle Datens&auml;tze abgerufen werden sollen, mit einem Sternchen gekennzeichnet wird. In Oracle geschieht dies durch Hinzuf&uuml;gen des eingeklammerten Pluszeichens (+) auf der Seite, auf der Nullwerte zul&auml;ssig sind (ist also im Prinzip das Gegenteil der Sternchen-Methode). N&auml;here Informationen dazu finden Sie im vorherigen Abschnitt &uuml;ber <span class="emphasis">JOINs</span>.</td>
								</tr>
								<tr><td><span class="emphasis">LIKE</span>-Abfrage</td>
									<td><pre>WHERE [NOT] column_name [NOT]
LIKE 'match_string'</pre>
									</td>
									<td><pre>/* get any phone number starting with 415 */
SELECT * FROM authors
WHERE phone LIKE '415%'</pre>
									</td><td>Bei Angabe von <span class="emphasis">LIKE</span> wird eine Mustersuche anhand des Strings in Anf&uuml;hrungszeichen durchgef&uuml;hrt. Die Wildcard-Symbole sind unter <span class="emphasis">LIKE </span>beschrieben.</td>
								</tr>
								<tr><td><span class="emphasis">EXISTS</span>-Abfrage</td>
									<td><pre>WHERE [NOT] EXISTS (subquery)</pre>
									</td>
									<td><pre>SELECT p1.pub_name
FROM publishers p1
WHERE EXISTS
    (SELECT *
    FROM titles t1
    WHERE pub_id =p1.pub_id
      AND type =
      'psychology')</pre>
									</td><td><span class="emphasis">EXISTS</span> wird immer zusammen mit einer Unterabfrage verwendet; anstatt Daten zur&uuml;ckzugeben, ist die Unterabfrage ein Boolescher Test, ob die Daten existieren. In diesem Beispiel werden alle Herausgeber von Psychologieb&uuml;chern zur&uuml;ckgegeben.</td>
								</tr>
								<tr><td><span class="emphasis">BETWEEN</span>-Bereichsabfrage</td>
									<td><pre>WHERE [NOT] expression [NOT] BETWEEN expression AND expression</pre>
									</td>
									<td><pre>SELECT *
FROM titles
WHERE ytd_sales BETWEEN 4000 AND 9000</pre>
									</td><td>Mit <span class="emphasis">BETWEEN</span> wird eine inklusive Bereichs&uuml;berpr&uuml;fung durchgef&uuml;hrt. Dies ist das gleiche wie <span class="emphasis">WHERE</span>
<span class="emphasis">(ausdruck</span>&gt;= <span class="emphasis">x AND ausdruck</span>&lt;= <span class="emphasis">y).</span></td>
								</tr>
								<tr><td><span class="emphasis">IN</span>-Bereichsabfrage</td>
									<td><pre>WHERE [NOT] expression [NOT] IN
(value_list | subquery)</pre>
									</td>
									<td><pre>SELECT *
FROM stores
WHERE state IN ('WA','IL','NY')

SELECT *
FROM stores
WHERE stor_id IN
  (SELECT stor_id
  FROM sales
  WHERE ord_date LIKE
  'Oct%')</pre>
									</td><td><span class="emphasis">IN</span> gibt eine Ergebnismenge zur&uuml;ck, die entweder mit einer Liste von Werten &uuml;bereinstimmt oder der Ergebnismenge der &auml;u&szlig;eren Abfrage entspricht, deren Wert mit den von der Unterabfrage zur&uuml;ckgegebenen Werten &uuml;bereinstimmt. Die <span class="emphasis">value_list</span> bzw. Unterabfrage sollte in Klammern gesetzt werden.</td>
								</tr>
								<tr><td><span class="emphasis">SOME | ALL</span>-Bereichsabfrage</td>
									<td><pre>WHERE [NOT] expression
comparison_operator
{[ANY | SOME] | ALL} (subquery)</pre>
									</td>
									<td><pre>-- Duplizierung der Funktionalit&auml;t von IN
SELECT au_lname,
       au_fname
FROM   authors
WHERE city = ANY
    (SELECT city
     FROM   publishers)
-- Duplizierung der Funktionalit&auml;t von NOT IN
SELECT au_lname,
       au_fname
FROM authors
WHERE city &lt;&gt; ALL
    (SELECT city
     FROM   publishers)
/* to find the titles that got an
advance larger than the minimum
advance amount paid New Moon Books*/
SELECT title
FROM   titles
WHERE  advance &gt; ANY
    (SELECT  advance
     FROM publishers,
      titles
     WHERE titles.pub_id =
       publishers.pub_id
     AND pub_name = 'New
       Moon Books')</pre>
									</td><td><span class="emphasis">ALL</span> und <span class="emphasis">SOME</span> werden immer zusammen mit einer Unterabfrage und einem Vergleichsoperator wie &lt;, &gt;, &lt;&gt;, &gt;=, or &lt;= verwendet. Eine Abfrage vom Typ <span class="emphasis">ALL</span> ergibt entweder TRUE oder FALSE, wenn <span class="emphasis">alle</span> von der Unterabfrage abgerufenen Werte mit dem Wert der <span class="emphasis">WHERE</span>-Klausel (oder der <span class="emphasis">HAVING</span>-Klausel) &uuml;bereinstimmen oder wenn die Unterabfrage keine Zeilen der &auml;u&szlig;eren Anweisung zur&uuml;ckgibt.<span class="emphasis">SOME</span> hat dieselbe Funktion wie <span class="emphasis">EXISTS</span>. Dieser Operator funktioniert wie <span class="emphasis">ALL</span>, ergibt allerdings TRUE, wenn <span class="emphasis">mindestens einer</span> der von der Unterabfrage zur&uuml;ckgegebenen Werte die Vergleichsbedingungen in der <span class="emphasis">WHERE</span>-Klausel der &auml;u&szlig;eren Anweisung erf&uuml;llt.</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wie in Tabelle 3.9,  erw&auml;hnt, k&ouml;nnen mit Wildcard-Zeichen die Suchoptionen erweitert werden, insbesondere mit dem <span class="emphasis">LIKE</span>-Operator. Unter <span class="emphasis">LIKE</span> finden Sie n&auml;here Informationen &uuml;ber die einzelnen Wildcard-Operationen.<span class="emphasis"></span> </p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Aggregate und die GROUP BY-Klausel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die <span class="emphasis">GROUP BY</span>-Klausel (und die <span class="emphasis">HAVING</span>-Klausel) wird nur in Abfragen gebraucht, die <span class="emphasis">Aggregatfunktionen</span> verwenden (siehe oben in diesem Kapitel). Abfragen mit Aggregatfunktionen liefern vielf&auml;ltige zusammenfassende Informationen. Zu den gebr&auml;uchlichsten Aggregatfunktionen geh&ouml;ren:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ol><li><span class="emphasis">AVG</span> gibt den Durchschnitt aller Nicht-NULL-Werte in der oder den angegebenen Spalten zur&uuml;ck.</li><li><span class="emphasis">COUNT</span> z&auml;hlt, wie oft Nicht-NULL-Werte in der oder den angegebenen Spalten vorkommen.</li><li><span class="emphasis">COUNT DISTINCT</span> z&auml;hlt, wie oft unterschiedliche Nicht-NULL-Werte in der oder den angegebenen Spalten vorkommen.</li><li><span class="emphasis">COUNT(*)</span> z&auml;hlt alle Datens&auml;tze in der Tabelle.</li><li><span class="emphasis">MAX</span> gibt den h&ouml;chsten Nicht-NULL-Wert in der oder den angegebenen Spalten zur&uuml;ck.</li><li><span class="emphasis">MIN </span>gibt den niedrigsten Nicht-NULL-Wert in der oder den angegebenen Spalten zur&uuml;ck.</li><li><span class="emphasis">SUM </span>summiert alle Nicht-NULL-Werte in der oder den angegebenen Spalten.</li></ol>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Aggregatfunktionen k&ouml;nnen nicht bei allen Datentypen eingesetzt werden. Nur <span class="emphasis">COUNT</span> und <span class="emphasis">COUNT DISTINCT</span> k&ouml;nnen in Spalten eines beliebigen Datentyps verwendet werden. <span class="emphasis">MIN</span> und <span class="emphasis">MAX</span> funktionieren bei numerischen Spalten (beliebigen Typs) sowie bei Datums- und Zeichenspalten. <span class="emphasis">SUM</span> und <span class="emphasis">AVG</span> k&ouml;nnen nur bei numerischen Spaltentypen angewendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn Aggregatfunktionen f&uuml;r Spalten mit Nullwerten ausgef&uuml;hrt werden m&uuml;ssen, verwenden Sie die Funktion <span class="emphasis">ISNULL( )</span> in SQL Server bzw. die Funktion <span class="emphasis">NVL</span> in Oracle, um den Nullspalten einen Wert zuzuweisen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Abfragen, die einen einzelnen Wert zur&uuml;ckgeben, hei&szlig;en <span class="emphasis">skalare Aggregate</span> . Bei skalaren Aggregaten ist keine <span class="emphasis">GROUP BY</span>-Klausel erforderlich. Beispiel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>--Abfrage
SELECT AVG(price)
FROM titles

--Ergebnisse
14.77</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Abfragen, die sowohl regul&auml;re Spaltenwerte als auch Aggregatfunktionen zur&uuml;ckgeben, werden h&auml;ufig als <span class="emphasis">Vektoraggregate</span> bezeichnet. Vektoraggregate verwenden die <span class="emphasis">GROUP BY</span>-Klausel und geben eine oder mehrere Zeilen zur&uuml;ck. Es gibt einige Regeln, die bei der Verwendung von <span class="emphasis">GROUP BY</span> beachtet werden sollten:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ol><li>Positionieren Sie die <span class="emphasis">GROUP BY</span>-Klausel an der richtigen Stelle &#8211; nach der <span class="emphasis">WHERE</span>-Klausel und vor der <span class="emphasis">ORDER BY</span>-Klausel.</li><li>Beziehen Sie alle Nichtaggregatspalten in die <span class="emphasis">GROUP BY</span>-Klausel mit ein.</li><li>Verwenden Sie keine Spaltenaliasnamen in der <span class="emphasis">GROUP BY</span>-Klausel; Tabellenaliasnamen dagegen sind erlaubt.</li></ol>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Angenommen, Sie m&ouml;chten wissen, wie viele Mitarbeiter im Unternehmen eine bestimmte Arbeit verrichten:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>--Abfrage
SELECT   j.job_desc AS "Job Description",
         COUNT(e.job_id) AS "Nbr in Job"
FROM     employee e
JOIN     jobs j ON e.job_id = j.job_id
GROUP BY j.job_desc

--Ergebnisse
Job Description                                    Nbr in Job
-------------------------------------------------- -----------
Acquisitions Manager                               4
Business Operations Manager                        1
Chief Executive Officer                            1
Chief Financial Officer                            1
Designer                                           3
Editor                                             3
Managing Editor                                    4
Marketing Manager                                  4
Operations Manager                                 4
Productions Manager                                4
Public Relations Manager                           4
Publisher                                          7
Sales Representative                               3</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">HAVING-Klausel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der <span class="emphasis">HAVING</span>-Klausel werden nach dem Ergebnis der <span class="emphasis">GROUP BY</span>-Klausel Suchbedingungen hinzugef&uuml;gt. <span class="emphasis">HAVING</span> hat keine Auswirkung auf die Zeilen, aus denen die Aggregate berechnet werden, sondern nur auf die Zeilen, die von der Abfrage zur&uuml;ckgegeben werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">HAVING</span> funktioniert in &auml;hnlicher Weise wie die <span class="emphasis">WHERE</span>-Klausel. Die <span class="emphasis">HAVING</span>-Klausel verwendet genau dieselben Suchbedingungen wie die WHERE-Klausel, die in Tabelle 3.9n&auml;her beschrieben ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel soll herausgefunden werden, welche Arbeit von mehr als drei Personen verrichtet wird:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>--Abfrage
SELECT   j.job_desc "Job Description",
         COUNT(e.job_id) "Nbr in Job"
FROM     employee e
JOIN     jobs j ON e.job_id = j.job_id
GROUP BY j.job_desc
HAVING   COUNT(e.job_id) &gt; 3

--Ergebnisse
Job Description                                    Nbr in Job
-------------------------------------------------- -----------
Acquisitions Manager                               4
Managing Editor                                    4
Marketing Manager                                  4
Operations Manager                                 4
Productions Manager                                4
Public Relations Manager                           4
Publisher                                          7</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">HAVING</span> sollte nicht zum L&ouml;schen von Zeilen verwendet werden, die auch mit der <span class="emphasis">WHERE</span>-Klausel entfernt werden k&ouml;nnen. <span class="emphasis">HAVING</span>-Bedingungen sollten sich immer nur auf aggregierte Werte beziehen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">ORDER BY-Klausel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Eine Ergebnismenge kann mit der <span class="emphasis">ORDER BY</span>-Klausel entsprechend der Sortierreihenfolge der Datenbank sortiert werden. Die Ergebnismenge kann in aufsteigender (<span class="emphasis">ASC</span>) oder absteigender (<span class="emphasis">DESC</span>) Reihenfolge sortiert werden. (Standard ist die aufsteigende Reihenfolge.) Beispiel:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>--ABFRAGE
SELECT   e.emp_id "Emp ID",
         rtrim(e.fname) || " " || rtrim(e.lname) "Name",
         j.job_desc "Job Desc"
FROM     employee e,
         jobs j
WHERE    e.job_id = j.job_id
  AND    j.job_desc = 'Acquisitions Manager'
ORDER BY e.fname DESC,
         e.lname ASC

--ERGEBNISSE
Emp ID    Name                           Job Desc
--------- ------------------------------ --------------------
M-R38834F Martine Ranc&eacute;                  Acquisitions Manager
MAS70474F Margaret Smith                 Acquisitions Manager
KJJ92907F Karla Jablonski                Acquisitions Manager
GHT50241M Gary Thomas                    Acquisitions Manager</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Sobald die Ergebnismenge anhand der Suchbedingungen verringert wurde, wird sie nach den Nachnamen der Autoren in absteigender Reihenfolge sortiert. Bei gleichen Nachnamen werden die Vornamen der Autoren in aufsteigender Reihenfolge sortiert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Alle hier besprochenen Implementierungen erm&ouml;glichen auch die Verwendung von Ordinalpositionen in der <span class="emphasis">ORDER_BY</span>-Klausel. Die Reihenfolge der Ergebnismenge kann durch Angabe der Nummer der Spaltenposition statt dem Spalten- oder Aliasnamen festgelegt werden. So k&ouml;nnen Sie beispielsweise die Reihenfolge nach <span class="emphasis">au_id</span>, <span class="emphasis">au_ fname</span> und schlie&szlig;lich nach <span class="emphasis">au_lname</span> sortieren:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT au_fname, au_lname, au_id
FROM authors
ORDER BY 3, 1, 2</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im Allgemeinen wird die ORDER BY-Klausel verwendet, um die Sortierreihenfolge der Ergebnismenge einer Abfrage zu bestimmen. Wenn keine <span class="emphasis">ORDER BY</span>-Klausel angegeben ist, geben die meisten Implementierungen die Daten entsprechend ihrer physischen Anordnung in der Tabelle oder entsprechend der Sortierreihenfolge des von der Abfrage verwendeten Index zur&uuml;ck. Das kann zu Problemen f&uuml;hren, wenn der Index oder die physische Sortierreihenfolge der Daten einmal ge&auml;ndert werden sollte. Geben Sie daher immer explizit die Reihenfolge an.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen </span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis"></span>Microsoft bietet verschiedene Varianten der <span class="emphasis">SELECT</span>-Anweisung; dazu geh&ouml;ren Optimiererhinweise, die <span class="emphasis">INTO</span>-Klausel, die <span class="emphasis">TOP</span>-Klausel, <span class="emphasis">GROUP BY</span>-Variationen, <span class="emphasis">COMPUTE</span> und <span class="emphasis">WITH OPTIONS</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SELECT . . . INTO</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT select_list
INTO   new_table_name
FROM   table_source
WHERE  clause</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">SELECT . . . INTO</span>  ist eine heftig diskutierte Befehlsoption, die es nur in SQL Server gibt. Mit dem Befehl <span class="emphasis">SELECT . . . INTO</span> lassen sich schnell aus anderen Tabellen abgefragte Zeilen und Spalten in einer nicht protokollierten Operation in eine neue Tabelle kopieren.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel wird mit Hilfe von <span class="emphasis">SELECT . . . INTO</span> eine Tabelle namens <span class="emphasis">non_mgr_employees</span> erstellt. Die Tabelle enth&auml;lt die <span class="emphasis">emp_id</span>, den Vornamen und den Nachnamen aller Mitarbeiter aus der Tabelle <span class="emphasis">employee</span>, die keine F&uuml;hrungsposition innehaben, zusammen mit den jeweiligen Jobbeschreibungen aus der Tabelle <span class="emphasis">jobs</span>:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>--ABFRAGE
SELECT   e.emp_id "emp_id",
         convert(char(25),rtrim(e.fname) + " " + rtrim(e.lname)) "name",
         substring(j.job_desc,1,30) "job_desc"
INTO     non_mgr_employee
FROM     employee e
    JOIN jobs AS j ON e.job_id = j.job_id
WHERE    j.job_desc NOT LIKE '%MANAG%'
ORDER BY 2,3,1</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die neu erstellte und geladene Tabelle <span class="emphasis">non_mgr_employee</span> kann nun abgefragt werden. Mit einer einfachen Abfrage werden folgende Daten zur&uuml;ckgegeben:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>--ABFRAGE
SELECT   emp_id,
         name,
         job_desc
FROM     non_mgr_emp
ORDER BY 3,2,1

--ERGEBNISSE
emp_id    name                      job_desc
--------- ------------------------- ------------------------------
PTC11962M Philip Cramer             Chief Executive Officer
F-C16315M Francisco Chang           Chief Financial Officer
&lt;...edited for brevity...&gt;
PMA42628M Paolo Accorti             Sales Representative
TPO55093M Timothy O'Rourke          Sales Representative</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">SELECT . . . INTO</span> sollte nur in Entwicklungscode und Nicht-Produktionscode verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">TOP-Klausel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Syntax der <span class="emphasis">TOP</span>-Klausel
 sieht folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT [TOP n [PERCENT] [WITH TIES]] select list
FROM table_name</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Dieser Befehl gibt an, dass nur die ersten <span class="emphasis">n</span> Zeilen in der Ergebnismenge der Abfrage ber&uuml;cksichtigt werden sollen. Wenn zus&auml;tzlich <span class="emphasis">PERCENT</span> angegeben wird, werden nur die ersten <span class="emphasis">n</span> Prozent der Zeilen abgerufen. Das Schl&uuml;sselwort <span class="emphasis">WITH TIES</span> kann nur bei Abfragen mit der <span class="emphasis">ORDER BY</span>-Klausel verwendet werden. Es gibt an, dass zus&auml;tzliche Zeilen aus der Basisergebnismenge mit demselben Wert in der <span class="emphasis">ORDER BY</span>-Klausel zur&uuml;ckgegeben werden und als letzte in den <span class="emphasis">TOP</span>-Zeilen erscheinen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">GROUP BY-Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">GROUP BY</span>  in Microsoft SQL Server unterst&uuml;tzt die Variationen <span class="emphasis">ALL</span>, <span class="emphasis">WITH CUBE</span> und <span class="emphasis">WITH ROLLUP</span>:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>[ GROUP BY [ALL] <span class="replaceable">group_by_expression </span>[,...n]
[ WITH { CUBE | ROLLUP } ] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">ALL</span> werden alle Gruppen in die Ergebnismenge aufgenommen, auch diejenigen, in denen es keine Zeilen gibt, die mit den Filtern in der <span class="emphasis">WHERE</span>-Klausel &uuml;bereinstimmen. <span class="emphasis">ALL</span> kann nicht zusammen mit <span class="emphasis">CUBE</span> oder <span class="emphasis">ROLLUP</span> verwendet werden. <span class="emphasis">CUBE</span> gibt an, dass f&uuml;r jede Kombination aus Gruppe und Untergruppe zus&auml;tzliche Zusammenfassungszeilen in die Ergebnismenge aufgenommen werden sollen. <span class="emphasis">ROLLUP</span> funktioniert &auml;hnlich wie <span class="emphasis">CUBE</span>, allerdings werden hier Gruppen in zusammengefasster hierarchischer Reihenfolge zur&uuml;ckgegeben, jeweils von der niedrigsten zur h&ouml;chsten Ebene in der Gruppe.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">COMPUTE-Klausel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der <span class="emphasis">COMPUTE</span>-Klausel
 werden Summen erzeugt, die als zus&auml;tzliche Zusammenfassungsspalten am Ende der Ergebnismenge erscheinen. Mit der Klausel <span class="emphasis">COMPUTE BY</span> werden Gruppenwechsel und Zwischensummen in der Ergebnismenge erzeugt. <span class="emphasis">COMPUTE BY</span> und <span class="emphasis">COMPUTE</span> k&ouml;nnen beide in derselben Abfrage verwendet werden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>[ COMPUTE { { AVG | COUNT | MAX | MIN | STDEV | STDEVP |VAR | VARP | SUM }
(expression) } [,...n]
[ BY expression [,...n] ] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Argumente (<span class="emphasis">AVG</span>, <span class="emphasis">COUNT</span>, <span class="emphasis">MAX</span>, <span class="emphasis">MIN</span>, <span class="emphasis">STDEV</span>, <span class="emphasis">STDEVP</span>, <span class="emphasis">VAR</span>, <span class="emphasis">VARP</span>, <span class="emphasis">SUM</span>) geben die von der <span class="emphasis">COMPUTE</span>-Klausel durchzuf&uuml;hrende Aggregation an. Der Wert <span class="emphasis">expression</span> ist in der Regel ein Spaltenname. Der Wert <span class="emphasis">BY expression</span> kann eine oder mehrere Spalten enthalten, die in der <span class="emphasis">ORDER BY</span>-Klausel der Abfragen stehen. <span class="emphasis">COMPUTE</span> erscheint in der Abfrage nach der <span class="emphasis">ORDER BY</span>-Klausel.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">OPTION-Klausel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die <span class="emphasis">OPTION</span>-Klausel
 ist die letzte Klausel, die in einer Microsoft SQL Server-Abfrage steht. Sie gibt an, dass in der gesamten Abfrage ein <span class="emphasis">Abfragehinweis</span> verwendet werden soll. Abfragehinweise stellen eine nicht im ANSI-Standard festgelegte Methode dar, mit der Sie die Standardverarbeitung einer Abfrage &auml;ndern k&ouml;nnen. Abfragehinweise und die vollst&auml;ndige Syntax und Verwendung von <span class="emphasis">OPTION</span> gehen &uuml;ber den Umfang dieses Buches hinaus. N&auml;here Informationen dazu finden Sie in der SQL Server-Dokumentation.<span class="emphasis"></span></p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT [STRAIGHT_JOIN][SQL_SMALL_RESULT][SQL_BIG_RESULT][HIGH_PRIORITY]
[INTO {OUTFILE | DUMPFILE} 'file_name' options]
FROM...
JOIN...
[LIMIT [[offset_record,] number_of_rows]];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Zu den MySQL-Erweiterungen geh&ouml;ren &Auml;nderungen am Standard-<span class="emphasis">SELECT</span>-Schl&uuml;sselwort, teilweise <span class="emphasis">JOIN</span>-Unterst&uuml;tzung, die <span class="emphasis">LIMIT</span>-Klausel und die <span class="emphasis">PROCEDURE</span>-Klausel.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die erste Erweiterung der Standard-<span class="emphasis">SELECT</span>-Klausel ist <span class="emphasis">STRAIGHT_ JOIN</span>. <span class="emphasis">STRAIGHT_JOIN</span> zwingt den Optimierer, Tabellen in der Reihenfolge, in der sie in der FROM-Klausel erscheinen, zu verkn&uuml;pfen. <span class="emphasis">SQL_SMALL_RESULT</span> und <span class="emphasis">SQL_BIG_RESULT</span> k&ouml;nnen verwendet werden, wenn die Abfrage eine <span class="emphasis">GROUP BY</span>-oder <span class="emphasis">DISTINCT</span>-Klausel enth&auml;lt. Sie teilen dem Optimierer mit, dass eine kleinere bzw. eine gr&ouml;&szlig;ere Ergebnismenge erzeugt werden soll. Da MySQL eine tempor&auml;re Tabelle anlegt, wenn eine Abfrage eine <span class="emphasis">DISTINCT</span>- oder <span class="emphasis">GROUP BY</span>-Klausel enth&auml;lt, wird MySQL mit diesen optionalen Klauseln aufgefordert, entweder eine schnelle tempor&auml;re Tabelle im Arbeitsspeicher (bei <span class="emphasis">SQL_SMALL_RESULT</span>) oder eine langsamere, festplattenbasierte tempor&auml;re Tabelle (bei <span class="emphasis">SQL_BIG_RESULT</span>) zu erstellen, um die Arbeitstabelle zu verarbeiten. <span class="emphasis">HIGH_PRIORITY</span> gibt der Abfrage eine h&ouml;here Priorit&auml;t als Anweisungen, die Daten in der Tabelle modifizieren. Diese Option sollte nur bei speziellen Abfragen, die schnell durchgef&uuml;hrt werden m&uuml;ssen, verwendet werden. Mit der <span class="emphasis">LIMIT</span>-Klausel wird die Anzahl der Zeilen, die von der Abfrage zur&uuml;ckgegeben werden, wie angegeben beschr&auml;nkt (Beginn: <span class="emphasis">offset_record</span>; Anzahl von Datens&auml;tzen: <span class="emphasis">returning number_of_rows</span>). Wenn nur ein Wert angegeben wird, wird dieser als Anzahl der zur&uuml;ckzugebenden Datens&auml;tze interpretiert, und f&uuml;r <span class="emphasis">offset_record</span> wird vom Standardwert 0 ausgegangen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">SELECT . . . INTO OUTFILE 'file_name'</span> wird die Ergebnismenge der Abfrage in eine Datei im Dateisystem des Hosts geschrieben. Es darf noch keine Datei mit diesem Namen geben. Mit der Syntax <span class="emphasis">SELECT . . . INTO DUMPFILE</span> wird eine einzelne lange Datenzeile ohne Spaltenenden, Zeilenenden oder Steuerzeichen geschrieben. Diese Option wird meistens f&uuml;r BLOB-Dateien verwendet.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>MySQL unterst&uuml;tzt nur die folgenden Typen der <span class="emphasis">JOIN</span>-Syntax:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>[CROSS JOIN]
INNER JOIN
STRAIGHT_JOIN
LEFT [OUTER] JOIN
NATURAL LEFT [OUTER] JOIN</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT {[ALL] [DISTINCT] | [UNIQUE]}...
{columns_and_expressions_list} [,...n] AS alias
[INTO {variable[,...n] | record}]
FROM {[table_name [@database_link]| view_name | snapshot_name]
   | subquery [WITH {READ ONLY | CHECK OPTION [CONSTRAINT constraint_name]}]
   | TABLE {(nested_tbl_column)}
      [PARTITION {partition_name}]
      [SUBPARTITION {subpartition_name}
         [SAMPLE [BLOCK] [sample_percentage]}
WHERE
[[START WITH clause] CONNECT BY clause]
GROUP BY...
[ORDER BY... [NULLS FIRST | NULLS LAST] |
 FOR UPDATE [OF [schema.]table[,...n]] [NOWAIT] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle bietet verschiedene Erweiterungen der <span class="emphasis">SELECT</span>-Anweisung, mit denen zus&auml;tzliche Serverfunktionalit&auml;ten unterst&uuml;tzt werden. Da zum Beispiel sowohl verschachtelte als auch partitionierte Tabellen erstellt werden k&ouml;nnen (siehe <span class="emphasis">CREATE TABLE</span>), erm&ouml;glicht die <span class="emphasis">SELECT</span>-Anweisung Abfragen aus diesen speziell benannten Strukturen. (Die Klausel <span class="emphasis">PARTITION</span> ist nicht erforderlich, wenn die Abfrage von der Standardpartition aus erfolgt.)</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">SAMPLE</span> wird Oracle aufgefordert, Datens&auml;tze aus einer zuf&auml;lligen Auswahl von Zeilen in der Ergebnismenge und nicht aus der gesamten Tabelle auszuw&auml;hlen. Die Klausel <span class="emphasis">SAMPLE BLOCK</span> fordert Oracle auf, Block-Sampling an Stelle von Zeilen-Sampling zu verwenden. Mit dem Sampling-Prozentsatz wird Oracle die gesamte Block- oder Zeilenzahl mitgeteilt, die in der Ausgangsmenge ber&uuml;cksichtigt werden soll. Dieser Wert kann zwischen 0,000001 und 99 liegen. Sampling kann nur bei Abfragen verwendet werden, die auf einer einzigen Tabelle basieren.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Syntax <span class="emphasis">SELECT . . . INTO</span> kann nur in PL/SQL-Code verwendet werden und erm&ouml;glicht es der <span class="emphasis">SELECT</span>-Anweisung, Variablen Werte zuzuweisen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Bei der Abfrage einer verschachtelten Tabelle muss die Klausel <span class="emphasis">FROM TABLE nested_table_column</span> verwendet werden. Die Klausel <span class="emphasis">@database_link</span> erm&ouml;glicht der Abfrage den Zugriff auf Tabellen, die in anderen Datenbanken oder auf anderen Servern gespeichert sind, sofern diese Datenbanken und Server als <span class="emphasis">db_link </span> deklariert wurden (n&auml;here Informationen zu db_link finden Sie in der Dokumentation des Herstellers).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit den Optionen <span class="emphasis">NULL FIRST</span> und <span class="emphasis">NULL LAST</span> der Klausel <span class="emphasis">ORDER BY</span> wird angegeben, dass Zeilen, die Nullwerte enthalten, in der Ergebnismenge an den Anfang bzw. an das Ende gestellt werden sollen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle erm&ouml;glicht die Angabe von Ergebnismengen in einer hierarchischen Reihenfolge. Diese so genannten <span class="emphasis">hierarchischen Abfragen</span> enthalten eine Reihe von Regeln und besondere Verhaltensweisen. Eine vollst&auml;ndige Beschreibung der Regeln f&uuml;r diesen Abfragetyp finden Sie in der Dokumentation des Herstellers. Die Klausel <span class="emphasis">START WITH</span> ist elementarer Bestandteil von hierarchischen Abfragen und gibt die Root-Zeilen einer Hierarchie an. Mit der Klausel <span class="emphasis">CONNECT BY</span> wird die Beziehung zwischen Parent- und Child-Zeilen in der Hierarchie beschrieben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">FOR UPDATE OF</span> wird ausschlie&szlig;lich die von der Abfrage zur&uuml;ckgegebene Zeile gesperrt. Unmittelbar danach sollte ein <span class="emphasis">UPDATE . . . WHERE</span>-, <span class="emphasis">COMMIT</span>- oder <span class="emphasis">ROLLBACK</span>-Befehl kommen. Bei Angabe der Option <span class="emphasis">NOWAIT</span> wartet Oracle nicht, wenn der Datensatz bereits gesperrt ist, sondern beendet die Abfrage und kehrt sofort zum Benutzer zur&uuml;ck.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SELECT...
[INTO [TEMPORARY | TEMP] [TABLE] new_table_name]
FROM...
WHERE...
[FOR UPDATE [OF class_name[,...n]]
[LIMIT {count | ALL} [offset [,number_of_records]] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL erm&ouml;glicht die Erstellung einer neuen Tabelle mit der Syntax <span class="emphasis">SELECT . . . INTO</span>, die im Prinzip genauso funktioniert wie die gleichnamige Syntax in Microsoft SQL Server. Mit der Klausel <span class="emphasis">FOR UPDATE</span> k&ouml;nnen von der Abfrage zur&uuml;ckgegebene Zeilen exklusiv gesperrt werden. Dar&uuml;ber hinaus wird &auml;hnlich wie bei MySQL die Klausel <span class="emphasis">LIMIT</span> unterst&uuml;tzt, mit der die Anzahl der von der Abfrage zur&uuml;ckgegebenen Zeilen beschr&auml;nkt werden kann.     </p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="SET CONNECTION">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">SET CONNECTION</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Die Anweisung <span class="emphasis">SET CONNECTION</span>
 bietet dem Benutzer die M&ouml;glichkeit, zwischen verschiedenen offenen Verbindungen zu einem oder mehreren Datenbankservern umzuschalten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Einschr&auml;nkungen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET CONNECTION {DEFAULT | connection_name}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Dieser Befehl beendet keine Verbindung, sondern schaltet von der aktuellen Verbindung zu der in dem Befehl angegebenen Verbindung bzw. bei Verwendung der <span class="emphasis">DEFAULT</span>-Klausel zur aktuellen Verbindung um. Beim Umschalten zwischen Verbindungen ruht die alte Verbindung (ohne dass &Auml;nderungen festgeschrieben werden), w&auml;hrend die neue Verbindung aktiviert wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der Befehl <span class="emphasis">CONNECT</span> muss zum Herstellen einer neuen Verbindung, der Befehl <span class="emphasis">DISCONNECT</span> zum Trennen einer Verbindung verwendet werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt <span class="emphasis">SET CONNECTION</span> nur in Embedded-SQL (ESQL), nicht aber im interaktiven Microsoft-Abfragewerkzeug SQL Query Analyzer. Es wird die volle SQL99-Syntax unterst&uuml;tzt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Nachfolgend ein vollst&auml;ndiges ESQL-Programm in SQL Server, in dem <span class="emphasis">CONNECT</span>, <span class="emphasis">DISCONNECT</span> und <span class="emphasis">SET CONNECTION</span>verwendet werden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>EXEC SQL CONNECT TO chicago.pubs AS chicago1 USER sa;
EXEC SQL CONNECT TO new_york.pubs AS new_york1 USER read-only;
// opens connections to the servers named "chicago" //
//   and "new_york"//

EXEC SQL SET CONNECTION chicago1;
EXEC SQL SELECT name FROM employee INTO :name;
// sets the chicago1 connection as active and performs work //
//   within that session //

EXEC SQL SET CONNECTION new_york1;
EXEC SQL SELECT name FROM employee INTO :name;
// sets the new_york1 connection as active and performs work //
//   within that session //

EXEC SQL DISCONNECT ALL;
// Terminates all sessions.  You could alternately use two //
//   DISCONNECT commands, one for each named connection. //</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="SET ROLE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">SET ROLE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">SET ROLE</span>




 werden bestimmte Sicherheitsrollen f&uuml;r die aktuelle Sitzung aktiviert oder deaktiviert. Sitzungen werden mit der Anweisung <span class="emphasis">CONNECT</span> erstellt, Rollen dagegen mit der Anweisung <span class="emphasis">CREATE ROLE</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET ROLE {NONE | role_name}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Sitzung wird mit der Anweisung <span class="emphasis">CONNECT</span> ge&ouml;ffnet. Nach Initiierung einer Benutzersitzung wird dieser Sitzung mit der Anweisung <span class="emphasis">SET ROLE</span> eine Reihe von rollenbezogenen Privilegien zugewiesen. Der Befehl <span class="emphasis">SET ROLE</span> kann nur au&szlig;erhalb einer Transaktion ausgef&uuml;hrt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">SET ROLE NONE</span> wird der aktuellen Sitzung eine <span class="emphasis">NULL</span>-Rolle zugewiesen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn der gerade aktiven Benutzersitzung eine Rolle zugewiesen werden soll, kann ein Zeichenstring, eine Datenbankvariable oder eine Systemfunktion wie <span class="emphasis">CURRENT_ROLE</span> oder <span class="emphasis">SYSTEM_ROLE</span> verwendet werden. In allen F&auml;llen muss der angegebene Wert ein g&uuml;ltiger Rollenname sein.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET ROLE {role_name [IDENTIFIED BY password] [,...n]
| [ALL [EXCEPT role_name [,...]]
|  NONE;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wenn ein Benutzer eine Verbindung aufbaut, weist Oracle ihm explizit rollenspezifische Zugriffsrechte zu. Die f&uuml;r die Sitzung geltende(n) Rolle(n) k&ouml;nnen mit dem Befehl <span class="emphasis">SET ROLE</span> ge&auml;ndert werden. Oracle verwendet den Initialisierungsparameter <span class="emphasis">MAX_ENABLED_ROLES</span>, um die maximale Anzahl an Rollen, die gleichzeitig ge&ouml;ffnet sein k&ouml;nnen, festzulegen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der angegebene <span class="emphasis">role_name</span> muss ein g&uuml;ltiger Rollenname sein, der bereits in Oracle vorhanden ist. Nicht angegebene Rollen stehen f&uuml;r die aktuelle Sitzung nicht zur Verf&uuml;gung. Wenn der <span class="emphasis">role_name</span> &uuml;ber ein Kennwort verf&uuml;gt, muss dieses in der Klausel <span class="emphasis">IDENTIFIED BY password</span> angegeben werden. Wenn Sie mehrere
Rollen angeben m&ouml;chten, m&uuml;ssen diese durch Kommas voneinander getrennt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">SET ROLE ALL</span> werden alle Rollen aktiviert, die der aktuellen Sitzung zugewiesen wurden, einschlie&szlig;lich der Rollen, die &uuml;ber andere Rollen gew&auml;hrt wurden. Mit der Klausel <span class="emphasis">EXCEPT</span> k&ouml;nnen Sie bestimmte Rollen ausschlie&szlig;en. <span class="emphasis">SET ROLE ALL</span> kann nicht verwendet werden, wenn ein Kennwort angegeben werden muss. Auf Rollen mit Kennw&ouml;rtern kann nur &uuml;ber die Anweisung <span class="emphasis">SET ROLE role_name IDENTIFIED BY password</span> zugegriffen werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">SET ROLE NONE</span> werden alle Rollen deaktiviert, auch die Standardrolle.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So aktivieren Sie die Rollen <span class="emphasis">read_only</span> und <span class="emphasis">updater</span> mit dem Kennwort <span class="emphasis">editor</span> bzw. <span class="emphasis">red_marker</span> f&uuml;r die aktuelle Sitzung:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET ROLE read_only IDENTIFIED BY editor, updater IDENTIFIED BY red_marker;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>So aktivieren Sie alle Rollen au&szlig;er <span class="emphasis">read_write</span>:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET ROLE ALL EXCEPT read_write;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="SET TIME ZONE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">SET TIME ZONE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">SET TIME ZONE</span>
  wird die Zeitzone der aktuellen Sitzung ge&auml;ndert, wenn eine andere als die Standardzeitzone erforderlich ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET TIME ZONE {LOCAL | INTERVAL {+ | -}'00:00' HOUR TO MINUTE}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wie die meisten <span class="emphasis">SET</span>-Befehle kann auch <span class="emphasis">SET TIME ZONE</span> nur au&szlig;erhalb einer expliziten Transaktion verwendet werden. Mit der Klausel <span class="emphasis">LOCAL</span> wird die Zeitzone der aktuellen Sitzung auf die Standardzeitzone des Servers zur&uuml;ckgesetzt. Ansonsten kann auch ein Intervallwert angegeben werden, mit dem von der Standardzeit nach oben (mit +) oder unten (mit -) abgewichen wird.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET TIME ZONE {'timezone' | LOCAL | DEFAULT
| INTERVAL {+ | -}'00:00' HOUR TO MINUTE};</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In PostgreSQL kann die Zeitzone einer Sitzung mit <span class="emphasis">LOCAL</span> oder <span class="emphasis">DEFAULT</span> auf den Standardwert des Servers gesetzt werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der f&uuml;r die Zeitzone anzugebende Wert h&auml;ngt vom Betriebssystem ab. "PST8PDT" ist beispielsweise eine g&uuml;ltige Zeitzone f&uuml;r Kalifornien auf Linux-Systemen, w&auml;hrend "Europe/Rome" eine g&uuml;ltige Zeitzone f&uuml;r Italien auf Linux- und anderen Systemen ist. Wenn eine ung&uuml;ltige Zeitzone angegeben wird, setzt der Befehl die Zeitzone auf Greenwich Mean Time (GMT).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Zeitzone kann auch als Intervall der Standardzeitzone des Servers angegeben werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel wird die Zeitzone gegen&uuml;ber der aktuellen Standardzeitzone um drei Stunden nach vorne gesetzt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET TIME ZONE INTERVAL +'03:00' HOUR TO MINUTE;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Als N&auml;chstes wird die Zeitzone f&uuml;r die aktuelle Sitzung um viereinhalb Stunden zur&uuml;ck gesetzt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET TIME ZONE INTERVAL -'04:30' HOUR TO MINUTE;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Zum Schluss wird die Zeitzone f&uuml;r die aktuelle Sitzung auf den Standardwert zur&uuml;ckgesetzt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET TIME ZONE LOCAL;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="SET TRANSACTION">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">SET TRANSACTION</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit der Anweisung <span class="emphasis">SET TRANSACTION</span>

 werden zahlreiche Eigenschaften einer Datenmodifikation wie Lesen/Schreiben oder die Isolationsebene gesteuert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Einschr&auml;nkungen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET [LOCAL] TRANSACTION { {READ ONLY | READ WRITE}[,...]
| ISOLATION LEVEL
  {READ COMMITTED
  | READ UNCOMMITTED
  | REPEATABLE READ
  | SERIALIZABLE}[,...]
| DIAGNOSTIC SIZE INT};</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Dieser Befehl befindet sich au&szlig;erhalb des Kontexts eines Transaktion und gilt f&uuml;r die n&auml;chste g&uuml;ltige Transaktion. Er kann mehr als eine Option enthalten, wobei die einzelnen Optionen durch Kommas voneinander zu trennen sind.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">LOCAL</span> k&ouml;nnen die Transaktionseinstellungen nur auf den lokalen Server angewendet werden. Ansonsten gelten die Einstellungen unabh&auml;ngig davon, wo die Transaktion ausgef&uuml;hrt wird. Dies ist eine neue Option in SQL99.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Eine Transaktion kann auch als <span class="emphasis">READ ONLY</span> oder <span class="emphasis">READ WRITE</span> konfiguriert werden. Die Klausel <span class="emphasis">DIAGNOSTIC SIZE</span>, gefolgt von einer Ganzzahl, gibt die Anzahl der Fehlermeldungen an, die f&uuml;r eine Transaktion aufgezeichnet werden sollen. Mit der Anweisung <span class="emphasis">GET DIAGNOSTICS</span> k&ouml;nnen diese Informationen abgerufen werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit der Klausel <span class="emphasis">ISOLATION LEVEL</span> werden verschiedene Eigenschaften des Transaktionsverhaltens im Hinblick auf gleichzeitig stattfindende Transaktionen gesteuert. Mit Isolationsebenen wird gesteuert, wie sich Transaktionen bei <span class="emphasis">Dirty Reads</span>, <span class="emphasis">Non-Repeatable Reads</span> und <span class="emphasis">Phantom Records</span> verhalten:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<ul><li><i><span class="emphasis">Dirty Reads</span> </i><br>&#160;
						  Treten auf, wenn eine Transaktion die ge&auml;nderten Datens&auml;tze einer anderen Transaktion liest, bevor diese beendet ist. Damit kann auch ein Datensatz modifiziert werden, der noch nicht in der Datenbank festgeschrieben wurde.</li><li><i><span class="emphasis">Non-Repeatable Reads</span> </i><br>&#160;
						  Treten auf, wenn eine Transaktion einen Datensatz liest, w&auml;hrend eine andere ihn &auml;ndert. Wenn die erste Transaktion also versucht, den Datensatz nochmals zu lesen, findet sie diesen nicht.</li><li><i><span class="emphasis">Phantom Records</span> </i><br>&#160;
						  Treten auf, wenn eine Transaktion eine Gruppe von Datens&auml;tzen liest, die Daten durch eine Datenmodifikation aber so ge&auml;ndert werden, dass mehr Datens&auml;tze als zuvor zur ersten Transaktion geh&ouml;ren.</li></ul>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Einstellung der Isolationsebene hat Auswirkungen auf diese Anomalien, wie in Tabelle 3.10n&auml;her beschrieben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Isolationsebene</th><th>Dirty Reads</th><th>Non-Repeatable Reads</th><th>Phantom Records</th></tr>
								<tr><td>READ COMMITTED</td><td>Nein</td><td>Ja</td><td>Ja</td>
								</tr>
								<tr><td>READ UNCOMMITTED</td><td>Ja</td><td>Ja</td><td>Ja</td>
								</tr>
								<tr><td>REPEATABLE READ</td><td>Nein</td><td>Nein</td><td>Ja</td>
								</tr>
								<tr><td>SERIALIZABLE</td><td>Nein</td><td>Nein</td><td>Nein</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In SQL99 ist <span class="emphasis">SERIALIZABLE</span> die Standardisolationsebene. <span class="emphasis">READ WRITE</span>-Transaktionen d&uuml;rfen nicht <span class="emphasis">READ UNCOMMITTED</span> sein.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET TRANSACTION ISOLATION LEVEL
{READ COMMITTED
| READ UNCOMMITTED
| REPEATABLE READ
| SERIALIZABLE}</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">READ COMMITTED</span> ist die Standardeinstellung in SQL Server, im Gegensatz zu <span class="emphasis">SERIALIZABLE</span> in SQL99. Die Isolationsebene bleibt w&auml;hrend der gesamten Dauer der Sitzung bestehen, und nicht nur f&uuml;r eine Transaktion wie in SQL99.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle SQL Server: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET TRANSACTION READ ONLY;</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle unterst&uuml;tzt nicht die gesamte Syntax der Anweisung <span class="emphasis">SET TRANSACTION</span>, und die Implementierung von <span class="emphasis">READ ONLY</span> weicht ebenfalls ab. Oracle unterst&uuml;tzt nur <span class="emphasis">READ COMMITTED</span> und <span class="emphasis">SERIALIZABLE</span>. <span class="emphasis">READ COMMITTED</span> ist das Standardverhalten. In Oracle wird mit diesem Befehl eine Transaktion auf der Isolationsebene <span class="emphasis">SERIALIZABLE </span>gestartet. Oracle l&auml;sst <span class="emphasis">SELECT</span>-Befehle nur zu, wenn die folgenden Befehle gesetzt sind: <span class="emphasis">READ ONLY</span>, <span class="emphasis">ALTER SESSION</span>, <span class="emphasis">ALTER SYSTEM</span>, <span class="emphasis">LOCK TABLE</span> und <span class="emphasis">SET ROLE</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">PostgreSQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>SET TRANSACTION ISOLATION LEVEL {READ COMMITTED | SERIALIZABLE};</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL unterst&uuml;tzt nicht die vollst&auml;ndige Syntax der Anweisung <span class="emphasis">SET TRANSACTION</span>. In PostgreSQL gibt <span class="emphasis">SET TRANSACTION ISOLATION LEVEL READ COMMITTED</span><span class="emphasis">
</span>an, dass die schreibgesch&uuml;tzten Zeilen der aktuellen Transaktion vor Beginn der Transaktion festgeschrieben wurden. Dies ist die Standardeinstellung. <span class="emphasis">SERIALIZABLE</span>, die ANSI-Standardisolationsebene, gibt an, dass die schreibgesch&uuml;tzten Zeilen der aktuellen Transaktion vor der ersten erste Datenmodifikation im Batch festgeschrieben wurden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="START TRANSACTION">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">START TRANSACTION</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Neu in SQL99 ist die Anweisung <span class="emphasis">START TRANSACTION</span>,
 die alle Funktionen von <span class="emphasis">SET TRANSACTION</span> unterst&uuml;tzt und dar&uuml;ber hinaus auch eine neue Transaktion startet.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Nicht unterst&uuml;tzt; siehe <span class="emphasis">BEGIN TRAN</span> weiter unten</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Nicht unterst&uuml;tzt; siehe <span class="emphasis">BEGIN TRAN</span> weiter unten</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>START TRANSACTION { {READ ONLY | READ WRITE}[,...]
| ISOLATION LEVEL
  {READ COMMITTED
  | READ UNCOMMITTED
  | REPEATABLE READ
  | SERIALIZABLE}[,...]
| DIAGNOSTIC SIZE INT};</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der einzige Unterschied zwischen <span class="emphasis">SET</span> und <span class="emphasis">START</span> besteht darin, dass <span class="emphasis">SET</span> au&szlig;erhalb der aktuellen Transaktion liegt, w&auml;hrend <span class="emphasis">START</span> den Beginn einer neuen Transaktion kennzeichnet.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">BEGIN TRANSACTION</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Der Befehl <span class="emphasis">BEGIN TRANSACTION</span>
 hat eine &auml;hnliche Funktion wie <span class="emphasis">START TRANSACTION</span>. Sowohl Microsoft SQL Server als auch PostgreSQL unterst&uuml;tzen <span class="emphasis">BEGIN TRANSACTION</span>, auch wenn sie sich hinsichtlich der Syntax ein wenig unterscheiden. Oracle unterst&uuml;tzt implizite, aber keine expliziten Transaktionen. MySQL unterst&uuml;tzt atomare Transaktionen &uuml;berhaupt nicht. <span class="emphasis">BEGIN TRANSACTION</span> deklariert eine explizite Transaktion, legt aber keine Isolationsebenen fest.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Syntax in Microsoft SQL Server sieht folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>BEGIN TRAN[SACTION] [transaction_name | @transaction_variable
[WITH MARK [ 'log_description' ] ] ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Microsoft SQL Server k&ouml;nnen einer Transaktion Namen zugewiesen und Transaktionen mittels einer Variablen referenziert werden. Dies hat jedoch keine Auswirkungen auf die Funktionalit&auml;t und erweitert diese auch nicht. Beim Verschachteln von Transaktionen sollte nur das &auml;u&szlig;erste <span class="emphasis">BEGIN . . . COMMIT</span>- oder <span class="emphasis">BEGIN . . . ROLLBACK</span>-Paar den Transaktionsnamen angeben (sofern ein solcher vorhanden ist).</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Option <span class="emphasis">WITH MARK</span> sorgt daf&uuml;r, dass die Transaktion im Ereignisprotokoll von SQL Server protokolliert wird. Mit <span class="emphasis">WITH MARK 'log_description'</span> k&ouml;nnen Sie einen zus&auml;tzlichen Beschreibungstext f&uuml;r das zu protokollierende Ereignis angeben.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Syntax in PostgreSQL sieht folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>BEGIN [ WORK | TRANSACTION ]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL l&auml;uft normalerweise im Autocommit-Modus, in dem jede Datenmodifikation oder Abfrage eine eigene Transaktion bildet. PostgreSQL f&uuml;hrt normalerweise am Ende der Transaktion ein implizites <span class="emphasis">COMMIT</span> oder <span class="emphasis">ROLLBACK</span> aus. Mit der Anweisung <span class="emphasis">BEGIN</span> kann das n&auml;chste <span class="emphasis">COMMIT</span> oder <span class="emphasis">ROLLBACK</span> explizit deklariert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Verwenden Sie <span class="emphasis">BEGIN</span> immer zusammen mit <span class="emphasis">COMMIT</span> oder <span class="emphasis">ROLLBACK</span>. Ansonsten f&uuml;hrt das DBMS den oder die Befehle erst dann aus, wenn es auf <span class="emphasis">COMMIT</span> oder <span class="emphasis">ROLLBACK</span> st&ouml;&szlig;t. Dies kann m&ouml;glicherweise zu riesigen Transaktionen mit unvorhersehbaren Auswirkungen auf die Daten f&uuml;hren.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Manuell kodierte Transaktionen sind in PostgreSQL wesentlich schneller als Autocommit-Transaktionen. <span class="emphasis">SET TRANSACTION ISOLATION LEVEL</span> sollte direkt nach der Anweisung <span class="emphasis">BEGIN</span> auf <span class="emphasis">SERIALIZABLE</span> gesetzt werden, um die Transaktionsisolation zu optimieren. Ein <span class="emphasis">BEGIN . . . COMMIT </span>-Block kann zahlreiche Datenmodifizierungsanweisungen enthalten (<span class="emphasis">INSERT</span>, <span class="emphasis">UPDATE</span>, <span class="emphasis">DELETE</span>). Bei Ausf&uuml;hrung des Befehls <span class="emphasis">COMMIT</span> finden entweder alle Transaktionen oder &uuml;berhaupt keine statt, je nachdem, ob der Befehl erfolgreich war oder fehlgeschlagen ist.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel werden die drei <span class="emphasis">INSERT</span>-Anweisungen als einzige Transaktion behandelt:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>BEGIN TRANSACTION
   INSERT INTO sales VALUES('7896','JR3435','Oct 28 2001',25,
   'Net 60','BU7832')

   INSERT INTO sales VALUES('7901','JR3435','Oct 28 2001',17,
   'Net 60','BU7832')

   INSERT INTO sales VALUES('7907','JR3435','Oct 28 2001',6,
   'Net 60','BU7832')

COMMIT
GO</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die gesamte Transaktionsgruppe w&uuml;rde jedoch fehlschlagen, wenn in einer der <span class="emphasis">INSERT</span>-Anweisungen eine Verletzung des Prim&auml;rschl&uuml;ssels auftreten w&uuml;rde.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="TRUNCATE TABLE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">TRUNCATE TABLE </td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p><span class="emphasis">TRUNCATE TABLE</span>

 ist eine Anweisung, die nicht zum ANSI-Standard geh&ouml;rt und mit der Sie alle Zeilen aus einer Tabelle l&ouml;schen k&ouml;nnen, ohne dass das L&ouml;schen der einzelnen Zeilen protokolliert wird. Es handelt sich hierbei um einen sehr praktischen Befehl, mit dem schnell alle Datens&auml;tze einer Tabelle gel&ouml;scht werden k&ouml;nnen, ohne die Tabellenstruktur zu ver&auml;ndern und zu viel Platz in den Redo- oder Transaktionsprotokollen zu beanspruchen. Nachteil ist, dass dieser Befehl nicht r&uuml;ckg&auml;ngig werden kann, da keine Protokollierung stattfindet.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>MySQL</td><td>Nicht unterst&uuml;tzt</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>TRUNCATE TABLE <span class="replaceable">name</span></pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Anweisung <span class="emphasis">TRUNCATE TABLE</span> hat dieselbe Wirkung wie eine <span class="emphasis">DELETE</span>-Anweisung ohne <span class="emphasis">WHERE</span>-Klause. In beiden F&auml;llen werden alle Zeilen einer Tabelle gel&ouml;scht. Es gibt jedoch zwei wichtige Unterschiede. <span class="emphasis">TRUNCATE TABLE</span> ist schneller und wird nicht protokolliert, kann also beim Auftreten eines Fehlers nicht r&uuml;ckg&auml;ngig gemacht werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p><span class="emphasis">TRUNCATE TABLE</span> aktiviert normalerweise keine Trigger und funktioniert nicht, wenn die betreffende Tabelle Fremdschl&uuml;ssel enth&auml;lt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiel</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel werden alle Daten aus der Tabelle <span class="emphasis">publishers</span> gel&ouml;scht:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>TRUNCATE TABLE publishers</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>TRUNCATE { CLUSTER [owner.]cluster
   | TABLE [owner.]table [{PRESERVE | PURGE} SNAPSHOT LOG]}
[{DROP | REUSE} STORAGE]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle kann eine Tabelle oder ein indizierter Cluster (aber kein Hash-Cluster) geleert werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Oracle bietet die M&ouml;glichkeit, beim Leeren einer Tabelle das Snapshot-Protokoll beizubehalten oder zu l&ouml;schen, sofern f&uuml;r die Tabelle eines definiert ist. Bei Angabe von <span class="emphasis">PRESERVE</span> wird das Snapshot-Protokoll beibehalten, wenn die Master-Tabelle geleert wird, bei Angabe von <span class="emphasis">PURGE</span> wird es gel&ouml;scht.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Bei Verwendung der Klausel <span class="emphasis">DROP STORAGE</span> wird der von den gel&ouml;schten Zeilen zuvor beanspruchte Festplattenspeicher freigegeben. Bei Verwendung der Klausel <span class="emphasis">REUSE STORAGE</span> bleibt der Speicherplatz im Cluster oder in der Tabelle erhalten.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Hinweis zu Microsoft SQL Server und PostgreSQL</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Beide Implementierungen unterst&uuml;tzen die SQL99-Standardsyntax.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
<div id="UPDATE">
			<table width="100%" cellspacing="0" cellpadding="0" border="0" class="main"><tr>				<td valign="top" class="name">UPDATE</td><td valign="top" nowrap class="compatibility">&#160;</td>
				</tr>
				<tr>
					<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
				</tr>
				<tr>
					<td><p>Mit dem Befehl <span class="emphasis">UPDATE</span>
 werden in einer Tabelle vorhandene Daten ge&auml;ndert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td>
						<table border="1"><tbody><tr><th>Hersteller</th><th>Befehl</th></tr>
								<tr><td>SQL Server</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>MySQL</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>Oracle</td><td>Unterst&uuml;tzt, mit Variationen</td>
								</tr>
								<tr><td>PostgreSQL</td><td>Unterst&uuml;tzt</td>
								</tr>
							</tbody></table>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">SQL99: Syntax und Beschreibung</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>UPDATE {table_name | view_name}
SET {column_name | variable_name} = {DEFAULT | expression} [,...n]
WHERE conditions</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wie die Anweisung <span class="emphasis">DELETE</span> wird auch der Befehl <span class="emphasis">UPDATE</span> selten ohne die Klausel <span class="emphasis">WHERE</span> verwendet, da sich die Anweisung sonst auf jede Zeile in der gesamten Tabelle auswirkt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Es gilt als guter Stil, zuerst einen <span class="emphasis">SELECT</span>-Befehl mit der gleichen <span class="emphasis">WHERE</span>-Klausel und dann die eigentliche <span class="emphasis">UPDATE</span>-Anweisung anzugeben. Auf diese Weise werden alle Zeilen in der Ergebnismenge &uuml;berpr&uuml;ft, bevor die <span class="emphasis">UPDATE</span>-Operation ausgef&uuml;hrt wird. Alle von <span class="emphasis">SELECT</span> zur&uuml;ckgegebenen Zeilen werden durch <span class="emphasis">UPDATE</span> modifiziert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Beispiele</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Eine einfache <span class="emphasis">UPDATE</span>-Anweisung ohne <span class="emphasis">WHERE</span>-Klausel sieht folgenderma&szlig;en aus:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>UPDATE authors
SET contract = 0</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Ohne <span class="emphasis">WHERE</span>-Klausel wird bei allen Autoren in der Tabelle <span class="emphasis">authors</span> der Vertragsstatus auf 0 gesetzt, was bedeutet, dass sie keinen Vertrag mehr haben. Werte k&ouml;nnen auch mathematisch mit einer <span class="emphasis">UPDATE</span>-Anweisung ge&auml;ndert werden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>UPDATE titles
SET price = price * 1.1</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dieser <span class="emphasis">UPDATE</span>-Anweisung w&uuml;rden alle Buchpreise um 10&#160;% erh&ouml;ht werden.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Wird einer <span class="emphasis">UPDATE</span>-Anweisung eine <span class="emphasis">WHERE</span>-Klausel hinzugef&uuml;gt, werden nur bestimmte Datens&auml;tze in der Tabelle ge&auml;ndert:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>UPDATE titles
SET    type  = 'pers_comp',
       price = (price * 1.15)
WHERE  type  = 'popular_com'</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit dieser Abfrage werden an jedem Datensatz des Typs <span class="emphasis">'popular_com'</span> zwei &Auml;nderungen vorgenommen. Durch den Befehl wird der Preise um 15&#160;% erh&ouml;ht und der Typ in <span class="emphasis">'pers_comp'</span> ge&auml;ndert.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Manchmal m&uuml;ssen Werte in einer Tabelle anhand von Werten in einer anderen Tabelle aktualisiert werden. Wenn zum Beispiel das Erscheinungsdatum aller Titel eines bestimmten Autors aktualisiert werden muss, muss zun&auml;chst mit Unterabfragen nach dem Autor und der Liste der Titel gesucht werden:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>UPDATE titles
SET    pubdate = 'Jan 01 2002'
WHERE  title_id IN
    (SELECT title_id
     FROM   titleauthor
     WHERE  au_id IN
         (SELECT au_id
          FROM   authors
          WHERE  au_lname = 'White'))</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Microsoft: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>UPDATE {table_name | view_name} [WITH (table_hint [,...n])]
SET {column_name | variable_name} = {DEFAULT | expression | NULL} [,...n]
[FROM {table [,...n]}]
WHERE {conditions | CURRENT OF [GLOBAL] cursor_name}
[OPTION (query_hint [,...n])]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server ist in der Lage, sowohl Views als auch Tabellen zu aktualisieren. Mit den Klauseln <span class="emphasis">WITH table_hint</span> und <span class="emphasis">OPTION</span> k&ouml;nnen Optimiererhinweise auf Tabellen- und Abfrageebene deklariert werden. Optimiererhinweise &auml;ndern die Standardfunktionalit&auml;t des Abfrageoptimierers. In der Herstellerdokumentation finden Sie eine umfassende Beschreibung der Optimiererhinweise.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Microsoft SQL Server unterst&uuml;tzt die Klausel <span class="emphasis">FROM</span> in einer <span class="emphasis">UPDATE</span>-Anweisung. Der Hauptvorteil dieser Variante besteht darin, dass sich mehrere Tabellen viel einfacher verkn&uuml;pfen lassen. Im folgenden Beispiel werden Tabelle mit beiden Syntaxformaten verkn&uuml;pft:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>-- ANSI-Format
UPDATE titles
SET    pubdate = GETDATE(  )
WHERE  title_id IN
    (SELECT title_id
     FROM   titleauthor
     WHERE  au_id IN
         (SELECT au_id
          FROM   authors
          WHERE  au_lname = 'White'))

-- Microsoft Transact-SQL-Format
UPDATE  titles
SET     pubdate = GETDATE(  )
FROM    authors a,
        titleauthor t2
WHERE   a.au_id     = t2.au_id
    AND t2.title_id = titles.title_id
    AND a.au_lname  = 'White'</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im Transact-SQL-Format m&uuml;ssen schlicht und einfach die drei Tabellen <span class="emphasis">authors</span>, <span class="emphasis">titles</span> und <span class="emphasis">titleauthor</span> miteinander verkn&uuml;pft werden. Um dieselbe Operation im ANSI-Format auszuf&uuml;hren, muss zun&auml;chst die <span class="emphasis">au_id</span> in der Tabelle <span class="emphasis">author</span> gesucht und an die Tabelle <span class="emphasis">titleauthors</span> &uuml;bergeben werden, wo die <span class="emphasis">title_id</span> identifiziert und dann an die Haupt-UPDATE-Anweisung weitergegeben werden muss.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">WHERE CURRENT OF cursor_name</span> teilt SQL Server bei Verwendung mit einem Cursor mit, dass nur der Datensatz, auf dem der Cursor gerade steht, aktualisiert werden soll. Der Cursor kann global oder lokal sein; dar&uuml;ber gibt das Schl&uuml;sselwort <span class="emphasis">GLOBAL</span> Auskunft.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Im folgenden Beispiel wird die Spalte <span class="emphasis">state </span> der ersten 10 Autoren in der Tabelle <span class="emphasis">authors</span> aktualisiert:</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>UPDATE authors
SET state = 'ZZ'
FROM (SELECT TOP 10 * FROM authors ORDER BY au_lname) AS t1
WHERE authors.au_id = t1.au_id</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">MySQL: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>UPDATE [LOW PRIORITY] table_name
SET {column_name | variable_name} = {DEFAULT | expression}
WHERE conditions
[LIMIT integer]</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>MySQL unterst&uuml;tzt den SQL99-Standard mit zwei Variationen: der Klausel <span class="emphasis">LOW PRIORITY</span> und der Klausel <span class="emphasis">LIMIT</span>. Die Klausel <span class="emphasis">LOW PRIORITY</span> fordert MySQL auf, die Ausf&uuml;hrung der Anweisung <span class="emphasis">UPDATE</span> so lange hinauszuz&ouml;gern, bis kein anderer Client mehr aus der Tabelle liest. Mit der Klausel <span class="emphasis">LIMIT</span> wird die <span class="emphasis">UPDATE</span>-Aktion auf die durch den Integerwert angegebene Anzahl an Zeilen beschr&auml;nkt.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Oracle: Syntax und Variationen</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><span class="programlisting"><pre>UPDATE [schema.]{view_name | snapshot_name
   | table_name [@database_link]
      {[PARTITION partition_name] | [SUBPARTITION subpartition_name]}
   | subquery [WITH {[READ ONLY]
      | [CHECK OPTION [CONSTRAINT constraint_name] ]
SET {column [,...] = {expression [,...n] | subquery} | VALUE value}
WHERE conditions | CURRENT OF cursor_name}
RETURNING expression [,...n] INTO variable [,...n];</pre>
						</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Oracle-Implementierung von <span class="emphasis">UPDATE</span> erm&ouml;glicht Aktualisierungen von Views, Snapshots und Tabellen in einem Schema, in dem dies erlaubt ist. Zu aktualisierende Tabellen k&ouml;nnen lokal sein oder &uuml;ber <span class="emphasis">@dblink</span> zur Verf&uuml;gung stehen. Aktualisierungen werden immer in der Partition ausgef&uuml;hrt; der Befehl <span class="emphasis">UPDATE</span> unterst&uuml;tzt aber auch Updates in einer benannten <span class="emphasis">PARTITION</span> oder <span class="emphasis">SUBPARTITION</span>.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Bei der Aktualisierung anhand einer Unterabfrage steht auch die Klausel <span class="emphasis">WITH</span> zur Verf&uuml;gung. Mit der Klausel <span class="emphasis">WITH READ ONLY</span> wird angegeben, dass die Unterabfrage nicht aktualisiert werden kann. Mit <span class="emphasis">WITH CHECK OPTION</span> wird Oracle aufgefordert, s&auml;mtliche &Auml;nderungen an der aktualisierten Tabelle zu verwerfen, die nicht in der Ergebnismenge der Unterabfrage erscheinen. Die Unterklausel <span class="emphasis">CONSTRAINT</span> weist Oracle an, &Auml;nderungen auf der Grundlage eines bestimmten Constraints weiter einzuschr&auml;nken.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Die Klausel <span class="emphasis">SET VALUE</span> bietet dem Benutzer die M&ouml;glichkeit, f&uuml;r beliebige Tabellendatentypen den gesamten Zeilenwert festzulegen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>In Oracle gibt die Klausel <span class="emphasis">WHERE CURRENT OF</span> an, dass die <span class="emphasis">UPDATE</span>-Operation nur f&uuml;r den aktuellen Datensatz im Cursorkontext ausgef&uuml;hrt werden soll.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>Mit <span class="emphasis">RETURNING</span> werden die von dem Befehl betroffenen Zeilen abgerufen. Beim Aktualisieren einer einzelnen Zeile werden die Werte der Zeile in PL/SQL-Variablen und Bindungsvariablen gespeichert. Beim Aktualisieren mehrerer Zeilen dagegen werden die Werte der Zeilen in Bindungs-Arrays gespeichert. Mit dem Schl&uuml;sselwort <span class="emphasis">INTO</span> wird festgelegt, dass die aktualisieren Werte in der Variablenliste gespeichert werden sollen.</p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td valign="top" colspan="2"><span class="title">Hinweise zu PostgreSQL</span></td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
				<tr>
					<td><p>PostgreSQL unterst&uuml;tzt den SQL99-Standard. Eine umfassende Beschreibung des Befehls <span class="emphasis">UPDATE</span>finden Sie oben. </p>
					</td>
				</tr>
				<tr><td valign="top" colspan="2" class="clearseparation">&#160;</td>
				</tr>
			</table>
		</div>
	</body></html>