PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Utwórz dynamiczną tabelę z funkcji w PostgreSQL

Twoje rozwiązanie to opłacalny sposób. W dużej mierze przepisałem twoją funkcję plpgsql dla uproszczenia / wydajności / czytelności / bezpieczeństwa.

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;

Działa to dla PostgreSQL 9.1 lub nowszych.

Dla strony 8.4 lub później wymień

SELECT string_agg(col || ' numeric(9,2) DEFAULT 0', ', ')

z:

SELECT array_to_string(array_agg(col || ' numeric(9,2) DEFAULT 0'), ', ')

W przypadku wersji jeszcze starszych niż tworzą funkcję agregującą w ten sposób:

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
);

A potem napisz:

SELECT concat_comma(col || ' numeric(9,2) DEFAULT 0')

Również:

DROP TABLE IF EXISTS tmptable;

Klauzula „IF EXISTS” została wprowadzona w wersji 8.2 .
Jeśli powinieneś używać wersji jeszcze starszej niż powinieneś:

IF EXISTS (
    SELECT *
    FROM   pg_catalog.pg_class
    WHERE  oid = 'tmptable'::regclass
    AND    relkind = 'r')
THEN
    DROP TABLE tmptable;
END IF;
*/

Uaktualnij!

Zapoznaj się z polityką wersjonowania projektu PostgreSQL . Wersja 8.0.1 jest szczególnie błędną wersją. Chciałbym zdecydowanie radzę ci uaktualnić. Jeśli nie możesz uaktualnić do nowszej wersji głównej, przynajmniej zaktualizuj do najnowszej wersji punktowej ze względów bezpieczeństwa, w twoim przypadku 8.0.26. Można to zrobić na miejscu, bez zmiany czegokolwiek innego.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Obsługa transakcji Postgresql za pomocą java

  2. nie można połączyć się z instancją postgres AWS RDS z pgadmin4

  3. Jak zainstalować PostgreSQL 12 na Ubuntu 20.04 DigitalOcean?

  4. Jak unpivotować tabelę w PostgreSQL

  5. Zduplikowane wiersze SQL z wieloma lewymi sprzężeniami