Für die Verarbeitung einer einzelnen Zeile oder die sequentielle Verarbeitung von Zeilen können Sie die Klausel RETURNING
von INSERT
kombiniert mit der Klausel plpgsql INTO
verwenden. Beispiel:
Aber Sie versuchen offensichtlich auf einmal eine ganze Reihe zu verarbeiten.
calculate distance from address points to all streets within a distance of 50 meters ...
Verwenden Sie einen Set-basierten Ansatz. Viel schneller und sauberer. Wenn Sie Zeilen vom INSERT
zusätzlich zurückgeben möchten, verwenden Sie eine Set-Return-Funktion. Beispiel:
Sie würden nicht brauchen überhaupt eine Funktion. Nur diese Abfrage:
INSERT INTO street(ad_geom, st_geom, distance, traffic_ct) -- any columns in street
SELECT ad.geom, st.geom, ST_Distance(ad.geom, st.geom), ad.traffic_ct
FROM ad
LEFT JOIN st ON ST_DWithin(ad.geom, st.geom, 50.0)
RETURNING * -- all columns in street
Ich denke, Sie nicht wirklich brauchen nichts mehr zurück, da diese Abfrage alle tut man wollte, aber ich hielt RETURNING
als Proof of Concept. Sie können es einfach überspringen.
Verwenden Sie [INNER] JOIN
anstelle von , wenn Sie keine Adressen ohne übereinstimmende Straße hinzufügen möchten.
The manual about RETURNING
in INSERT
:
The optional RETURNING
clause causes INSERT
to compute and return value(s) based on each row actually inserted [...] any expression using the table's columns is allowed. The syntax of the RETURNING
list is identical to that of the output list of SELECT
. Only rows that were successfully inserted or updated will be returned.
Wenn Sie Notwendigkeit diese in eine plpgsql Funktion zu wickeln (könnte auch eine einfache SQL-Funktion sein) - und zurück nach wie vor alle Zeilen:
CREATE OR REPLACE FUNCTION insert_neighbours()
RETURNS SETOF street AS
$func$
BEGIN
RETURN QUERY
INSERT INTO street(ad_geom, st_geom, distance, traffic_ct) -- any columns in street
SELECT ad.geom, st.geom, ST_Distance(ad.geom, st.geom), ad.traffic_ct
FROM ad
LEFT JOIN st ON ST_DWithin(ad.geom, st.geom, 50.0)
RETURNING *; -- all columns in street
END
$func$ LANGUAGE plpgsql;
Call:
SELECT * FROM insert_neighbours(); -- use SELECT * FROM ... !
Zur Vereinfachung gehe ich zurück n die ganze Zeile, aber Sie können auch ausgewählte Spalten zurückgeben. See above example.
Creating the function gives no error
Das ist, weil PL/pgSQL derzeit nur oberflächliche Syntaxprüfungen auf CREATE FUNCTION
läuft. Sie müssen die Funktion tatsächlich ausführen, um sie zu testen - und sicherstellen, dass alle Zweige des Codes in plpgsql-Funktionen getestet werden.
Pass ganze Datensätze - ad/st, oder Geometrie ... In der Funktion - wenn ad/st ist Geometrie - dann neu schreiben inneren wählen ... –
Wie können Sie diese Funktion ausführen, ohne Fehler zu bekommen? Gibt es in Ihrer Datenbank Tables "ad" und "st" (da Sie aus diesen auswählen)? Bitte beschreiben Sie genauer, was Sie zu erreichen versuchen. –