AutoIncr Procedure

AutoIncr Procedure

am 12.09.2006 15:10:06 von Phillip Parr

Hallo,

kann mir jemand kurz das Statement für eine MySQL 5.0-Procedure mit einem
Zähler sagen ? Also ich bräuchte eine, welche eine Art Zählwerk
implementiert und mir bei jedem Aufruf (parameterlos) die folgende Zahl
nennt. Die Prozedur soll dazu dienen, bei jeder Tabelle die
AutoIncr-Funktionalität zu ersetzen. Also für jede Tabelle soll dann solche
eine Prozedur existieren, welche den nächsten freien PKey zurückgeben soll.
Das Statement zum Aufruf dazu wäre auch nicht schlecht ;)

Oder gibt es sowas schon in MySQL ? Ich brauch einen freien PKey noch bevor
der Datensatz gespeichert wird. Den PKey schreibe ich dann jeweils über das
Statement mit.


Danke schonmal für die Hilfe,
oliver

Re: AutoIncr Procedure

am 12.09.2006 15:18:04 von Christian Kirsch

Oliver Neumann schrieb:
> Hallo,
>
> kann mir jemand kurz das Statement für eine MySQL 5.0-Procedure mit einem
> Zähler sagen ? Also ich bräuchte eine, welche eine Art Zählwerk
> implementiert und mir bei jedem Aufruf (parameterlos) die folgende Zahl
> nennt.

In anderen Datenbanken würde man dafür eine Sequence nehmen. Dass Du
zurzeit sowas in MySQL mit einer Stored Procedure implementieren
kannst, bezweifle ich. Dazu müsste es sowas wie Singletons in der
Sprache geben - die habe ich aber bislang nicht gesehen.

> Die Prozedur soll dazu dienen, bei jeder Tabelle die
> AutoIncr-Funktionalität zu ersetzen.

Äh, warum möchtest Du denn etwas ersetzen, was es gibt?

> Also für jede Tabelle soll dann solche
> eine Prozedur existieren, welche den nächsten freien PKey zurückgeben soll.
> Das Statement zum Aufruf dazu wäre auch nicht schlecht ;)

Wie soll das gehen? Welcher wirklich "frei" (whateverthatmeans) ist,
kann doch der Server erst entscheiden, wenn das Insert gerade
stattfindet. Sonst bekommst Du beliebige race conditions:
- Prozess 1 fragt nach next_free und bekommt "n" geliefert.
- Prozess 2 führt ein INSERT durch.
- next_free wäre jetzt "n+1", aber Prozess 1 arbeitet fröhlich
mit "n" weiter - das aber nun nicht länger "frei" ist,
sondern eben von Prozess 2 bereits verbraten wurde.

Kurzfassung: keine gute Idee.

>
> Oder gibt es sowas schon in MySQL ? Ich brauch einen freien PKey noch bevor
> der Datensatz gespeichert wird.

Wozu brauchst Du den?

> Den PKey schreibe ich dann jeweils über das
> Statement mit.

Warum?

Re: AutoIncr Procedure

am 12.09.2006 15:33:23 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: AutoIncr Procedure

am 12.09.2006 15:41:45 von Phillip Parr

Hallo Christian,

> Wie soll das gehen? Welcher wirklich "frei" (whateverthatmeans) ist,
> kann doch der Server erst entscheiden, wenn das Insert gerade
> stattfindet. Sonst bekommst Du beliebige race conditions:
> - Prozess 1 fragt nach next_free und bekommt "n" geliefert.
> - Prozess 2 führt ein INSERT durch.
> - next_free wäre jetzt "n+1", aber Prozess 1 arbeitet fröhlich
> mit "n" weiter - das aber nun nicht länger "frei" ist,
> sondern eben von Prozess 2 bereits verbraten wurde.

ahm nein...da der PKey jeweils nur eimmal zurückgegeben wird gibts das
Problem nicht. Also n wird nur einmal vergeben.

> > Oder gibt es sowas schon in MySQL ? Ich brauch einen freien PKey noch
bevor
> > der Datensatz gespeichert wird.
>
> Wozu brauchst Du den?

Kommt daher, dass ich ein Programm für Oracle Database geschrieben hatte,
welches nun auf MySQL portiert werden soll. Der hat das mit Sequenzen
implementiert. Um nicht zu viel zu ändern wollte ich dasselbe gern in MySQL
haben. Wozu ich die brauche ich ja erstmal egal.

Aber gut, wenn das so jetzt nicht direkt geht, muss ich das eben über den
längeren Weg umändern.


Danke und Gruss,
oliver

Re: AutoIncr Procedure

am 12.09.2006 15:52:00 von Claus Reibenstein

Christian Kirsch schrieb:

> Oliver Neumann schrieb:
>
>> Die Prozedur soll dazu dienen, bei jeder Tabelle die
>> AutoIncr-Funktionalität zu ersetzen.
>
> Äh, warum möchtest Du denn etwas ersetzen, was es gibt?

Vielleicht weil er es in einer bestimmten Form benötigt, die sich damit
nicht erschlagen lässt? Ich denke da an so schöne Dinge wie
Kundennummern, Auftragsnummern, Rechnungsnummen, Produktnummern o.ä.,
die selten nur aus einer einfachen Zahl bestehen und oft auch nicht bei
1 beginnen.

Ich erzeuge mir in solchen Fällen immer eine eigene Tabelle zur
Verwaltung dieser Zähler.

>> Also für jede Tabelle soll dann solche
>> eine Prozedur existieren, welche den nächsten freien PKey zurückgeben soll.
>> Das Statement zum Aufruf dazu wäre auch nicht schlecht ;)
>
> Wie soll das gehen? Welcher wirklich "frei" (whateverthatmeans) ist,
> kann doch der Server erst entscheiden, wenn das Insert gerade
> stattfindet.

Das mag für die Auto-Increments von MySQL gelten, und auch das Problem
lässt sich relativ leicht durch ein INSERT eines Dummies (zur Belegung
des nächsten freien Index) mit anschließendem UPDATE (zur Ablage der
Daten) umgehen.

Bei selbstdefinierten Keys bist Du jedoch völlig frei. Hier kannst Du
selbstverständlich (und musst wahrscheinlich sogar) erst nach dem
nächsten freien PKey fragen, um ihn später zu benutzen. Das ist bei mir
der Normalfall.

> Sonst bekommst Du beliebige race conditions:

Die sich programmtechnisch ohne Weiteres in den Griff bekommen lassen.
Im obigen Beispiel genügt es, die Tabelle zu locken, während einer der
Zähler neu bestimmt wird.

> - Prozess 1 fragt nach next_free und bekommt "n" geliefert.
> - Prozess 2 führt ein INSERT durch.

Programmfehler: Prozess 2 hat nicht nach next_free gefragt!

Gruß. Claus

Re: AutoIncr Procedure

am 12.09.2006 15:52:35 von Christian Kirsch

Andreas Kretschmer schrieb:
> begin Christian Kirsch schrieb:
>> Oliver Neumann schrieb:
>>> Hallo,
>>>
>>> kann mir jemand kurz das Statement für eine MySQL 5.0-Procedure mit einem
>>> Zähler sagen ? Also ich bräuchte eine, welche eine Art Zählwerk
>>> implementiert und mir bei jedem Aufruf (parameterlos) die folgende Zahl
>>> nennt.
>> In anderen Datenbanken würde man dafür eine Sequence nehmen. Dass Du
>
> Korrekt. Hat MySQL das nicht mittlerweile auch?
> http://dev.mysql.com/doc/maxdb/en/6d/117c29d14811d2a97400a0c 9449261/content.htm
>
> Ach, das ist wohl MaxDB?

Yep.
>
> Aber vielleicht hilft dem Fragesteller ja dies:
> http://dev.mysql.com/doc/refman/5.0/en/information-functions .html
>
Da gibt's nur LAST_INSERT_ID(), und das liefert eben die ID *nach* dem
Insert (was mir bislang immer gereicht hat - was soll ich mit einem
"wenn nichts dazwischen kommt, ist die nächste ID *vermutlich* 123"?)

>
>>> Oder gibt es sowas schon in MySQL ? Ich brauch einen freien PKey noch bevor
>>> der Datensatz gespeichert wird.
>> Wozu brauchst Du den?
>
> Gute Frage. Nach der erfolgreichen Speicherung ist ja okay, aber vorher?
> Und wie plaziere ich jetzt meine fällige PostgreSQL-Werbung?

Ätsch. M.E. kommen die Sequences ohnehin von Oracle und sind auf dem
Weg in den Standard gewandert.
BTW: Benutzt man nicht Sequences auch direkt im INSERT, so etwa:
INSERT INTO bla (PK, fasel) VALUES (SEQ.next_value,123)
?

Re: AutoIncr Procedure

am 12.09.2006 16:02:18 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: AutoIncr Procedure

am 12.09.2006 16:12:08 von Christian Kirsch

Andreas Kretschmer schrieb:

>> BTW: Benutzt man nicht Sequences auch direkt im INSERT, so etwa:
>> INSERT INTO bla (PK, fasel) VALUES (SEQ.next_value,123)
>
> Es reicht, PK wegzulassen. Also INSERT INTO bla (fasel) VALUES (123);
> Bei der Anlage der Table wird nextval(...) als Default eingesetzt,
> guggst Du:
>
> test=> create table foobar (id serial, wert int);
> NOTICE: CREATE TABLE will create implicit sequence "foobar_id_seq" for serial column "foobar.id"
> CREATE TABLE

Merci. Meine Sequence-Kenntnisse kommen noch aus Oracle (8?) und sind
inzwischen schlappe 8 Jahre alt :-(

Re: AutoIncr Procedure

am 12.09.2006 16:23:45 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: AutoIncr Procedure

am 12.09.2006 16:33:33 von Christian Kirsch

Andreas Kretschmer schrieb:
> begin Oliver Neumann schrieb:
>> Kommt daher, dass ich ein Programm für Oracle Database geschrieben hatte,
>> welches nun auf MySQL portiert werden soll. Der hat das mit Sequenzen
>> implementiert. Um nicht zu viel zu ändern wollte ich dasselbe gern in MySQL
>> haben. Wozu ich die brauche ich ja erstmal egal.
>
> Ich habe intensive Zweifel, daß Dir Oracle einen Sequencewert _VOR_ dem
> Insert schon liefert, also so in dem Szenario, wie von Dir geschildert.

Du irrst:
CREATE SEQUENCE bla INCREMENT BY 1 START WITH 100;

Jetzt kannst Du z.B.
SELECT bla.NextVal FROM dual
machen: Liefert den nächsten Wert der Sequence. Mein Buch (Oracle
Database 10g. Die umfassende Referenz) sagt dazu: NextVal liefert
immer einen eindeutigen Wert, den niemand sonst bekommt. Wenn man den
gerade von NextVal gelieferten Wert benutzen will, muss man CurrVal
verwenden. Ein
SELECT bla.CurrVal FROM dual
liefert also dasselbe wie das erste SELECT, ein
SELECT bla.NextVal FROM dual
aber einen anderen (mit etwas Glück nur um 1 höheren ;-) Wert. Ich
könnte mir vorstellen, dass der OP also sowas gemacht hat:
SELECT bla.NextValue FROM dual;
INSERT INTO fasel (PK, ....) VALUES (bla.CurrValue,...)

*Das* könnte man natürlich in MySQL ebenso wie in PG erledigen. Aber
da er nicht sagt, was er will ...

Re: AutoIncr Procedure

am 12.09.2006 16:42:05 von Phillip Parr

> Ich erzeuge mir in solchen Fällen immer eine eigene Tabelle zur
> Verwaltung dieser Zähler.

ja, das hatte ich auch schon überlegt. Werd mal sehen was ich nun mache.


Ahm und wie mir scheint nutzen also die meisten die generierten PKeys des
Statements nach dessen Ausführung, z.B. mit einem INSERT. Was macht ihr
dann, wenn ihr mehrere Tabellen habt und eine Tabelle Referenzen auf eine
andere Tabellen in Form eines PKeys besitzt. Bsp: TabelleA hat Referenz auf
eine Zeile aus TabelleB. Ihr müsstet dann ja sofort nach Hinzufügen eines
Eintrages für TabelleB diesen neuen Eintrag speichern, um dessen PKey zu
erhalten, der dann in einem Eintrag in TabelleA verwendet werden kann. Oder
benutzt ihr dann alle einen Sekundärschlüssel ?


Grüsse,
oliver

Re: AutoIncr Procedure

am 12.09.2006 16:45:14 von Phillip Parr

Hallo,

> Du irrst:
> CREATE SEQUENCE bla INCREMENT BY 1 START WITH 100;
>
> Jetzt kannst Du z.B.
> SELECT bla.NextVal FROM dual
> machen: Liefert den nächsten Wert der Sequence. Mein Buch (Oracle
> Database 10g. Die umfassende Referenz) sagt dazu: NextVal liefert
> immer einen eindeutigen Wert, den niemand sonst bekommt. Wenn man den
> gerade von NextVal gelieferten Wert benutzen will, muss man CurrVal
> verwenden. Ein
> SELECT bla.CurrVal FROM dual
> liefert also dasselbe wie das erste SELECT, ein
> SELECT bla.NextVal FROM dual
> aber einen anderen (mit etwas Glück nur um 1 höheren ;-) Wert. Ich
> könnte mir vorstellen, dass der OP also sowas gemacht hat:
> SELECT bla.NextValue FROM dual;
> INSERT INTO fasel (PK, ....) VALUES (bla.CurrValue,...)
>
> *Das* könnte man natürlich in MySQL ebenso wie in PG erledigen. Aber
> da er nicht sagt, was er will ...

Ja, genau das habe ich in Oracle genutzt. Und was ich will ist eigentlich
genau das in mysql ;)

Re: AutoIncr Procedure

am 12.09.2006 16:50:04 von Christian Kirsch

Oliver Neumann schrieb:
> Hallo,
>
>> Du irrst:
>> CREATE SEQUENCE bla INCREMENT BY 1 START WITH 100;
>>
>> Jetzt kannst Du z.B.
>> SELECT bla.NextVal FROM dual
>> machen: Liefert den nächsten Wert der Sequence. Mein Buch (Oracle
>> Database 10g. Die umfassende Referenz) sagt dazu: NextVal liefert
>> immer einen eindeutigen Wert, den niemand sonst bekommt. Wenn man den
>> gerade von NextVal gelieferten Wert benutzen will, muss man CurrVal
>> verwenden. Ein
>> SELECT bla.CurrVal FROM dual
>> liefert also dasselbe wie das erste SELECT, ein
>> SELECT bla.NextVal FROM dual
>> aber einen anderen (mit etwas Glück nur um 1 höheren ;-) Wert. Ich
>> könnte mir vorstellen, dass der OP also sowas gemacht hat:
>> SELECT bla.NextValue FROM dual;
>> INSERT INTO fasel (PK, ....) VALUES (bla.CurrValue,...)
>>
>> *Das* könnte man natürlich in MySQL ebenso wie in PG erledigen. Aber
>> da er nicht sagt, was er will ...
>
> Ja, genau das habe ich in Oracle genutzt. Und was ich will ist eigentlich
> genau das in mysql ;)
>
>
Das ergab schon in Oracle keinen Sinn (weil überflüssig). Warum also
machst Du es in MySQL nicht so, wie es dort eben üblich ist:
CREATE TABLE bla (pk INTEGER AUTO_INCREMENT PRIMARY KEY,
fasel CHAR(4));
INSERT INTO bla (fasel) VALUES ('huhu');
SELECT LAST_INSERT_ID();
Das INSERT erzeugt den Datensatz, und LAST_INSERT_ID() liefert Dir
seine ID. Wozu brauchst Du die *vor* dem INSERT?

Re: AutoIncr Procedure

am 12.09.2006 16:53:09 von Christian Kirsch

Oliver Neumann schrieb:
>> Ich erzeuge mir in solchen Fällen immer eine eigene Tabelle zur
>> Verwaltung dieser Zähler.
>
> ja, das hatte ich auch schon überlegt. Werd mal sehen was ich nun mache.
>
>
> Ahm und wie mir scheint nutzen also die meisten die generierten PKeys des
> Statements nach dessen Ausführung, z.B. mit einem INSERT. Was macht ihr
> dann, wenn ihr mehrere Tabellen habt und eine Tabelle Referenzen auf eine
> andere Tabellen in Form eines PKeys besitzt. Bsp: TabelleA hat Referenz auf
> eine Zeile aus TabelleB. Ihr müsstet dann ja sofort nach Hinzufügen eines
> Eintrages für TabelleB diesen neuen Eintrag speichern, um dessen PKey zu
> erhalten, der dann in einem Eintrag in TabelleA verwendet werden kann. Oder
> benutzt ihr dann alle einen Sekundärschlüssel ?

Nein. Siehe mein anderes Posting: Du benutzt LAST_INSERT_ID(), z.B. in
der Form
INSERT INTO t1 (bla) VALUES ('fasel');
INSERT INTO t2 (fk, foo) VALUES(LAST_INSERT_ID(),'lala');

Und bevor Du fragst: Ja, LAST_INSERT_ID() ist in diesem Fall genau die
ID, die das erste INSERT-Statement erzeugt hat. Viele APIs für MySQL
haben eine eigene Funktion, die Dir (etwas für die weitere
Verarbeitung im Client) die letzte ID liefert.

Übrigens gibt es zu MySQL eine Dokumentation unter dev.mysql.com/doc.

Re: AutoIncr Procedure

am 12.09.2006 16:59:34 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: AutoIncr Procedure

am 12.09.2006 17:41:26 von Phillip Parr

> Nein. Siehe mein anderes Posting: Du benutzt LAST_INSERT_ID(), z.B. in
> der Form
> INSERT INTO t1 (bla) VALUES ('fasel');
> INSERT INTO t2 (fk, foo) VALUES(LAST_INSERT_ID(),'lala');
>
> Und bevor Du fragst: Ja, LAST_INSERT_ID() ist in diesem Fall genau die
> ID, die das erste INSERT-Statement erzeugt hat. Viele APIs für MySQL
> haben eine eigene Funktion, die Dir (etwas für die weitere
> Verarbeitung im Client) die letzte ID liefert.

Ja und genau das reicht mir nicht. Ich habe eine Art Datenbankbrowser
geschrieben, welcher Einträge hinzufügen kann etc. Wenn ich nun zu TabelleA
einen Eintrag hinzufüge ist der sofort für alle anderen Tabellen zu
referenzieren, ohne dass dieser wirklisch schon in der DB steht. Erst bei
einem Speichern werden alle tabellen auch wirklich gespeichert. Die
Änderungen geschehen also erstmal losgelöst von der DB.

Aber gut...ich hab das jetzt über eine extra Tabelle gelöst, welche alle
Indizes beinhaltet und als eine Art Zählwerk dient.

Grüsse,
oliver

Re: AutoIncr Procedure

am 12.09.2006 17:42:30 von Thomas Rachel

Christian Kirsch wrote:

> INSERT INTO t1 (bla) VALUES ('fasel');
> INSERT INTO t2 (fk, foo) VALUES(LAST_INSERT_ID(),'lala');
>
> Und bevor Du fragst: Ja, LAST_INSERT_ID() ist in diesem Fall genau die
> ID, die das erste INSERT-Statement erzeugt hat. Viele APIs für MySQL
> haben eine eigene Funktion, die Dir (etwas für die weitere
> Verarbeitung im Client) die letzte ID liefert.

Mit dem Untershied, daß die MySQL-Funktion vor der nächsten
Auto-ID-Generierung abgefragt werden muß, die API-Funktion hingegen bereits
vor dem nächsten Query überhaupt.

Das steht zwar in der

> Dokumentation unter dev.mysql.com/doc.

, aber ich glaube, da kann man (fast) nie genug drauf hinwweisen, weil -
böse Falle.


Thomas
--
Wos hom's gsogt? Nix hom's gsogt! Rausgschmissn homs mi!

Re: AutoIncr Procedure

am 12.09.2006 19:26:28 von Axel Schwenke

"Oliver Neumann" wrote:

>> INSERT INTO t1 (bla) VALUES ('fasel');
>> INSERT INTO t2 (fk, foo) VALUES(LAST_INSERT_ID(),'lala');
>>
>> Und bevor Du fragst: Ja, LAST_INSERT_ID() ist in diesem Fall genau die
>> ID, die das erste INSERT-Statement erzeugt hat. Viele APIs für MySQL
>> haben eine eigene Funktion, die Dir (etwas für die weitere
>> Verarbeitung im Client) die letzte ID liefert.
>
> Ja und genau das reicht mir nicht. Ich habe eine Art Datenbankbrowser
> geschrieben, welcher Einträge hinzufügen kann etc. Wenn ich nun zu TabelleA
> einen Eintrag hinzufüge ist der sofort für alle anderen Tabellen zu
> referenzieren, ohne dass dieser wirklisch schon in der DB steht. Erst bei
> einem Speichern werden alle tabellen auch wirklich gespeichert. Die
> Änderungen geschehen also erstmal losgelöst von der DB.

Du hast eine merkwürdige Art, mit Datenbanken umzugehen. Eventuell
kennst du ja auch das Konzept "Transaktion" nicht.

> Aber gut...ich hab das jetzt über eine extra Tabelle gelöst, welche alle
> Indizes beinhaltet und als eine Art Zählwerk dient.

So könnte man Sequenzen in MySQL realisieren. Ich habe dazu mal was
auf MySQL-Forge geschrieben: http://forge.mysql.com/snippets/view.php?id=7
Da kann man natürlich noch eine SP drumwickeln, wenn man das will.


XL

Re: AutoIncr Procedure

am 12.09.2006 19:36:23 von Axel Schwenke

Thomas Rachel wrote:
> Christian Kirsch wrote:
>
>> INSERT INTO t1 (bla) VALUES ('fasel');
>> INSERT INTO t2 (fk, foo) VALUES(LAST_INSERT_ID(),'lala');
>>
>> Und bevor Du fragst: Ja, LAST_INSERT_ID() ist in diesem Fall genau die
>> ID, die das erste INSERT-Statement erzeugt hat. Viele APIs für MySQL
>> haben eine eigene Funktion, die Dir (etwas für die weitere
>> Verarbeitung im Client) die letzte ID liefert.
>
> Mit dem Untershied, daß die MySQL-Funktion vor der nächsten
> Auto-ID-Generierung abgefragt werden muß, die API-Funktion hingegen bereits
> vor dem nächsten Query überhaupt.

Das liegt daran, wie die Information auf den Client gelangt. Mit jeder
Antwort überträgt der MySQL-Server ein paar Bytes Status zum Client:
affected rows, insert id, status code. Die API Funktion wertet nun
lediglich das letzte Response-Paket (wird von libmysqlclient gecached)
nochmal aus. Statements, die kein AUTO_INCREMENT benutzen, geben
insert_id=0 zurück, löschen also effektiv die Variable auf dem Client.

Die Server-Variable, die mit LAST_INSERT_ID() ausgelesen werden kann,
wird hingegen wirklich nur gesetzt, wenn ein AUTO_INCREMENT-Wert
generiert wird (oder wenn man LAST_INSERT_ID() mit einem Argument
aufruft).


XL

Re: AutoIncr Procedure

am 12.09.2006 20:12:54 von Andreas Kretschmer

Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)

Re: AutoIncr Procedure

am 12.09.2006 21:40:52 von Axel Schwenke

Andreas Kretschmer wrote:
> Axel Schwenke wrote:
>
>> Du hast eine merkwürdige Art, mit Datenbanken umzugehen. Eventuell
>> kennst du ja auch das Konzept "Transaktion" nicht.
>
> Axel, zur Erinnerung: er nutzt MySQL.

Andreas, zur Erinnerung: deine Vorurteile sind nicht up-to-date.
So alle 5 Jahre solltest du deine Rants mal wieder mit der
Realität abgleichen.


XL

Re: AutoIncr Procedure

am 12.09.2006 22:12:41 von Claus Reibenstein

Andreas Kretschmer schrieb:

> begin Axel Schwenke wrote:
>
>> Du hast eine merkwürdige Art, mit Datenbanken umzugehen. Eventuell
>> kennst du ja auch das Konzept "Transaktion" nicht.
>
> Axel, zur Erinnerung: er nutzt MySQL.

Du hast eine merkwürdige Art, Deine mangelhaften MySQL-Kenntnisse zu
dokumentieren.

Gruß. Claus

Re: AutoIncr Procedure

am 13.09.2006 07:36:59 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: AutoIncr Procedure

am 13.09.2006 10:34:09 von Claus Reibenstein

Andreas Kretschmer schrieb:

> begin Axel Schwenke schrieb:
>
>> Andreas Kretschmer wrote:
>>
>>> Axel Schwenke wrote:
>>>
>>>> Du hast eine merkwürdige Art, mit Datenbanken umzugehen. Eventuell
>>>> kennst du ja auch das Konzept "Transaktion" nicht.
>>>
>>> Axel, zur Erinnerung: er nutzt MySQL.
>>
>> Andreas, zur Erinnerung: deine Vorurteile sind nicht up-to-date.
>
> Axel, Du irrst.

Du willst also allen Ernstes behaupten, MySQL kenne keine Transaktionen?
Sorry, aber damit hast Du Dich endgültig disqualifiziert.

Leb wohl.
Claus

Re: AutoIncr Procedure

am 13.09.2006 11:03:01 von Andreas Sakowski

Hallo

"Oliver Neumann" schrieb
> Hallo,
>
> kann mir jemand kurz das Statement für eine MySQL 5.0-Procedure mit
> einem
> Zähler sagen ? Also ich bräuchte eine, welche eine Art Zählwerk
> implementiert und mir bei jedem Aufruf (parameterlos) die folgende
> Zahl
> nennt. Die Prozedur soll dazu dienen, bei jeder Tabelle die
> AutoIncr-Funktionalität zu ersetzen. Also für jede Tabelle soll dann
> solche
> eine Prozedur existieren, welche den nächsten freien PKey
> zurückgeben soll.
> Das Statement zum Aufruf dazu wäre auch nicht schlecht ;)
>
> Oder gibt es sowas schon in MySQL ? Ich brauch einen freien PKey
> noch bevor
> der Datensatz gespeichert wird. Den PKey schreibe ich dann jeweils
> über das
> Statement mit.

Nur so eine Idee. Du schreibst eine strored function die in der
gewünschten
Tabelle, die ein PK mit auto_increment hat, einen leeren Datensatz
speichert,
holst Dir mit last_insert_id() die id, löschst den Datensatz dann
wieder und
gibst eben diese id zurück. Damit hast Du dann eine eindeutige ID und
kannst
dann den Datensatz ganz normal mit insert einfügen.

Irgend welche Probleme zu erwarten?

Gruß
Andreas

Re: AutoIncr Procedure

am 13.09.2006 11:31:05 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: AutoIncr Procedure

am 13.09.2006 11:50:16 von Dirk Brosowski

Andreas Kretschmer schrieb:
> begin Claus Reibenstein schrieb:
>>>>>> Du hast eine merkwürdige Art, mit Datenbanken umzugehen. Eventuell
>>>>>> kennst du ja auch das Konzept "Transaktion" nicht.
>>>>> Axel, zur Erinnerung: er nutzt MySQL.
>>>> Andreas, zur Erinnerung: deine Vorurteile sind nicht up-to-date.
>>> Axel, Du irrst.
>> Du willst also allen Ernstes behaupten, MySQL kenne keine Transaktionen?
>> Sorry, aber damit hast Du Dich endgültig disqualifiziert.
>
> Claus, bevor Du lospolterst und Dich zum weiter zum Obst machst,
> informier Dich doch mal bitte, was MySQL kann und was nicht. Ich zeige
> Dir, wenn Du weiter behauptest, MySQL kann 'richtige' Transaktionen, an
> einem Minimalbeispiel, daß dem nicht so ist. Sorry, falls ich Dir hier
> eine Traumwelt zerstöre...
>
> Und ja, aktuellste Version von MySQL. Wir reden nicht über das, was
> MySQL vielleicht mal in 5 Jahren kann, sondern über das jetzt.

Auch wenn ich InnoDB und Transaktionen nicht mag, wäre ein Beispiel
deiner Seits auf jeden Fall mal angebracht.

Grüße

Dirk

Re: AutoIncr Procedure

am 13.09.2006 11:58:00 von Christian Kirsch

Dirk Brosowski schrieb:
> Andreas Kretschmer schrieb:

>> Und ja, aktuellste Version von MySQL. Wir reden nicht über das, was
>> MySQL vielleicht mal in 5 Jahren kann, sondern über das jetzt.
>
> Auch wenn ich InnoDB und Transaktionen nicht mag, wäre ein Beispiel
> deiner Seits auf jeden Fall mal angebracht.

Auch wenn ich nicht Andreas bin - AFAIK hat er solche Beispiele in der
Vergangenheit schon gebracht. Aus dem Kopf fallen mir die
DDL-Statements von MySQL ein:

set autocommit=0;
create table bla(id integer);
rollback;
show tables;

Wird Dir brav "bla" als Tabelle zeigen.

Re: AutoIncr Procedure

am 13.09.2006 12:01:06 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: AutoIncr Procedure

am 13.09.2006 12:13:47 von Christian Kirsch

Christian Kirsch schrieb:
> Dirk Brosowski schrieb:
>> Andreas Kretschmer schrieb:
>
>>> Und ja, aktuellste Version von MySQL. Wir reden nicht über das, was
>>> MySQL vielleicht mal in 5 Jahren kann, sondern über das jetzt.
>> Auch wenn ich InnoDB und Transaktionen nicht mag, wäre ein Beispiel
>> deiner Seits auf jeden Fall mal angebracht.
>
> Auch wenn ich nicht Andreas bin - AFAIK hat er solche Beispiele in der
> Vergangenheit schon gebracht. Aus dem Kopf fallen mir die
> DDL-Statements von MySQL ein:
>
> set autocommit=0;
> create table bla(id integer);
> rollback;
> show tables;
>
> Wird Dir brav "bla" als Tabelle zeigen.

Nachtrag: Das liegt "natürlich" daran, dass MySQL eben selbst nicht
transaktionsfähig ist bzw. die Tabellenverwaltung außerhalb seiner
selbst erledigt (wenn man das so sagen kann). Oracle z.B. (um jetzt
mal nicht Andreas' Liebling zu nennen) benutzt Tabellen zum Speichern
der Tabellendaten, IIRC. Und dieser Mechanismus ist
transaktionsfähig, weil die *ganze* Datenbank das ist.

Würde MySQL (z.B.) InnoDB-Tabellen einsetzen, um Metadaten zu
verwalten, wären auch DDL-Statements transaktionsfähig. Außerdem
könnte das einige andere Nettigkeiten bringen, z.B. eine brauchbare
Speicherung von Konfigurationsparametern. "Brauchbar" im Sinne von:
Ich kann die Dinger ganz normal per SELECT erfragen und mit UPDATE
ändern, wer das darf, regeln die DB-Permissions und nicht irgendwelche
Dateisystemregeln (wie bei my.cnf), und vor allem: Jede Änderung ist
sofort wirksam - man muss nicht eine externe Datei anpassen und dann
den Server neu starten. Oracle kann sowas (natürlich in gewissen
Grenzen - manches kann man nur in externen Dateien regeln, z.B. das
datadir).

Re: AutoIncr Procedure

am 13.09.2006 13:43:16 von Sascha Klopp

Hi,

Christian Kirsch schrieb:
> Oracle z.B. (um jetzt
> mal nicht Andreas' Liebling zu nennen) benutzt Tabellen zum Speichern
> der Tabellendaten, IIRC. Und dieser Mechanismus ist
> transaktionsfähig, weil die *ganze* Datenbank das ist.

Kleine Zwischenbemerkung: In Oracle committet eine DDL-Anweisung (also
CREATE, DROP, ALTER, etc.) automatisch die Transaktion, da ist Postgres
sogar dem teuren Oracle voraus.

skl

Re: AutoIncr Procedure

am 13.09.2006 14:04:18 von Christian Kirsch

Sascha Klopp schrieb:
> Hi,
>
> Christian Kirsch schrieb:
>> Oracle z.B. (um jetzt
>> mal nicht Andreas' Liebling zu nennen) benutzt Tabellen zum Speichern
>> der Tabellendaten, IIRC. Und dieser Mechanismus ist
>> transaktionsfähig, weil die *ganze* Datenbank das ist.
>
> Kleine Zwischenbemerkung: In Oracle committet eine DDL-Anweisung (also
> CREATE, DROP, ALTER, etc.) automatisch die Transaktion, da ist Postgres
> sogar dem teuren Oracle voraus.
>

Wieder was gelernt. Ich wollte eigentlich nachher noch den Server
anwerfen und es ausprobieren - danke, dass ich mir das sparen kann.

Re: AutoIncr Procedure

am 13.09.2006 14:33:27 von Axel Schwenke

Andreas Kretschmer wrote:
> Dirk Brosowski schrieb:
>>
>> Auch wenn ich InnoDB und Transaktionen nicht mag, wäre ein Beispiel
>> deiner Seits auf jeden Fall mal angebracht.

> Das Problem ist, das Transaktionen _NICHT_ bei z.B. ALTER TABLE wirkt,

Ja. Nur warum schreibst du das nicht gleich? Und welche Rolle spielt
das in einem Thread, in dem es gar nicht um DDL Statements geht?


XL

Re: AutoIncr Procedure

am 13.09.2006 15:06:29 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: AutoIncr Procedure

am 13.09.2006 15:22:39 von Claus Reibenstein

Andreas Kretschmer schrieb:

> begin Axel Schwenke schrieb:
>
>> Ja. Nur warum schreibst du das nicht gleich? Und welche Rolle spielt
>> das in einem Thread, in dem es gar nicht um DDL Statements geht?
>
> Weil ich zu diesem Zeitpunkt kein Beispiel liefern konnte und weil der
> Thread sich in diese Richtung hin entwickelt hat. Vielleicht schaust Du
> Dir das noch mal in Ruhe an, okay? Dann fällt vielleicht sogar Dir auf,
> wer diesen Thread in diese Richtung gelenkt hat...

Stimmt. In <2g1lt3-alp.ln1@tux.schollglas.com> wird der Thread in diese
Richtung gelenkt. Vorher war von DDL nirgends die Rede ...

Ist Dir inzwischen auch ein Beispiel _ohne_ DDL eingefallen? Meine
kümmerlichen SQL-Kenntnisse reichen dazu leider nicht aus.

Gruß. Claus

Re: AutoIncr Procedure

am 13.09.2006 16:35:15 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: AutoIncr Procedure

am 13.09.2006 16:44:35 von Axel Schwenke

Andreas Kretschmer wrote:
> Axel Schwenke schrieb:
>> Andreas Kretschmer wrote:
>>
>>> Das Problem ist, das Transaktionen _NICHT_ bei z.B. ALTER TABLE wirkt,
>>
>> Ja. Nur warum schreibst du das nicht gleich? Und welche Rolle spielt
>> das in einem Thread, in dem es gar nicht um DDL Statements geht?
>
> Weil ich zu diesem Zeitpunkt kein Beispiel liefern konnte und weil der
> Thread sich in diese Richtung hin entwickelt hat. Vielleicht schaust Du
> Dir das noch mal in Ruhe an, okay?

Das mache ich doch gern. Oliver beschrieb, wie er sein Problem mit
INSERTs in referentiell abhängige Tabellen außerhalb der Datenbank
löst und die INSERT Statements erst ausführt, wenn der Anwender
den [Speichern] Button betätigt.

Ich empfahl ihm daraufhin Transaktionen und du wiesest mich darauf
hin, daß Oliver MySQL verwendet. Was *genau* du mit deinem Hinweis
sagen wolltest, ist nicht klar [1] - aber aus dem Kontext habe ich
vermutet, daß du etwas wie "Transaktionen helfen Oliver hier nicht,
weil MySQL das nicht kann" sagen wolltest.

Und das ist falsch. Auch mit MySQL kann Oliver eine Transaktion
starten, seine INSERTs machen und beim Klick auf [Speichern] alles
COMMITten. Um so mehr, als er wegen der referentiellen Constraints
ja ohnehin InnoDB-Tabellen verwendet.


[1] natürlich weiß ich, was du wolltest. Du wolltest mal wieder
ein bisschen trollen und allen vorschwärmen, wieviel besser
PostgreSQL doch ist. Entschuldige, daß ich nicht gleich
drauf angesprungen bin.

XL

Re: AutoIncr Procedure

am 13.09.2006 17:16:24 von Claus Reibenstein

Andreas Kretschmer schrieb:

> ---cut (Zitat aus IRC)
> LOCK TABLE in MySQL ebenfalls eine tx implizit committed (zumindest bis 4.1)
> ---cut

So steht es zumindest in der Referenz zu MySQL 4.0. Wie das bei 4.1 oder
neuer aussieht, weiß ich nicht.

Die Frage ist jetzt, was der SQL-Standard hier fordert. Kann das mal
jemand checken?

Gruß. Claus

Re: AutoIncr Procedure

am 13.09.2006 18:14:42 von Andreas Kretschmer

Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)

Re: AutoIncr Procedure

am 13.09.2006 18:53:09 von Claus Reibenstein

Andreas Kretschmer schrieb:

> begin Axel Schwenke wrote:
>
>> sagen wolltest, ist nicht klar [1] - aber aus dem Kontext habe ich
>> vermutet, daß du etwas wie "Transaktionen helfen Oliver hier nicht,
>> weil MySQL das nicht kann" sagen wolltest.
>
> Falsch.

Warum verrätst Du uns dann nicht endlich, was Du _wirklich_ gemeint
hast? Muss man Dir die Würmer immer einzeln aus der Nase ziehen?

Tipp für die Zukunft: Eindeutig formulieren. Das vermeidet
Missverständnisse (ich habe es genauso verstanden wie Axel, und ich
vermute mal, dass das vielen hier so geht) und den damit verbundenen
unnötigen Traffic.

Gruß. Claus

Re: AutoIncr Procedure

am 13.09.2006 19:33:09 von Andreas Kretschmer

Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)

Re: AutoIncr Procedure

am 13.09.2006 20:48:43 von Andreas Kretschmer

Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)

Re: AutoIncr Procedure

am 14.09.2006 01:17:51 von Dirk Brosowski

Andreas Kretschmer schrieb:
> begin Dirk Brosowski schrieb:
>> Andreas Kretschmer schrieb:
>>> begin Claus Reibenstein schrieb:
>>>> Du willst also allen Ernstes behaupten, MySQL kenne keine Transaktionen?
>>>> Sorry, aber damit hast Du Dich endgültig disqualifiziert.
>>> Claus, bevor Du lospolterst und Dich zum weiter zum Obst machst,
>>> informier Dich doch mal bitte, was MySQL kann und was nicht. Ich zeige
>>> Dir, wenn Du weiter behauptest, MySQL kann 'richtige' Transaktionen, an
>>> einem Minimalbeispiel, daß dem nicht so ist. Sorry, falls ich Dir hier
>>> eine Traumwelt zerstöre...
>>>
>>> Und ja, aktuellste Version von MySQL. Wir reden nicht über das, was
>>> MySQL vielleicht mal in 5 Jahren kann, sondern über das jetzt.
>> Auch wenn ich InnoDB und Transaktionen nicht mag, wäre ein Beispiel
>> deiner Seits auf jeden Fall mal angebracht.
>
> Mit 2 Terminals, hab zwar nicht ich gemacht, wird aber ganz sicher reproduzierbar sein:
>
> ....

DDL cutted ...

Zeig mir bitte den Programmierer welcher sowas ernsthaft programmiert.
Ich kann mir keinen Fall vorstellen, bei dem sowas irgendwie Sinn macht.

Grüße

Dirk

Re: AutoIncr Procedure

am 14.09.2006 08:27:10 von Claus Reibenstein

Dirk Brosowski schrieb:

> Andreas Kretschmer schrieb:
>
>> Mit 2 Terminals, hab zwar nicht ich gemacht, wird aber ganz sicher reproduzierbar sein:
>
> DDL cutted ...
>
> Zeig mir bitte den Programmierer welcher sowas ernsthaft programmiert.

Andreas programmiert so was ganz bestimmt.

> Ich kann mir keinen Fall vorstellen, bei dem sowas irgendwie Sinn macht.

Darum geht's doch gar nicht. Es geht doch nur darum, zu zeigen, wie
beschissen MySQL und wie genial dagegen PostgreSQL ist. Und wenn es
keine praxisnahen Beispiele gibt, dann müssen halt irgendwelche
akademischen Konstrukte herhalten ...

"Leider" kenne ich PostgreSQL zu wenig (um nicht zu sagen: gar nicht).
Sonst hätte ich bestimmt schon ein akademisches Gegenbeispiel gefunden.

Gruß. Claus

Re: AutoIncr Procedure

am 14.09.2006 11:10:10 von Phillip Parr

Hallo,

> Nur so eine Idee. Du schreibst eine strored function die in der
> gewünschten
> Tabelle, die ein PK mit auto_increment hat, einen leeren Datensatz
> speichert,
> holst Dir mit last_insert_id() die id, löschst den Datensatz dann
> wieder und
> gibst eben diese id zurück. Damit hast Du dann eine eindeutige ID und
> kannst
> dann den Datensatz ganz normal mit insert einfügen.
>
> Irgend welche Probleme zu erwarten?

Nein , wäre eine Alternative. Hab das jetzt aber mit einer extra Tabelle zur
Haltung aller autoincr-Werte einer jeden Tabelle erstellt. Klappt wunderbar.
Reicht mir, danke.


Grüsse,
oliver

Re: AutoIncr Procedure

am 14.09.2006 11:15:58 von Phillip Parr

Hallo,

> > Ja und genau das reicht mir nicht. Ich habe eine Art Datenbankbrowser
> > geschrieben, welcher Einträge hinzufügen kann etc. Wenn ich nun zu
TabelleA
> > einen Eintrag hinzufüge ist der sofort für alle anderen Tabellen zu
> > referenzieren, ohne dass dieser wirklisch schon in der DB steht. Erst
bei
> > einem Speichern werden alle tabellen auch wirklich gespeichert. Die
> > Änderungen geschehen also erstmal losgelöst von der DB.
>
> Du hast eine merkwürdige Art, mit Datenbanken umzugehen. Eventuell
> kennst du ja auch das Konzept "Transaktion" nicht.

Na wie...das ist eine einfache Trennung der Datenschichten. Ich habe einen
Fatclient der nicht ständig Statements umherschicken soll, also halte ich
alle Daten lokal vor. Da helfen mir auch keine Transaktionen bei dem
genannten Problem. Oder wie würdest du das machen ?


Viele Grüsse,
oliver

Re: AutoIncr Procedure

am 14.09.2006 12:02:49 von Axel Schwenke

"Oliver Neumann" wrote:
> Hallo,
>
>> > Ja und genau das reicht mir nicht. Ich habe eine Art Datenbankbrowser
>> > geschrieben, welcher Einträge hinzufügen kann etc. Wenn ich nun zu
> TabelleA
>> > einen Eintrag hinzufüge ist der sofort für alle anderen Tabellen zu
>> > referenzieren, ohne dass dieser wirklisch schon in der DB steht. Erst
> bei
>> > einem Speichern werden alle tabellen auch wirklich gespeichert. Die
>> > Änderungen geschehen also erstmal losgelöst von der DB.
>>
>> Du hast eine merkwürdige Art, mit Datenbanken umzugehen. Eventuell
>> kennst du ja auch das Konzept "Transaktion" nicht.
>
> Na wie...das ist eine einfache Trennung der Datenschichten. Ich habe einen
> Fatclient der nicht ständig Statements umherschicken soll, also halte ich
> alle Daten lokal vor.

Ja, meinetwegen. Ist wahrscheinlich sogar ganz praktisch, erst alle
Daten in der Applikation zu sammeln und dann auf einmal an die
Datenbank zu schicken.

> Da helfen mir auch keine Transaktionen bei dem
> genannten Problem. Oder wie würdest du das machen ?

Mir ist nicht klar, wo da ein Problem sein soll. Die Fremdschlüssel-
Beziehung zwischen den Tabellen und überhaupt die Abbildung von Objekt-
Attributen auf mehrere Tabellen ist doch ein Tribut an das RDBMS.
In der Applikation sollten die äquivalenten Beziehungen statt über
IDs über direkte Objekt-Referenzen gehen.

Wozu brauchst du also die zukünftige ID eines Datensatzes? Gib dem
neuen Datensatz in der Applikation halt eine Fantasie-ID. Idealer-
weise eine, die sonst nicht vorkommt; z.B. 0. Und wenn du nachher
die INSERTs machst, verwendest du einfach LAST_INSERT_ID() in den
SQL-Statements.

Alternativ: starte eine Transaktion, INSERTe den Master-Datensatz.
Frage die Daten für weitere Tabellen ab und INSERTe sie auch jeweils.
Zum Schluß dann COMMIT (oder ROLLBACK).


XL

Re: AutoIncr Procedure

am 14.09.2006 14:28:28 von Phillip Parr

Hallo Axel,

> > Da helfen mir auch keine Transaktionen bei dem
> > genannten Problem. Oder wie würdest du das machen ?
>
> Mir ist nicht klar, wo da ein Problem sein soll. Die Fremdschlüssel-
> Beziehung zwischen den Tabellen und überhaupt die Abbildung von Objekt-
> Attributen auf mehrere Tabellen ist doch ein Tribut an das RDBMS.
> In der Applikation sollten die äquivalenten Beziehungen statt über
> IDs über direkte Objekt-Referenzen gehen.


ich arbeite mit keinen Objekten die dann auf Tabellen gemappt werden (wie
bei den Persistenzframeworks), sondern direkt mit den Tabellendaten. Das war
für meine Zwecke passender. Das ändern von Daten mache ich also über das
direkte ändern von Zellenwerten, die dann irgendwann mal gespeichert werden.
Mit Hibernate & Co. hat man dann mein Problem natürlich nicht.

Aber egal...wie gesagt läuft das jetzt alles wie es soll und ich bin
glücklich ;)


Grüsse,
oliver