あなたの解決策は実行可能な方法です。単純化/パフォーマンス/読みやすさ/セキュリティのためにplpgsql関数を大幅に書き直しました。
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;
これはPostgreSQL9.1以降で機能します。
pg 8.4の場合 または後で交換
SELECT string_agg(col || ' numeric(9,2) DEFAULT 0', ', ')
と:
SELECT array_to_string(array_agg(col || ' numeric(9,2) DEFAULT 0'), ', ')
さらに古いバージョンの場合 それよりも、次のような集計関数を作成します。
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
);
そして、次のように書きます:
SELECT concat_comma(col || ' numeric(9,2) DEFAULT 0')
また:
DROP TABLE IF EXISTS tmptable;
「IFEXISTS」という句は、バージョン 8.2で導入されました。 。
さらに古いバージョンを使用する必要がある場合 それよりもあなたができるべきです:
IF EXISTS (
SELECT *
FROM pg_catalog.pg_class
WHERE oid = 'tmptable'::regclass
AND relkind = 'r')
THEN
DROP TABLE tmptable;
END IF;
*/
アップグレード!
PostgreSQLプロジェクトのバージョン管理ポリシー をご覧ください。 。バージョン8.0.1は、特にバグのあるバージョンです。 強く アップグレードすることをお勧めします。新しいメジャーバージョンにアップグレードできない場合は、セキュリティ上の理由から、少なくとも最新のポイントリリース(この場合は8.0.26)にアップグレードしてください。これは、他に何も変更せずに、その場で実行できます。