PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Tạo bảng động từ hàm trong PostgreSQL

Giải pháp của bạn là một cách khả thi. Phần lớn tôi đã viết lại hàm plpgsql của bạn để đơn giản hóa / hiệu suất / khả năng đọc / bảo mật.

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;

Điều này hoạt động cho PostgreSQL 9.1 trở lên.

Đối với pg 8.4 hoặc sau đó thay thế

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

với:

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

Đối với các phiên bản thậm chí cũ hơn hơn là tạo một hàm tổng hợp như thế này:

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

Và sau đó viết:

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

Ngoài ra:

DROP TABLE IF EXISTS tmptable;

Mệnh đề "NẾU TỒN TẠI" đã được giới thiệu với phiên bản 8.2 .
Nếu bạn nên sử dụng phiên bản thậm chí cũ hơn hơn những gì bạn nên làm:

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

Nâng cấp!

Hãy xem chính sách lập phiên bản của dự án PostgreSQL . Phiên bản 8.0.1 là một phiên bản đặc biệt có nhiều lỗi. Tôi sẽ mạnh mẽ khuyên bạn nên nâng cấp. Nếu bạn không thể nâng cấp lên phiên bản chính mới hơn, ít nhất hãy nâng cấp lên bản phát hành điểm mới nhất vì lý do bảo mật, 8.0.26 trong trường hợp của bạn. Điều này có thể được thực hiện tại chỗ mà không cần thay đổi bất kỳ điều gì khác.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chênh lệch múi giờ địa phương trong PostgreSQL

  2. Elegant PostgreSQL Group của Ruby on Rails / ActiveRecord

  3. Cách sao chép dữ liệu PostgreSQL sang các trang web từ xa

  4. Không có lời nhắc mật khẩu cho postgresql superuser

  5. Cài đặt LC_CTYPE đã chọn yêu cầu mã hóa LATIN1