EXECUTE ... USING-Anweisung in PL / pgSQL funktioniert nicht mit Satzart?
-
21-09-2019 - |
Frage
Ich versuche, eine Funktion in PL / PgSQL zu schreiben, die mit einem Tisch zur Arbeit hat es als Parameter erhält.
Ich verwende EXECUTE..INTO..USING Aussagen innerhalb der Definition der Funktion zu bauen dynamischer Abfragen (es ist der einzige Weg, ich weiß, dies zu tun), aber ... traf ich ein Problem mit RECORD-Datentypen.
betrachten wir die Folge (stark vereinfacht) Beispiel.
-- A table with some values.
DROP TABLE IF EXISTS table1;
CREATE TABLE table1 (
code INT,
descr TEXT
);
INSERT INTO table1 VALUES ('1','a');
INSERT INTO table1 VALUES ('2','b');
-- The function code.
DROP FUNCTION IF EXISTS foo (TEXT);
CREATE FUNCTION foo (tbl_name TEXT) RETURNS VOID AS $$
DECLARE
r RECORD;
d TEXT;
BEGIN
FOR r IN
EXECUTE 'SELECT * FROM ' || tbl_name
LOOP
--SELECT r.descr INTO d; --IT WORK
EXECUTE 'SELECT ($1)' || '.descr' INTO d USING r; --IT DOES NOT WORK
RAISE NOTICE '%', d;
END LOOP;
END;
$$ LANGUAGE plpgsql STRICT;
-- Call foo function on table1
SELECT foo('table1');
Es gibt die folgende Fehlermeldung:
ERROR: konnte nicht Spalte "descr" in Rekorddatentyp identifizieren
obwohl die Syntax habe ich mir gültig zu sein scheint. Ich kann nicht die statischen wählen verwenden (im Beispiel kommentiert), weil ich mag dinamically die Spalten Namen beziehen.
So..someone wissen, was mit dem obigen Code falsch?
Lösung
Es ist wahr. Sie können nicht Satzart außerhalb PL / pgSQL Raum verwenden.
RECORD Wert ist nur gültig in plpgsql.
Sie tun können,
EXECUTE 'SELECT $1.descr' INTO d USING r::text::xx;
Andere Tipps
$1
innerhalb des ||
sein sollte, wie || $1 ||
und gibt Räume richtig dann wird es funktionieren.
BEGIN
EXECUTE ' delete from ' || quote_ident($1) || ' where condition ';
END;