Musisz włączyć tablicę na zestaw wierszy. Na przykład za pomocą generate_series
:
SELECT ARRAY(SELECT ROUND(ARRAY[1.53224,0.23411234])[i], 2) FROM generate_series(1,2) AS s(i));
Wiem, że to dość brzydki. Powinna istnieć funkcja pomocnicza ułatwiająca takie mapowanie.
Być może coś takiego (tak to straszne, powolne i kruche kod dynamiczny):
CREATE OR REPLACE FUNCTION map_with_arg(TEXT, ANYARRAY, TEXT)
RETURNS ANYARRAY
IMMUTABLE STRICT
LANGUAGE 'plpgsql' AS
$$
DECLARE
i INTEGER;
t TEXT;
cmd TEXT;
BEGIN
FOR i IN array_lower($2, 1) .. array_upper($2, 1) LOOP
cmd := 'SELECT ('||quote_ident($1)||'('||quote_nullable($2[i])||', '||quote_nullable($3)||'))::TEXT';
EXECUTE cmd INTO t;
$2[i] := t;
END LOOP;
RETURN $2;
END;
$$;
select map_with_arg('repeat', array['can','to']::TEXT[], '2');
map_with_arg
---------------
{cancan,toto}
Aktualizacja Wydaje mi się, że możemy korzystać z jednego dynamicznego oświadczenie dla całej pętli. Może to złagodzić niektóre obawy dotyczące wydajności.
CREATE OR REPLACE FUNCTION map_with_arg(TEXT, ANYARRAY, TEXT)
RETURNS ANYARRAY
IMMUTABLE STRICT
LANGUAGE 'plpgsql' AS
$$
DECLARE
cmd TEXT;
rv TEXT;
BEGIN
cmd := 'SELECT ARRAY(SELECT (' || quote_ident($1)||'($1[i], '||quote_nullable($3)||'))::TEXT FROM generate_subscripts($1, 1) AS gs(i))';
EXECUTE cmd USING $2 INTO rv;
RETURN rv;
END;
$$;
niesamowite sugestie od wszystkich. Myślę, że pójdę z przechowywanym procem, ponieważ muszę przez cały czas stosować tę funkcję 'map'. Byłoby jeszcze lepiej, gdybym mógł przekazać funkcję do przechowywanego procesu, tworząc w ten sposób przechowywany fabrycznie proces, który przekształciłby go w prawdziwą funkcję "map". Ale to zadziała na razie. Jeszcze raz dziękuję, wszystkim. – punkish
Re: przekazywanie funkcji: Może Cię zainteresować http://stackoverflow.com/questions/8346065/function-as-parametr- na -inne-funkcje-w-postgres. (To daleki od ideału, ale możesz z niego skorzystać.) – ruakh