如何在列是动态时迭代记录

时间:2014-08-23 18:10:13

标签: sql postgresql sql-function

嗨我在postgres中有这个函数,它包含了包含进入查询的列的PVH_COLS_DYNA:

CREATE OR REPLACE FUNCTION DRYNAMIC_DATA_F(PVH_COLS_DYNA VARCHAR) RETURNS numeric AS $$
    DECLARE

      VV_QUERY_DINAMIC VARCHAR;
      VV_ROW_RECORD record;

    BEGIN

    VV_QUERY_DINAMIC:=' SELECT '|| PVH_COLS_DYNA ||' FROM as_detalle_carga WHERE fk_id_carga_cartera = 1234 ;';


    FOR VV_ROW_RECORD IN EXECUTE VV_QUERY_DINAMIC LOOP
            raise notice ' data  % ', VV_ROW_RECORD.???????; 
    END LOOP;

    return 1;

    END;
    $$ LANGUAGE plpgsql;    

如何从记录变量 VV_ROW_RECORD 获取数据,因为列是动态的

    VV_ROW_RECORD.1
    VV_ROW_RECORD.?1
    VV_ROW_RECORD.[1]
    VV_ROW_RECORD.?????

2 个答案:

答案 0 :(得分:0)

您不能引用数组项之类的列,必须按名称引用列。

动态部分未获取示例中的行,而是引用每列。

CREATE OR REPLACE FUNCTION dynamic_data_f(pvh_cols_dyna text)
  RETURNS numeric AS
$func$
DECLARE
   _row  as_detalle_carga%ROWTYPE;
   _col  text;
   _data text;
BEGIN

SELECT *
INTO   _row 
FROM   as_detalle_carga
WHERE  fk_id_carga_cartera = 1234;

FOREACH _col IN ARRAY string_to_array(pvh_cols_dyna, ',') 
LOOP
   EXECUTE format('SELECT ($1).%I::text', trim(_col))
   USING   _row
   INTO    _data;

   RAISE NOTICE 'data: % ', _data;
END LOOP;

RETURN 1;

END
$func$ LANGUAGE plpgsql;

%Iformat()的参数,可根据需要正确转义标识符 EXECUTE的查询字符串中的$1是由USING子句填充的参数(不要与函数参数混淆!)。

相关答案(有更多解释):

答案 1 :(得分:0)

您无法直接迭代record列。您必须先将其转换为可迭代的内容,例如jsonhstore

FOR vv_row_record IN EXECUTE vv_query_dynamic LOOP

    FOR vv_row_record_pairs IN SELECT * FROM json_each(row_to_json(vv_row_record)) LOOP
        RAISE NOTICE ' field "%" in json is % ',
            vv_row_record_pairs.key,
            vv_row_record_pairs.value; 
    END LOOP;

    -- OR

    FOR vv_row_record_pairs IN SELECT * FROM each(hstore(vv_row_record)) LOOP
        RAISE NOTICE ' field "%" in text representation is % ',
            vv_row_record_pairs.key,
            vv_row_record_pairs.value; 
    END LOOP;

END LOOP;