1

我在我的 plpgsql 中需要帮助,必须返回一个具有动态列的临时表,我该怎么做?由于列的名称可能会有所不同,我不知道如何完成此过程对不起,谷歌翻译:D

CREATE OR REPLACE FUNCTION getreport(reportid INTEGER, userId VARCHAR)
RETURNS SETOF RECORD AS 
$$
    DECLARE
        recordResultadoFinal RECORD;            
        recordResultadoNomeEspecificos RECORD;      
        varGetSqlRelatorio VARCHAR;         
        varAreaId queryreports.f_area%TYPE;
        varClientId queryreports.f_client%TYPE;
        varTableNameTemp VARCHAR := 'temp'||userId; 
        varSqlAlterTable VARCHAR := '';
        varSqlUpdateTemp VARCHAR := '';
        varNomeColunaSpecificData VARCHAR := '';
    BEGIN
        SELECT f_sql,f_area,f_client INTO varGetSqlRelatorio,varAreaId,varClientId FROM queryreports WHERE f_id = reportid;
        EXECUTE 'DROP TABLE IF EXISTS '||varTableNameTemp;
        EXECUTE 'CREATE TEMP TABLE '||varTableNameTemp||' AS '||varGetSqlRelatorio;
        EXECUTE 'CREATE INDEX processid_idx ON '||varTableNameTemp||' USING btree (processid)';
        FOR recordResultadoNomeEspecificos IN EXECUTE '
                                SELECT DISTINCT cs.f_id as idcoluna, cs.f_name as nomecoluna, cs.f_type as tipodado
                                FROM clientspecifics cs
                                INNER JOIN clientspecificdatas csd ON (cs.f_id = csd.f_clientspecific AND csd.f_process IN (SELECT processid FROM '||varTableNameTemp||'))
                                ORDER BY 2
                                  '
        LOOP
            varSqlAlterTable := varSqlAlterTable||' ALTER TABLE '||varTableNameTemp||' ADD COLUMN specific_'||recordResultadoNomeEspecificos.idcoluna||' varchar;';

            IF (recordResultadoNomeEspecificos.tipodado = 1) THEN varNomeColunaSpecificData := 'f_text';
            ELSIF (recordResultadoNomeEspecificos.tipodado = 2) THEN varNomeColunaSpecificData := 'f_name';
            ELSIF (recordResultadoNomeEspecificos.tipodado = 3) THEN varNomeColunaSpecificData := 'f_date';
            ELSIF (recordResultadoNomeEspecificos.tipodado = 4) THEN varNomeColunaSpecificData := 'f_value';
            ELSIF (recordResultadoNomeEspecificos.tipodado = 5) THEN varNomeColunaSpecificData := 'f_text';
            END IF;
            varSqlUpdateTemp := varSqlUpdateTemp||' UPDATE '||varTableNameTemp||' SET specific_'||recordResultadoNomeEspecificos.idcoluna||' = csd.'||varNomeColunaSpecificData||'
                                FROM clientspecificdatas csd
                                WHERE csd.f_process = processid 
                                AND csd.f_clientspecific = '||recordResultadoNomeEspecificos.idcoluna||';';


        END LOOP;
        EXECUTE varSqlAlterTable;
        EXECUTE varSqlUpdateTemp;
        RETURN QUERY EXECUTE 'SELECT * FROM '||varTableNameTemp;
    END;
$$ LANGUAGE 'plpgsql'; 
4

1 回答 1

0

你有几个选择:

  1. 您可以返回一个 refcursor,然后从中获取。这仅适用于事务。
  2. 您可以返回一个 xml 文档,然后在您的应用程序中处理它
  3. 您可以返回 JSON 或 HSTORE。
  4. 您可以返回 setof 记录并在函数声明中指定列列表,但这既丑陋又脆弱。

问题是 PostgreSQL 在规划查询时需要知道返回类型。这意味着您不能拥有诸如锯齿状行或动态行数之类的东西。这些必须包装在计划者可以容纳的东西中。

于 2013-11-13T02:47:34.653 回答