
Temporäre Tabelle in Stored Procedure (FAQ 4.19 ähnlicher Fehler!)
Hallo
Ich brauche dringend Eure Hilfe! Ich habe eine Funktion, die von einem
Trigger aufgerufen wird, immer dann wenn eine Zeile in die Tabelle
'hikeroute' eingefügt wurde.
Die Funktion tut nichts anderes, als den prozentualen Anteil von
asphaltierten Wege und Naturpfade zu berechnen und in einer separaten
Tabelle abspeichern.
Dazu muss ich eine rechenintensive, räumliche Abfrage, welche als
Resultat alle Segmente (mit der Information asphaltiert oder nicht)
einer Route. Da ich jedoch diese Operation wegen der Performance nur
einmal ausführen möchte, speichere ich das Resultat in einer
temporären Tabelle. Füge ich nun der Tabelle hikeroute mehrere neue
Einträge hinzu, so wird der erste Eintrag hinzugefügt und die
nachfolgenden lösen folgenden Fehler aus:
<code>
psql:hikeroutes.sql:37: ERROR: relation with OID 41384 does not exist
KONTEXT: SQL statement "SELECT count(*) FROM htable"
PL/pgSQL function "getsurfacing" line 24 at select into variables
</code>
Ich habe bereits intensiv im Internet recherchiert, doch finde ich
keine Lösung die funktioniert..! Anscheinend handelt es sich um das
Problem, wie in der offiziellen FAQ 4.19 beschrieben. Kann mir jemand
helfen? Hat jemand eine Idee, wie ich meine Funktion zum Laufen
bringen kann? Ich bin auf Eure Hilfe angewiesen. Ich weiss nicht mehr
wie weiter...
Vielen lieben Dank bereits im Voraus!
Gruss aus Zürich
Thomas
<code>
CREATE OR REPLACE FUNCTION getSurfacing() RETURNS TRIGGER AS '
DECLARE
rows FLOAT;
rec RECORD;
nature FLOAT;
asphalt FLOAT;
undefined FLOAT;
BEGIN
IF (select count(*) from pg_tables where tablename=3D''htable'') THEN
EXECUTE ''DROP TABLE '' || ''htable'';
END IF;
CREATE LOCAL TEMPORARY TABLE htable AS (
SELECT s.name FROM hikeroute h, surfepm s
WHERE s.the_geom && setSRID(box2d(h.the_geom)::box2d, 21781)
AND h.id =3D NEW.id
AND within(s.the_geom, h.the_geom)
);
/* funktioniert auch nicht
EXECUTE ''
CREATE LOCAL TEMPORARY TABLE htable AS (
SELECT s.name FROM hikeroute h, surfepm s
WHERE s.the_geom && setSRID(box2d(h.the_geom)::box2d, 21781)
AND h.id =3D '' || NEW.id || ''
AND within(s.the_geom, h.the_geom)
)
'';
*/
SELECT INTO rows count(*) FROM htable;
SELECT INTO asphalt count(*) FROM htable WHERE name ~* ''Hartbelag'';
asphalt :=3D (100/rows)*(asphalt);
SELECT INTO nature count(*) FROM htable WHERE name ~* ''Naturbelag'';
nature :=3D (100/rows)*(nature);
undefined :=3D 100 - nature - asphalt;
INSERT INTO roadsurfacing VALUES(NEW.gid, nature, asphalt, undefined);
RETURN NEW;
EXCEPTION
WHEN division_by_zero THEN
RAISE NOTICE ''caught division_by_zero !!'';
RETURN OLD;
END;
' LANGUAGE plpgsql;
</code>
--
Thomas Zuberbuehler
http://www.zubi.li
---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match
Re: Te
Thomas Zuberbuehler <tzuberbuehler [at] datacomm.ch> schrieb:
> Einträge hinzu, so wird der erste Eintrag hinzugefügt und die
> nachfolgenden lösen folgenden Fehler aus:
>
> <code>
> psql:hikeroutes.sql:37: ERROR: relation with OID 41384 does not exist
> KONTEXT: SQL statement "SELECT count(*) FROM htable"
> PL/pgSQL function "getsurfacing" line 24 at select into variables
> </code>
>
> Ich habe bereits intensiv im Internet recherchiert, doch finde ich
> keine Lösung die funktioniert..! Anscheinend handelt es sich um das
> Problem, wie in der offiziellen FAQ 4.19 beschrieben. Kann mir jemand
> helfen? Hat jemand eine Idee, wie ich meine Funktion zum Laufen
> bringen kann? Ich bin auf Eure Hilfe angewiesen. Ich weiss nicht mehr
> wie weiter...
>
> Vielen lieben Dank bereits im Voraus!
> Gruss aus Zürich
> Thomas
>
> <code>
> CREATE OR REPLACE FUNCTION getSurfacing() RETURNS TRIGGER AS '
> ...
>
> SELECT INTO rows count(*) FROM htable;
Offenbar hier, oder? Probier mal, auch hier mit EXECUTE zu arbeiten. Ich
denke mal, der Planer hat hier noch die OID eines früheren Aufrufes
gecached. Und auch nachfolgende Aufrufe von htable.
Gruß aus Sachsen, viel Erfolg, Andreas
--
Really, I'm not out to destroy Microsoft. That will just be a completely
unintentional side effect. (Linus Torvalds)
"If I was god, I would recompile penguin with --enable-fly." (unknow)
Kaufbach, Saxony, Germany, Europe. N 51.05082=B0, E 13.56889=
=B0
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster
Re: Te
Hoi Andreas
Laut Internetquellen funktioniert leider SELECT INTO nicht mit EXECUTE
und auch ein eigener Test brachte leider keinen Erfolg. Ich sollte das
Zählergebnis irgendwie speichern und daher "benötige" ich SELECT INTO.
Oder gibt es eine Alternative? Hast Du eine Idee, wie ich das SELECT
INTO anders realisieren kann?
<code>
psql:hikeroutes.sql:37: ERROR: syntax error at or near "INTO" bei Zeichen 8
ANFRAGE: SELECT INTO rows count(*) FROM htable
KONTEXT: PL/pgSQL function "getsurfacing" line 24 at execute statement
psql:hikeroutes.sql:37: ZEILE 1: SELECT INTO rows count(*) FROM htable
psql:hikeroutes.sql:37: ^
</code>
Vielen Dank.
Thomas
Am 18.11.06 schrieb Andreas Kretschmer <akretschmer [at] spamfence.net>:
> Thomas Zuberbuehler <tzuberbuehler [at] datacomm.ch> schrieb:
> > Einträge hinzu, so wird der erste Eintrag hinzugefügt und die
> > nachfolgenden lösen folgenden Fehler aus:
> >
> > <code>
> > psql:hikeroutes.sql:37: ERROR: relation with OID 41384 does not exist
> > KONTEXT: SQL statement "SELECT count(*) FROM htable"
> > PL/pgSQL function "getsurfacing" line 24 at select into variables
> > </code>
> >
> > Ich habe bereits intensiv im Internet recherchiert, doch finde ich
> > keine Lösung die funktioniert..! Anscheinend handelt es sich um das
> > Problem, wie in der offiziellen FAQ 4.19 beschrieben. Kann mir jemand
> > helfen? Hat jemand eine Idee, wie ich meine Funktion zum Laufen
> > bringen kann? Ich bin auf Eure Hilfe angewiesen. Ich weiss nicht mehr
> > wie weiter...
> >
> > Vielen lieben Dank bereits im Voraus!
> > Gruss aus Zürich
> > Thomas
> >
> > <code>
> > CREATE OR REPLACE FUNCTION getSurfacing() RETURNS TRIGGER AS '
> > ...
> >
> > SELECT INTO rows count(*) FROM htable;
>
> Offenbar hier, oder? Probier mal, auch hier mit EXECUTE zu arbeiten. Ich
> denke mal, der Planer hat hier noch die OID eines früheren Aufrufes
> gecached. Und auch nachfolgende Aufrufe von htable.
>
>
> Gruß aus Sachsen, viel Erfolg, Andreas
> --
> Really, I'm not out to destroy Microsoft. That will just be a completely
> unintentional side effect. (Linus Torvalds)
> "If I was god, I would recompile penguin with --enable-fly." (unknow)
> Kaufbach, Saxony, Germany, Europe. N 51.05082=B0, E 13.56889=
=B0
>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: Don't 'kill -9' the postmaster
>
--
Thomas Zuberbuehler
http://www.zubi.li
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend
Re: Te
Thomas Zuberbuehler wrote:
> Hoi Andreas
>
> Laut Internetquellen funktioniert leider SELECT INTO nicht mit EXECUTE
> und auch ein eigener Test brachte leider keinen Erfolg. Ich sollte das
> Zählergebnis irgendwie speichern und daher "benötige" ich SELECT IN=
TO.
> Oder gibt es eine Alternative? Hast Du eine Idee, wie ich das SELECT
> INTO anders realisieren kann?
seit 8.1 gibts EXECUTE INTO
Stefan
---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo [at] postgresql.org so that your
message can get through to the mailing list cleanly
Re: Te
Hoi Stefan
Wo finde ich ein Beispiel zu EXECUTE INTO?
In der Referenz ist leider der Befehl nicht aufgelistet:
http://www.postgresql.org/docs/8.1/interactive/sql-commands. html
Gruss, Thomas
Am 18.11.06 schrieb Stefan Kaltenbrunner <stefan [at] kaltenbrunner.cc>:
> Thomas Zuberbuehler wrote:
> > Hoi Andreas
> >
> > Laut Internetquellen funktioniert leider SELECT INTO nicht mit EXECUTE
> > und auch ein eigener Test brachte leider keinen Erfolg. Ich sollte das
> > Zählergebnis irgendwie speichern und daher "benötige" ich SELECT IN=
TO.
> > Oder gibt es eine Alternative? Hast Du eine Idee, wie ich das SELECT
> > INTO anders realisieren kann?
>
> seit 8.1 gibts EXECUTE INTO
>
>
> Stefan
>
--
Thomas Zuberbuehler
http://www.zubi.li
---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match
Re: Te
Thomas Zuberbuehler <tzuberbuehler [at] datacomm.ch> schrieb:
> Hoi Andreas
>
> Laut Internetquellen funktioniert leider SELECT INTO nicht mit EXECUTE
> und auch ein eigener Test brachte leider keinen Erfolg. Ich sollte das
> Zählergebnis irgendwie speichern und daher "benötige" ich SELECT IN=
TO.
> Oder gibt es eine Alternative? Hast Du eine Idee, wie ich das SELECT
> INTO anders realisieren kann?
Neben dem, was Stefan 'mastermind' Kaltenbrunner schon sagte, geht auch
sowas wie:
sql :=3D 'select foo from bar'
for record_variable in execute sql loop
raise notice '%', record_variable.foo;
end loop;
Mal so als Code-Brocken.
PS.: bitte kein TOFU.
Andreas
--
Really, I'm not out to destroy Microsoft. That will just be a completely
unintentional side effect. (Linus Torvalds)
"If I was god, I would recompile penguin with --enable-fly." (unknow)
Kaufbach, Saxony, Germany, Europe. N 51.05082=B0, E 13.56889=
=B0
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend
Re: Te
Thomas Zuberbuehler <tzuberbuehler [at] datacomm.ch> schrieb:
> Hoi Stefan
>
> Wo finde ich ein Beispiel zu EXECUTE INTO?
>
> In der Referenz ist leider der Befehl nicht aufgelistet:
> http://www.postgresql.org/docs/8.1/interactive/sql-commands. html
http://www.postgresql.org/docs/8.1/interactive/plpgsql-state ments.html#PL=
PGSQL-STATEMENTS-EXECUTING-DYN
Andreas
--
Really, I'm not out to destroy Microsoft. That will just be a completely
unintentional side effect. (Linus Torvalds)
"If I was god, I would recompile penguin with --enable-fly." (unknow)
Kaufbach, Saxony, Germany, Europe. N 51.05082=B0, E 13.56889=
=B0
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend
Re: Te
Thomas Zuberbuehler wrote:
> Hoi Stefan
>
> Wo finde ich ein Beispiel zu EXECUTE INTO?
>
> In der Referenz ist leider der Befehl nicht aufgelistet:
> http://www.postgresql.org/docs/8.1/interactive/sql-commands. html
klar das ist ja (genau wie SELECT INTO im plpgsql context) kein
SQL-Befehl per se sondern Teil von pl/pgsql :-)
Das es im SQL Kontext auch SELECT INTO gibt mag verwirrend sein aber das
eine hat mit dem anderen nicht viel zu tun.
Stefan
---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo [at] postgresql.org so that your
message can get through to the mailing list cleanly
Re: Te
Vielen lieben Dank Euch beiden! Ohne Euch hätte ich wahrscheinlich
noch Stunden an diesem Problem gearbeitet!
Ich poste hier mal noch den funktionierenden Code, damit nachfolgende
Leute mit ähnlichen Probleme ein Codebeispiel haben bzw. finden.
Viele Grüsse
Thomas
<code>
CREATE OR REPLACE FUNCTION getSurfacing() RETURNS TRIGGER AS '
DECLARE
rows FLOAT;
rec RECORD;
nature FLOAT;
asphalt FLOAT;
undefined FLOAT;
BEGIN
IF (select count(*) from pg_tables where tablename=3D''htable'') THEN
EXECUTE ''DROP TABLE '' || ''htable'';
END IF;
CREATE LOCAL TEMPORARY TABLE htable AS (
SELECT s.name FROM hikeroute h, surfepm s
WHERE s.the_geom && setSRID(box2d(h.the_geom)::box2d, 21781)
AND h.id =3D NEW.id
AND within(s.the_geom, h.the_geom)
);
EXECUTE ''SELECT count(*) FROM htable'' INTO rows;
EXECUTE ''SELECT count(*) FROM htable WHERE name ~* '' || ''
''''Hartbelag'''' '' || '''' INTO asphalt;
asphalt :=3D (100/rows)*(asphalt);
EXECUTE ''SELECT count(*) FROM htable WHERE name ~* '' || ''
''''Naturbelag'''' '' || '''' INTO nature;
nature :=3D (100/rows)*(nature);
undefined :=3D 100 - nature - asphalt;
INSERT INTO roadsurfacing VALUES(NEW.gid, nature, asphalt, undefined);
RETURN NEW;
EXCEPTION
WHEN division_by_zero THEN
RAISE NOTICE ''caught division_by_zero !!'';
RETURN OLD;
END;
' LANGUAGE plpgsql;
</code>
--
Thomas Zuberbuehler
http://www.zubi.li
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?
http://archives.postgresql.org
Re: Te
Thomas Zuberbuehler <tzuberbuehler [at] datacomm.ch> schrieb:
> Vielen lieben Dank Euch beiden! Ohne Euch hätte ich wahrscheinlich
> noch Stunden an diesem Problem gearbeitet!
Case closed, schön ;-)
Andreas
--
Really, I'm not out to destroy Microsoft. That will just be a completely
unintentional side effect. (Linus Torvalds)
"If I was god, I would recompile penguin with --enable-fly." (unknow)
Kaufbach, Saxony, Germany, Europe. N 51.05082=B0, E 13.56889=
=B0
---------------------------(end of broadcast)---------------------------
TIP 7: You can help support the PostgreSQL project by donating at
http://www.postgresql.org/about/donate
Re: Te
Thomas Zuberbuehler wrote:
> Vielen lieben Dank Euch beiden! Ohne Euch hätte ich wahrscheinlich
> noch Stunden an diesem Problem gearbeitet!
>
> Ich poste hier mal noch den funktionierenden Code, damit nachfolgende
> Leute mit ähnlichen Probleme ein Codebeispiel haben bzw. finden.
nachdem du da schon 8.x hast könntest du auch gleich auf dollar-quoting
umsteigen - macht das Leben meist viel einfacher :-)
Stefan
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings