Variabler Name der Ausgabedatei von \copy

Moin,

ich werte Inhalte aus 12 verschiedenen PG-Datenbanken aus, bin jedoch nicht für Pflege/Erweiterung dieser DBen zuständig. Um die aktuellen Änderungen in den Datenbanken (neue Tabellen/Strukturänderungen) festzustellen, habe ich folgendes kleines Skript geschrieben, welches die Struktur ausgibt. Die Änderungen werden dann in einer ACCESS-Anwendung festgestellt, welche gleichzeitig zu Doku dient.
Das Skript habe ich als PG-Newbie geschrieben und ist wahrscheinlich nicht optimal - egal.
Meine Frage: Kann ich den Namen der Ausgabedatei im /copy-Befehl variabel gestalten?
Ich möchte, dass der Name der aktuellen Datenbank darin auftaucht (./PruefAendPG_.txt).
Skript:
create temporary table PAPG as
select table_schema
,table_name
,column_name
,case
when position(‘char’ in data_type) > 0 and position(‘varying’ in data_type) = 0 then data_type || ‘(’ || character_maximum_length || ‘)’
when data_type = ‘numeric’ and numeric_scale = 0 then data_type || ‘(’ || numeric_precision || ‘)’
when data_type = ‘numeric’ and numeric_scale > 0 then data_type || ‘(’ || numeric_precision || ‘,’ || numeric_scale || ‘)’
else data_type
end Datentyp
,ordinal_position
from information_schema.columns
where table_schema = current_database()
order by table_name, ordinal_position;

\copy PAPG TO ‘./PruefAendPG.txt’ csv delimiter ‘;’;

drop table PAPG;

Diese Bedingung:

wird in den meisten Fällen ein leeres Resultat liefern, weil ein Schema etwas anderes ist als eine Datenbank. Du willst vermutlich where table_schema = current_schema()

Alternativ eventuell where table_catalog = current_database() - aber das ändert nichts, weil INFORMATION_SCHEMA sowieso nur Informationen über die aktuelle Datenbank enthält. Wenn Du wirklich Datenbank (und nicht Schema) gemeint hast, dann brauchst also gar keine WHERE Bedingung

Mit psql könntest Du den \copy Befehl mit einem SELECT Befehl generieren, so dass der aktuelle Datenbankname (oder meintest Du: Schemaname?) drin steht. Das Ergebnis kann man dann mit \gexec ausführen:

Etwas in der Art:

select format('\copy papg to %L csv delimiter '';''', current_database()||'.csv')
\gexec

Beachte, dass das SELECT Statement kein ; am Ende hat (das \gexec ersetzt quasi das ;)

1 „Gefällt mir“

Danke für die schnelle Antwort!
current_database() ist schon richtig, die DB liegen tatsächlich auf verschiedenen Servern. Die Einschränkung schließt alle PG-eigenen Schemas/Tabellen aus. Wie gesagt, wahrscheinlich gibt es cleverere Befehle. Wichtig ist mir die Ausgabe.
Deine Ansatz ist sehr gut, funktioniert leider nicht, \gexec bringt folgenden Fehler:
ERROR: syntax error at or near “\”
ZEILE 1: \copy PAPG to ‘nama.csv’ csv delimiter ‘;’

Wenn ich die Doku richtig verstehe, kann \gexec nur interne Befehle verarbeiten.
Ich habe deshalb versucht, von \copy zu copy zu wechseln. dafür fehlen mir aber die Rechte.

Dann ist die Sache für mich wahrscheinlich nicht lösbar - ist auch nicht kriegsentscheidend.

Wie gesagt die Tabellen in INFORMATION_SCHEMA enthalten immer nur Information zur aktuellen Datenbank. Die Einschränkung auf current_database() macht also wenig Sinn für mich. Es sei denn ihr habt in jeder Datenbank ein Schema mit dem Namen der Datenbank (was aber irgendwie merkwürdig klingt).

Ah, Mist. Daran hatte ich nicht gedacht. Aber mit dem Umweg über eine Datei sollte es gehen:

\pset footer off
\pset tuples_only on
\o export.sql
select format('\copy papg to %L csv delimiter '';''', current_database()||'.csv');
\i export.sql

… Es sei denn ihr habt in jeder Datenbank ein Schema mit dem Namen der Datenbank …
Ist tatsächlich so - warum auch immer.

Deine Befehlsfolge klappt - Danke, hat mir sehr geholfen!!