Diskussion:Einführung in SQL: DML (2) - Daten speichern

Seiteninhalte werden in anderen Sprachen nicht unterstützt.
Aus Wikibooks

Rechtschreibfehler[Bearbeiten]

Dieser Text enthält sehr viele Rechtschreibfehler! --Julius-m 22:32, 21. Jan. 2008 (CET)[Beantworten]

Das erledigt sich durch die vollständige Überarbeitung. -- Juetho 16:44, 4. Okt. 2009 (CEST)[Beantworten]

MERGE[Bearbeiten]

In der Version 10g gibt es noch den MERGE-Befehl als eine Kombination aus INSERT, UPDATE und ggfs. auch DELETE. --Julius-m 22:32, 21. Jan. 2008 (CET)[Beantworten]

Firebird bietet UPDATE OR INSERT. Wir sollten uns aber soweit möglich und sinnvoll auf Standardbefehle beschränken. -- Juetho 12:58, 3. Okt. 2009 (CEST)[Beantworten]

Subselects[Bearbeiten]

Wäre noch interessant, wie man UPDATE, DELETE mit Subselects ausstatten kann, um gezeilter die Satz zu suchen, die verändert werden sollen. --Julius-m 22:32, 21. Jan. 2008 (CET)[Beantworten]

Siehe Einführung in SQL: Unterabfragen unter "Abfragen für Fortgeschrittene". -- Juetho 12:54, 3. Okt. 2009 (CEST)[Beantworten]

Anpassung für Oracle[Bearbeiten]

Ein Auto-ID kenne ich in OracleV.10 nicht, genauso kann es das Datum nicht ohne weiteres interpretieren, daher Hinweis auf folgende Anpassungen. Die ID müsste vorher ermittelt werden z.B. mit "select max (id) from mitarbeiter" und z.B. hier erstmal manuell eingetragen werden.

INSERT INTO Mitarbeiter
       ( id, Personalnummer, Name, Vorname, Geburtsdatum, Telefon,
         Email, Raum, Ist_Leiter, Abteilung_ID )<br />
VALUES ( '29', '20002', 'Schmitz', 'Michael', to_date('1959-08-25','yyyy-MM-dd'), '0231/5556187', 
         'michael.schmitz@unserefirma.de', '212', 'N', 2);

Sinnvoll wäre schon das intialskript der Beispieldatenbank zu ergänzen wegen der "autosequenz" Problematik, da müsste dann was rein wie

create sequence ID 
increment by 1
minvalue 1
cache 10;

Dann sähe das Beispiel für den Abschnitt "Insert" hier so aus:

INSERT INTO Mitarbeiter
       ( id, Personalnummer, Name, Vorname, Geburtsdatum, Telefon,
         Email, Raum, Ist_Leiter, Abteilung_ID )
VALUES (id.nextval, '20002', 'Schmitz', 'Michael', to_date('25.08.1959','dd.MM.yyyy'), '0231/5556187', 
         'michael.schmitz@unserefirma.de', '212', 'N', 2);

141.39.13.5 11:30, 14. Dez. 2010 (CET)CA[Beantworten]

Siehe dazu Einführung in SQL: DDL_-_Einzelheiten#AUTO_INCREMENT_.E2.80.93 automatischer_Zähler. Ob die einzelnen Parameter erforderlich sind oder 1 als Default-Werte gesetzt werden, entzieht sich meiner Kenntnis.
Eine SEQUENCE mit "ID" zu benennen ist eher unpraktisch. Dein Weg (ohne Trigger, direkt in den INSERT-Befehl) ist offensichtlich möglich und einfacher.
Ich kann mir nach wie vor nicht vorstellen, dass Oracle grundsätzlich keinen automatischen Zähler kennt. "select max (id) from mitarbeiter" solltest du schnell vergessen, siehe Oracle: Sequenzen; wenn mehrere Nutzer gleichzeitig Daten erfassen, kommt das System sofort durcheinander. Vielleicht ist es sinnvoll, zwei Versionen für das Beispielskript einzustellen: einmal mit AUTO INCREMENT, einmal mit SEQUENCE.
Das Problem mit den Datumsangaben kann ich nach wie vor nicht verstehen, siehe diese Dokumentation. Vorschlag: Im Skript lassen wir das einfache Datum stehen; irgendwo setzen wir einen Hinweis auf to_date. -- Jürgen 12:04, 14. Dez. 2010 (CET)[Beantworten]
Mit Hilfe eines Oracle-Forums habe ich mich sachkundig gemacht.
  • Die Dokumentation, die ich mir als Grundlage ausgesucht hatte, ist völlig unpassend. Diese "Lite"-Version ist für mobile Computer gedacht (Smartphone usw.), aber nicht für "richtige" PCs. Ich habe die Links auf die Doku der "normalen" Versionen (10g und 11g) umgestellt.
  • AUTO INCREMENT oder SEQUENCE: AUTO INCREMENT gibt es nur bei dieser (unpassenden) Lite-Version. In einer "normalen" Oracle-Version ist mit SEQUENCE zu arbeiten.
  • Die Beschreibung des Datumsformats ist etwas umständlicher:
    • Das Standardformat, das Oracle immer versteht, ergibt sich aus der Länder-Einstellung bei der Installation und kann durch NLS_DATE_FORMAT abgerufen und ggf. geändert werden.
    • Standardmäßig dürfte im deutschsprachigen Raum also 'DD.MM.YYYY' gelten. Aber es ist nicht auszuschließen, dass eine große Firma ein englisches oder amerikanisches Format voreingestellt hat. Deshalb ist es riskant, für die Beispieldatenbank das deutsche Format vorauszusetzen.
    • Man kann das Format für das Skript bei der Beispieldatenbank temporär umstellen mit drei Befehlen wie folgt:
      ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
    • Man kann das verwendete Format (wie oben von 141.39.13.5 vorgesehen) mit der Funktion TO_DATE genau angeben.
    • Man kann jedes Datum, das das Format nach ISO 8601 benutzt, mit dem Schlüsselwort DATE versehen, wie mir im Forum gesagt wurde: Use "date literals".
Ich werde die Beispieldatenbank entsprechend umschreiben mit SEQUENCE und DATE.
Auf jeden Fall danke ich dir für die wertvollen Hinweise und die Erweiterung meiner Kenntnisse. -- Gruß Jürgen 16:54, 14. Jan. 2011 (CET)[Beantworten]

TRUNCATE - Ein DDL-Befehl[Bearbeiten]

Eigentlich ist TRUNCATE ein DDL-Befehl, da es ein implizites COMMIT (fehlt auch in der Beschreibung) sendet und man kann auch keine WHERE/Bedingungen setzen.

Ich bitte dies zu berücksichtigen. Aus Zeitgründen komme nicht selbst dazu, die entsprechenden Einträge zu ändern.

85.22.94.146 11:46, 23. Aug. 2012 (CEST)[Beantworten]

Einspruch! TRUNCATE ist eindeutig ein DML-Befehl. Er manipuliert die Daten, nicht die Definition einer Tabelle. Der Befehl wird in der Regel zusammen mit DELETE behandelt; Beispiele:
  • MSDN: "TRUNCATE TABLE entspricht DELETE ohne WHERE-Klausel."
  • MySQL (5.1): "Logisch gesehen ist dies äquivalent zu einer DELETE-Anweisung, die alle Datensätze löscht, aber es gibt unter bestimmten Umständen praktische Unterschiede."
Wahrscheinlich genügt dir das noch nicht. Dann schau einmal in der SQL-Referenz nach. Über SQL-Standards enthalten die SQL:20nn Working Draft Documents u.a. das Dokument 7IWD2-02-Foundation-2011-12.pdf mit dem Kapitel 14. Data manipulation und dem Abschnitt 14.10 <truncate table statement>. Ich könnte Hinweise auf besondere Bedingungen akzeptieren, die für TRUNCATE zu beachten wären. Da diese aber schon wieder DBMS-spezifisch sind und TRUNCATE für Einsteiger (an die sich das Buch in erster Linie richtet) sehr gefährlich ist, sollte es bei dem kurzen Hinweis bleiben.
Zu deinen Aspekten im Einzelnen: COMMIT wird erst zwei Kapitel später besprochen; was soll dann hier ein solcher Hinweis bringen? Vielleicht bearbeitet ein DBMS intern TRUNCATE wie einen DDL-Befehl, das mag ja sein; aber wie ein DBMS intern arbeitet, hat nichts mit den SQL-Befehlen aus Sicht des Anwenders zu tun. Das Fehlen von WHERE bei TRUNCATE ist doch ein wesentliches Merkmal und im Text erwähnt. Also was soll das? -- Jürgen 15:33, 23. Aug. 2012 (CEST)[Beantworten]
Möglicherweise führt das jeder Hersteller etwas anders auf. Im Handbuch von MysQL (5.5) steht es zumindest in der DDL-Rubrik.
Und dort gehört es meiner Meinung nach auch hin, weil
  • TRUNCATE ändert direkt die Tabellenstruktur, da es Daten einfach abschneidet
  • TRUNCATE umgeht sämtliche DML-Mechanismen (es werden bspw. keine Row-Trigger gefeuert)
  • TRUNCATE beendet (wie bei DDL üblich) offene Transaktionen mit einem COMMIT
  • TRUNCATE ist oftmals als DROP AND re-CREATE realisiert, was Beides DDL ist
Dies in Summe führt dazu, dass ich TRUNCATE rein technisch zu DDL zähle, auch wenn es logisch eher DML wäre. -- Falk Prüfer (mit Falks Genehmigung aus einer PN des Entwickler-Forums kopiert durch Jürgen)
Wegen der Schlussfolgerung und der SQL-Referenz (siehe den Link oben) werde ich TRUNCATE weiterhin bei DML belassen, weil es aus Sicht des reinen Anwenders dazu gehört; und die Leser einer Einführung gehören zwangsläufig in diese Zielgruppe. Aber als Hintergrundwissen sind diese Gesichtspunkte hilfreich. -- Jürgen 15:18, 24. Okt. 2012 (CEST)[Beantworten]
Ich habe jetzt per Fußnote auf der Buchseite auf diese Diskussion hingewiesen. -- Jürgen 09:44, 3. Nov. 2012 (CET)[Beantworten]

Mengen mit SELECT - Abgeschnittenes Beispiel[Bearbeiten]

"Für jeden Abteilungsleiter aus der Tabelle Mitarbeiter wird ein Eintrag in der Tabelle Dienstwagen gespeichert: [...]"

Beispiel ist vollständig im Wiki-Quellcode, wird aber abgeschnitten angezeigt - das doppelte Pipe-Symbol (||) wird vermutlich das Problem sein ... - ‎79.241.106.40 21:11, 11. Okt. 2013 (CEST)[Beantworten]

Danke, ist jetzt korrigiert; siehe TCL. -- Jürgen 10:02, 12. Okt. 2013 (CEST)[Beantworten]