Abfrageergebnsi als eigenständige Abfrage ausführen

Hallo,

Das Forum hier scheint recht kompetente Mitglieder zu haben, mal schauen, ob auch mir geholfen werden kann. :wink:

Nach dem Übertragen der Datenbank aus Access nach Postgresql kommen bei mir immer die Sequenzzähler durcheinander.

Ich habe mir nun eine Abfrage zusammengebastelt, um den notwendigen Befehl zu generieren, um jede einzelne Sequenz auf den aktuellen Stand zu updaten:

SELECT 'select setval(''' || name || ''', max(' || 
substring( name FROM 1 FOR position('_seq' in name)-1 ) || ')) ' 
AS "Korrektur_der_Sequenzzaehler" 
FROM (SELECT c.relname AS "name",
CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'i'
THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' END as "Type"
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_user u ON u.usesysid = c.relowner
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('S','')
AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
AND pg_catalog.pg_table_is_visible(c.oid)) AS seq

Das Ergebnis sind also neue SELECT Anweisungen, wie kann ich diese Strings gleich als SQL-Befehl ausführen?

Ich würde an deiner Stelle etwas anders vorgehen:

Schreibe dir eine Funktion (plpgsql bietet sich hier förmlich an), in dieser Funktion baust du als erstes eine Schleife, die dir alle Sequencen ausliest. Innerhalb dieser Schleife updatest du dann jede einzelne Sequenz. In plpgsql kannst du dir Queries zusammensetzen und mit EXECUTE auch ausführen.

Stimmt, PLSQL wäre auch eine Möglichkeit. Gibt es keinen ähnlichen Befehl wie “execute” auf der SQL-Ebene?

Nein, SQL selber bietet dafür keine Möglichkeiten, dafür ist die Sprache zu “schlicht”.

Naja, ich habe darauf spekuliert, dass es eine eingebaute Funktion gäbe. Ich glaube bei Oracle hat es so was gegeben, bin mir aber nicht mehr sicher.

Meine PL/SQL-Kenntnisse waren schon etwas angerostet, aber nach einigen try & error gibt es nun eine funktionieredne Lösung, vielleicht kann das jemand noch gebrauchen:


CREATE OR REPLACE FUNCTION aelitha_update_seq&#40]

Ok, sooooo kann man das natürlich auch halten :wink:

Ich hätte den äußeren Query nicht so kompliziert gestaltet sondern einfach nur die Daten geholt. Im Loop dann in einem String den Query zusammengesetzt und ausgeführt. Das sollte den Query übersichtlicher halten …

Gerade fällt mir auf: das max() könntest du dann auch in den Loop packen und direkt während des setval() Befehls auslesen lassen.

Und ev. wäre das information_schema auch daran interessiert, dir die notwendigen Informationen zu liefern, in einer Form, die portabel bleibt. Deine jetzigen Queries müssen mit der nächsten/letzten Version von PG schon nicht mehr funktionieren.

Es wäre natürlich optisch eleganter und die Funktion wäre besser zu lesen, mir war allerdings wichtig, dass Query mit copy & paste auch direkt ausgeführt werden kann.

Das habe ich nicht gewusst, um welche Zeile(n) müsste dann meine Abfrage erweitert werden?

Nicht erweitern, umschreiben. Du solltest die gleichen Informationen auch aus dem Information Schema bekommen, auf eine Art und Weise, die auf jeder Datenbank, die dieses Schema unterstützt (und die Funktionen hat), laufen sollte.
Also eigentlich auf jeder zukünftigen PG Version …

Anyway, wenn es läuft, läuft es.