Autor Beitrag
Nersgatt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1581
Erhaltene Danke: 279


Delphi 10 Seattle Prof.
BeitragVerfasst: Di 13.03.12 08:55 
Moin,

meine Frage ist ganz einfach: geht es auch einfacher? :D

Ich möchte einen Generator per SQL auf einen bestimmten Wert setzen, der aber von den Daten in einer Tabelle abhängt.
Sowas hatte ich mir vorgestellt:
ausblenden SQL-Anweisung
1:
ALTER SEQUENCE GENERATORNAME RESTART WITH (COALESCE(SELECT MAX(ID) FROM TABELLE), 0) + 1);					

Auch mit der alten Syntax nicht:
ausblenden SQL-Anweisung
1:
SET GENERATOR GENERATORNAME TO (COALESCE(SELECT MAX(ID) FROM TABELLE), 0) + 1);					

Ich hab es jetzt mit Trick 17 von hinten durchs Knie gelöst:
ausblenden SQL-Anweisung
1:
SELECT GEN_ID(GENERATORNAME, coalesce((select max(id) + 1 from TABELLE), 1) - (select gen_id(GENERATORNAME, 0from rdb$database)) FROM RDB$DATABASE					

Das funktioniert in der Tat - aber gibt es da nicht einen einfacheren Weg?

_________________
Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Di 13.03.12 18:33 
Ich finde meinen alten Oracle-Code nicht wieder (:roll:), aber ich kann mich erinnern, dass das so ähnlich war: INCREMENT BY ändern und dann einen Wert holen:
ausblenden SQL-Anweisung
1:
2:
3:
ALTER SEQUENCE seq_test INCREMENT BY :newval - seq_test.currval;
SELECT seq_test.nextval FROM dual; 
ALTER SEQUENCE seq_test INCREMENT BY 1;

Der nächste Aufruf an nextval gibt dann :newval+1.

Falls ich dein letztes Statement richtig lese, tut das exakt das. Scheint also wohl so gedacht zu sein...

Alternativ kannst du die Sequence auch droppen und mit START WITH auf einem neuen Startwert erzeugen (hoffe mal dass Firebird das kann ;) ) Ist halt doof, weil DDL ja nicht transaktionsfähig ist - da kann zwischendurch trotzdem Mist produziert werden.

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
Nersgatt Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1581
Erhaltene Danke: 279


Delphi 10 Seattle Prof.
BeitragVerfasst: Di 13.03.12 21:11 
Es ging mir drum, das in einem simplen Statement zu machen.
Was gehen würde, wäre sowas:
ausblenden SQL-Anweisung
1:
ALTER SEQUENCE GENERATORNAME RESTART WITH 4711;					

Dafür brauch ich die Sequenz nicht erst zu droppen (was ja in einer Multiuserumgebung sowieso Probleme machen würde).
Mein Problem war eigentlich nur, dass die 4711 nicht durch einen Wert ersetzen kann, den ich im gleichen Atemzug durch ein Select ermittel.
Was im Übrigen auch nicht geht, ist bei ALTER SEQUENCE die Verwendung von Parametern. Sowas geht also auch nicht:
ausblenden SQL-Anweisung
1:
alter sequence GENERATORNAME restart with :newval;					

Und da such ich eine hübsche, elegante Lösung dafür. Meine Lösung (siehe oben) funktioniert, ist aber nicht wirklich hübsch.

_________________
Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Di 13.03.12 21:26 
Ah okay. Firebird ist also sehr anders ;)

Was würde mit einer Procedure passieren? Die hätte zwar Variablen, aber ich lese die Doku so, dass da gleich ganz nur DML erlaubt ist?

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."