Su solución es una forma viable. Reescribí en gran medida su función plpgsql para simplificación/rendimiento/legibilidad/seguridad.
CREATE OR REPLACE FUNCTION f_taxamount()
RETURNS void AS
$BODY$
DECLARE
rec record;
BEGIN
DROP TABLE IF EXISTS tmptable;
EXECUTE 'CREATE TABLE tmptable (invoiceid integer PRIMARY KEY, '
|| (
SELECT string_agg(col || ' numeric(9,2) DEFAULT 0', ', ')
FROM (
SELECT quote_ident(lower(replace(taxname,' ','_'))) AS col
FROM tbltaxamount
GROUP BY 1
ORDER BY 1
) x
)
|| ')';
EXECUTE '
INSERT INTO tmptable (invoiceid)
SELECT DISTINCT invoiceid FROM tbltaxamount';
FOR rec IN
SELECT taxname, taxamt, invoiceid FROM tbltaxamount ORDER BY invoiceid
LOOP
EXECUTE '
UPDATE tmptable
SET ' || quote_ident(lower(replace(rec.taxname,' ','_')))
|| ' = '|| rec.taxamt || '
WHERE invoiceid = ' || rec.invoiceid;
END LOOP;
END;
$BODY$ LANGUAGE plpgsql;
Esto funciona para PostgreSQL 9.1 o posterior.
Para página 8.4 o más tarde reemplazar
SELECT string_agg(col || ' numeric(9,2) DEFAULT 0', ', ')
con:
SELECT array_to_string(array_agg(col || ' numeric(9,2) DEFAULT 0'), ', ')
Para versiones incluso más antiguas que eso crea una función agregada como esta:
CREATE OR REPLACE FUNCTION f_concat_comma(text, text)
RETURNS text AS
$BODY$
BEGIN
RETURN ($1 || ', '::text) || $2;
END;
$BODY$
LANGUAGE plpgsql IMMUTABLE;
CREATE AGGREGATE concat_comma(text) (
SFUNC=f_concat_comma,
STYPE=text
);
Y luego escribe:
SELECT concat_comma(col || ' numeric(9,2) DEFAULT 0')
También:
DROP TABLE IF EXISTS tmptable;
La cláusula "SI EXISTE" se introdujo con la versión 8.2 .
Si debe usar una versión aún más antigua de lo que deberías puedes:
IF EXISTS (
SELECT *
FROM pg_catalog.pg_class
WHERE oid = 'tmptable'::regclass
AND relkind = 'r')
THEN
DROP TABLE tmptable;
END IF;
*/
¡Actualízate!
Eche un vistazo a la política de versiones del proyecto PostgreSQL . La versión 8.0.1 es una versión especialmente con errores. Lo haría fuertemente le aconsejo que actualice. Si no puede actualizar a una versión principal más nueva, al menos actualice a la última versión puntual por razones de seguridad, 8.0.26 en su caso. Esto se puede hacer en el lugar, sin cambiar nada más.