È necessario attivare l'array in un set di fila. Ad esempio, utilizzando generate_series
:
SELECT ARRAY(SELECT ROUND(ARRAY[1.53224,0.23411234])[i], 2) FROM generate_series(1,2) AS s(i));
So che è piuttosto brutto. Ci dovrebbe essere una funzione di supporto per rendere più semplici tali mappature.
Forse qualcosa di simile (sì, è orribile, lento, e fragile codice dinamico):
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}
Aggiornamento mi viene in mente che potremmo usare un unico prospetto dinamica per l'intero ciclo. Questo potrebbe mitigare alcuni dei problemi di prestazioni.
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;
$$;
fantastici suggerimenti da parte di tutti. Penso che andrò con il proc memorizzato in quanto ho bisogno di applicare questo tipo di una funzione 'mappa' tutto il tempo. Sarebbe ancora più grande se potessi passare una funzione al processo memorizzato, rendendolo quindi un processo memorizzato in fabbrica che lo convertirà in una vera funzione 'map'. Ma questo funzionerà per ora. Grazie ancora, a tutti. – punkish
Ri: passare in una funzione: potresti essere interessato a http://stackoverflow.com/questions/8346065/funzionamento-come-parametro-per-un'altra-funzione-in-postgres. (È lontano dall'ideale, ma potresti farne un uso.) – ruakh