Ich muss schon sagen, eure hilfen hier sind echt spitze
Leider find ich zu meinem aktuellen Problem nichts (liegt vielleicht auch daran dass ich überhaupt keine Peilung habe wie ich nach diesem Problem suchen soll )
Ich hab folgendes Problem. Eine sehr umfangreiche View erzeugt mir rund 180’000 Datenzeilen. Mit einer Anwendung die ich in Delphi schreibe benutze ich diese Daten unter anderem dazu Files von einem FTP-Server runterzuladen (Pfad und Dateiname kommen aus der PG-View).
Nun habe ich festgestellt dass der Export aller Daten aus der View über 100 Stunden in Anspruch nehmen wird und da dieser ganze Export über’s Wochenende laufen muss hab ich mir ne andere Lösung gesucht. Somit habe ich mir folgendes gedacht…
Ich nehme die Daten dieser View und schreibe sie aufgesplittet in verschiedene Tabellen (Hab ich mich dazu entschieden da’s mit Index über der Tabelle deutlich schneller geht die Daten abzurufen). Somit habe ich nacher z.B. tmp_data1, tmp_data2, tmp_data3, tmp_data4 usw…
Somit habe ich die Möglichkeit dass die Delphi-Anwendung auf mehreren Rechnern gleichzeitig Daten exportieren kann.
Nun meine eigentliche Frage…
Ich habe eine Funktion die gewisse Prüfungen macht und dann die Daten an die Anwendung weitergibt. Diese Funktion heisst get_data_to_transfer(INTEGER)
Der Integer-Parameter den ich übergebe ist der Index der tmp_data-Tabellen die ich ansprechen möchte. z.B. 1 -> tmp_data1 usw.
Wie kann ich mir nun innerhalb dieser Funktion einen Tabellennamen zusammenbasteln dass ich die SELECT-Abfrage nur einmal schreiben muss…
Also z.B. tblName := ‘tmp_data’ || $1
Aber wenn ich nun SELECT * FROM tblName ausführen möchte bekomme ich immer Fehlermeldungen
Ich hab’s schon auf verschiedenste Arten versucht und schaffe es leider nicht… Weiss mir jemand einen Rat???
Vielen Dank für deine prompte Antwort… Ich glaube aber fast mit EXECUTE kann ich’s gar nicht machen…
Im Grunde mache ich folgendes… ich iteriere mit einer FOR-Schlaufe durch alle Datenzeilen einer SELECT-Abfrage (um diese SELECT-Abfrage geht’s auch bei meinem Problem) und prüfe dann jede Datenzeile ob sie in einer anderen Tabelle schon vorhanden ist.
Hier der Code:
FOR tmp_record IN SELECT *
FROM pmuser.tmpdata_from_pm1
LIMIT 50
LOOP
-- Prüfen ob Datensatz bereits transferiert wurde
SELECT INTO tmp_query *
FROM transfered_data
WHERE doc_num = trim(tmp_record.DOC_NUM) AND
rev_num = tmp_record.REV_NUM::INTEGER AND
ver_num = tmp_record.DOC_VR_NUM AND
file_format = tmp_record.fileextension;
IF NOT FOUND THEN
-- Datenzeile zurückgeben, da noch nicht transferiert
RETURN NEXT tmp_record;
END IF;
END LOOP;
RETURN;
Seh ich das richtig dass ich diese FOR-Schlaufe kaum mit einem EXECUTE betreiben kann, oder??
Der Integer-Parameter den ich übergebe ist der Index der tmp_data-Tabellen die ich ansprechen möchte. z.B. 1 → tmp_data1 usw.
Wie kann ich mir nun innerhalb dieser Funktion einen Tabellennamen zusammenbasteln dass ich die SELECT-Abfrage nur einmal schreiben muss…
Also z.B. tblName := ‘tmp_data’ || $1
Aber wenn ich nun SELECT * FROM tblName ausführen möchte bekomme ich immer Fehlermeldungen
Und die Lösung dafür ist EXECUTE.
Ist die 1 in Deinem “FROM pmuser.tmpdata_from_pm1” die Variable?
Ja genau… Das Beispiel mit der 1 ist grade etwas unglücklich gwählt
Die 1 ist der Integerwert den ich der Funktion übergebe…
Die fertige Funktion lautet nun so:
sql_statement := 'SELECT * FROM tmpdata_from_pm' || $1::text;
RAISE NOTICE 'Daten aus Tabelle: %', sql_statement;
FOR tmp_record IN EXECUTE sql_statement
LOOP
-- Prüfen ob Datensatz bereits transferiert wurde
SELECT INTO tmp_query *
FROM transfered_data
WHERE doc_num = trim(tmp_record.DOC_NUM) AND
rev_num = tmp_record.REV_NUM::INTEGER AND
ver_num = tmp_record.DOC_VR_NUM AND
file_format = tmp_record.fileextension;
IF NOT FOUND THEN
-- Datenzeile zurückgeben, da noch nicht transferiert
RETURN NEXT tmp_record;
END IF;
END LOOP;
RETURN;