Ingres: Userrechte kopieren mit MAX?

Fehler

Benutzer
Beiträge
17
Hallo,

ich komme bei einem INSERT nicht weiter und vereinfache diesen zur Übersichtlichkeit mal...

Tabelle userrechte
Spalten iduser, berechtigung, idzuordnung (idzuordnung hat immer eine fortlaufende Nummer und kommt nie doppelt vor... 1,2,3,4,5,... dazu kommt, das in der selben Tabelle im Bereich über 10000 andere Zuordnungen stattfinden...)

Habe versch. Möglichkeiten ausprobiert, eine davon wäre:
insert into userrechte (iduser, berechtigung, idzuordnung) select 'NEUEUSERID', berechtigung, (select max(idzuordnung) from userrechte where idzuordnung<=10000) from userrechte where resid=REFERENZUSERID;

Klar funktioniert das Statement nicht, da der select max den wert behält, beispielsweise 555 und den bei 3 Einträgen hinterlegen möchte, aber wie kann der Wert hochgezählt werden? Es gibt ja hier keine for-Schleifen...

Hat jemand einen Lösungsvorschlag?
(Es handelt sich hierbei noch um Ingres-SQL)

Viele Grüße
Christian
 
Zuletzt bearbeitet:
Werbung:
Ähm, was machst Du da? Bzw, was soll das werden?

Warum machst Du ein Select auf dieselbe Tabelle, auf die Du einfügen willst?

Nach Deinem Beispiel würde dies funktionieren:

Code:
postgres=# create table userrechte(iduser text, berechtigung text, idzuordnung int);
CREATE TABLE
postgres=# insert into userrechte values ('bla','xxx',1);
INSERT 0 1
postgres=# insert into userrechte values ('foo','zzz',2);
INSERT 0 1
postgres=# insert into userrechte values ('doof','xyz',1000);
INSERT 0 1
postgres=# insert into userrechte (iduser, berechtigung, idzuordnung) select 'NEUEUSERID', berechtigung, max(idzuordnung)+1 from userrechte where idzuordnung < 1000 group by berechtigung;
INSERT 0 2
postgres=# select * from userrechte ;
   iduser   | berechtigung | idzuordnung 
------------+--------------+-------------
 bla        | xxx          |           1
 foo        | zzz          |           2
 doof       | xyz          |        1000
 NEUEUSERID | xxx          |           2
 NEUEUSERID | zzz          |           3
(5 rows)

Aber ist es das, was Du suchst? Wohl nicht... Suchst Du vielleicht eher:

Code:
postgres=# insert into userrechte (iduser, berechtigung, idzuordnung) select 'NEUEUSERID', 'berechtigung', (select max(idzuordnung)+1 from userrechte where idzuordnung < 1000);
INSERT 0 1
postgres=# select * from userrechte ;
   iduser   | berechtigung | idzuordnung 
------------+--------------+-------------
 bla        | xxx          |           1
 foo        | zzz          |           2
 doof       | xyz          |        1000
 NEUEUSERID | xxx          |           2
 NEUEUSERID | zzz          |           3
 NEUEUSERID | berechtigung |           4
(6 rows)

Aber eigentlich suchst Du eher eine Sequence, und Du willst auch nicht schon Einträge über 1000 haben, weil das knallt ja irgendwann...
 
hallo akretschmer,

Danke erst mal für deine Antwort.
was ich da mache? 😁
Mit bestem wissen versuche ich mir das Script zu basteln welches mir viel Arbeit abnehmen soll, das Problem ist tatsächlich, dass ich ja nicht weiss wieviele Einträge in der Referenz sind. Es können 0, aber auch 10 sein.

Ich kann deinem 2. Script nicht ganz folgen... Was bedeutet INSERT 0 1?

Viele Grüße
 
Ja, so viele @Fehler hier gell?

Wenn Du eine Spalte hast, die eigentlich noch hochzählen soll und eindeutig sein soll und damit als PRIMARY KEY dienen soll, dann ist die passende Lösung eine Sequence. PostgreSQL bietet dafür passend (BIG)SERIAL an. Noch besser, in aktuellen Versionen: 'generated always as identity'.
 
Ja immer diese Fehler, gibt solche und seuche 🤣

Verstehe nur garnicht was ich jetzt machen soll, also an der bestehenden DB bzw. Datenbankstruktur kann ich leider 0 ändern!
Kann diese nur mit Statements füttern...
 
Also du musst unterscheiden.

Richtiger Weg: Die Datenbank übernimmt das Erstellen des Primary Keys. Dazu muss die Tabelle entsprechend definiert sein (Stichwörter Sequenz, Serial, Identity, etc.)

zu Fuss und eventuell fehlerhaft: Geht natürlich auch. Du musst dann das, was du selektierst, auch hoch zählen, z.B.:
Code:
INSERT INTO tabelle(id,spalte)
SELECT (SELECT max(id) FROM tabelle) + ROW_NUMBER() OVER (ORDER BY spalte) As id,spalte FROM tabelle
 
Hallo Ukulele,

Ich hatte auch mal versucht die ID einfach weg zu lassen (weil ich dachte der zählt die von alleine hoch), dann wurde aber automatisch die ID 0 genommen. Wenn ich den Vorgang wiederhole kommt eine Meldung, dass die ID 0 schon vorhanden ist. 🤪

Was du mir da vorschlägst ist mir noch neu.
Ich werde ich mich mal mit auseinander setzen und wieder melden, vielen Dank für deinen Tipp!

Viele Grüße
Christian
 
dann wurde aber automatisch die ID 0 genommen. Wenn ich den Vorgang wiederhole kommt eine Meldung, dass die ID 0 schon vorhanden ist.
Dass bedeutet, dass die Spalte als (das veraltete) serial definiert wurde, Du aber INSERTs ausgeführt hast, bei denen der Mechanismus der Datenbank umgangen wurde. Jetzt sind die Werte in der ID Spalte und der dahinter liegenden SEQUENCE nicht mehr synchron. Deswegen der Fehler, wenn der Mechanismus wieder greift.

Du musst jetzt die SEQUENCE die von der Spalte verwendet wird, auf den höchsten Wert der ID Spalte setzen. Danach funktioniert die automatische Generierung wieder:

Code:
select nextval(pg_get_serial_sequence('tabelle', 'id'), max(id)) 
from tabelle
Und danach einfach nie wieder explizit einen Wert für die ID Spalte angeben.

Noch besser wäre es die Spalte als id integer generated always as identity anzulegen. Dann bekommst Du sofort einen Fehler wenn Du versuchst die Generierung der Werte durch die Datenbank zu umgehen.
 
@castorp Ein guter Ansatz, danke für den Tipp 👍. Ich habe das mal ausprobiert (in einem Select), es kommt aber eine Fehlermeldung...
Angeblich ist der Syntax falsch und "(" wird hinter dem nextval bemängelt... Trotzdem scheint Ingres den Befehl zu kennen, weil wenn ich aus nextval <-> rnextval (oder was anderes) mache, bekomme ich den Fehler, dass der Befehl nicht bekannt ist.
Es kommt aber noch eine Schwierigkeit hinzu...
Es gab da diesen Datenbankhirni der versch. Verknüpfungen in versch. ID-Bereichen in diese Tabelle gepackt hat (hier kann ich wie gesagt leider nichts ändern!!!)....
Das bedeutet also, wenn ich die höchste Zahl zurück bekomme, kann ich diese nicht verwenden, da diese nicht für Personen sondern für Räume gedacht ist... Ich weiß die genauen Bereiche jetzt nicht aus dem Kopf, sagen wir mal ID 1-9999 ist für User und 10.000-19.999 für Räume.
Wenn ich den Befehl also richtig verstehe, würde ich beispielsweise die ID 12.345 bekommen weil die letzte Zuordnung Raum 12.344 ist.
Die letzte User-Zuordnung die ich benötige ist aber die 1234.
 
Ach Mist, das muss natürlich select setval(....) from ... sein.

Und "Ingres" kann das vermutlich sowieso nicht - nur Postgres
 
Werbung:
Zurück
Oben