호출 예시

SELECT * FROM GENERATE_SELECT('테이블명');
SELECT * FROM GENERATE_SELECT('스키마명.테이블명');

정의

-- ---------------------------------------------------------------------------------------------
-- SELECT 문 생성
-- ---------------------------------------------------------------------------------------------
-- 예시
--   - SELECT * FROM GENERATE_SELECT('테이블명'); -- public 스키마: 스키마 이름 생략
--   - SELECT * FROM GENERATE_SELECT('스키마명.테이블명');
-- ---------------------------------------------------------------------------------------------
DROP FUNCTION IF EXISTS GENERATE_SELECT;
CREATE FUNCTION GENERATE_SELECT(table_name text, add_comment_margin int = 0)
RETURNS text AS $$
DECLARE
    column_name text;
    column_comment text;
    column_len int;
    select_query text := 'SELECT' || chr(10);
    first_column boolean := true;
    max_column_len int;
    table_comment text;
BEGIN
    -- 스키마명이 명시되지 않은 경우 public
    IF strpos(table_name, '.') = 0 THEN
        table_name := 'public.' || table_name;
    END IF;

    -- 해당 테이블의 컬럼 최대 길이 조회
    SELECT MAX(LENGTH(attname)) + add_comment_margin
      FROM pg_catalog.pg_attribute
     WHERE attrelid = table_name::regclass
       AND attnum > 0
       AND NOT attisdropped
    INTO max_column_len;
    
    -- 테이블 코멘트 조회
    SELECT d.description AS table_comment
      FROM pg_class c
      JOIN pg_namespace n ON n.oid = c.relnamespace
      LEFT JOIN pg_description d ON d.objoid = c.oid AND d.objsubid = 0
     WHERE (n.nspname || '.' || c.relname) = table_name
    INTO table_comment;

    -- Loop: 컬럼명, 컬럼 코멘트 조회
    FOR column_name, column_comment IN
        SELECT a.attname AS column_name,
               pg_catalog.col_description(a.attrelid, a.attnum) AS column_comment
          FROM pg_catalog.pg_attribute a
         WHERE a.attrelid = table_name::regclass
           AND a.attnum > 0
           AND NOT a.attisdropped
         ORDER BY a.attnum
    LOOP
        IF NOT first_column THEN
            select_query := select_query || chr(10) || ' ' || ',';
        ELSE
            first_column := false;
            select_query := select_query || '  ';
        END IF;
        
        column_len := LENGTH(column_name);
        select_query := select_query || column_name;
        
        IF column_comment IS NOT NULL THEN
            select_query := select_query || REPEAT(' ', GREATEST(max_column_len - column_len, 0)) || ' -- ' || column_comment;
        END IF;
    END LOOP;
    
    select_query := select_query || chr(10) || 'FROM ' || table_name || ';';
    
    IF table_comment IS NOT NULL THEN
        select_query := select_query || ' -- ' || table_comment;
    END IF;
    
    RAISE NOTICE '%', chr(10) || select_query;
    RETURN select_query;
END;
$$ LANGUAGE plpgsql;