在PostgreSQL函数中传递表列名

时间:2018-12-28 13:51:03

标签: postgresql

我已经阅读了一些有关在PostgreSQL函数中使用表列名的文章,但我无法使其适用于我。

我有这个简单的功能

DROP FUNCTION IF EXISTS public.benchmark(CHARACTER VARYING, CHARACTER VARYING, BIGINT, BIGINT, BIGINT);
CREATE OR REPLACE FUNCTION benchmark(params CHARACTER VARYING, colName CHARACTER VARYING, idFrom BIGINT, idTo BIGINT, testNumber BIGINT) RETURNS SETOF RECORD AS $$
DECLARE
    elemArray TEXT[] := ARRAY(SELECT colName FROM public.test WHERE test.id BETWEEN idFrom AND idTo);
    selectedElem RECORD;
    elem TEXT;
BEGIN
    FOREACH elem IN ARRAY elemArray LOOP
        raise notice 'elem Value: %', elem;
        SELECT elem INTO selectedElem;
        RETURN NEXT selectedElem;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

当我用

执行它时
SELECT * FROM public.benchmark('ad','name',1,2,1) AS x(Item TEXT);

我明白了

enter image description here

我应该得到的是 idFrom idTo 之间的 name 列值。如何在elemArray TEXT[] := ARRAY(SELECT colName FROM public.test WHERE test.id BETWEEN idFrom AND idTo);

中使用colName变量作为实际的列名

1 个答案:

答案 0 :(得分:1)

您可以将RETURNS TABLE + RETURN QUERY EXECUTE用于动态列。

CREATE OR REPLACE FUNCTION benchmark(params CHARACTER VARYING, colName 
CHARACTER VARYING, idFrom BIGINT, idTo BIGINT, testNumber BIGINT) 
RETURNS TABLE (colvalue TEXT)  AS 
$$
 BEGIN
  RETURN QUERY EXECUTE --dynamic query
          format('SELECT %I::TEXT FROM test WHERE test.id BETWEEN $1 AND $2',colName)
                       --dynamic cols                           --bind parameters
   USING idFrom,idTo;
 END;
$$ LANGUAGE plpgsql;

Demo

编辑

  

我只想用colName元素填充它并使用   扩展代码后面的数组

您可以使用ARRAY_AGG并将其加载到数组变量中。

CREATE OR REPLACE FUNCTION benchmark(params CHARACTER VARYING, colName 
CHARACTER VARYING, idFrom BIGINT, idTo BIGINT, testNumber BIGINT) 
RETURNS void   AS 
$$
DECLARE
elemArray TEXT[];
    elem TEXT;
 BEGIN
 EXECUTE format('SELECT array_agg(%I::TEXT) FROM test 
                     WHERE test.id BETWEEN $1 AND $2',colName)
   USING idFrom,idTo INTO elemArray ;
   FOREACH elem IN ARRAY elemArray LOOP
    raise notice 'elem Value: %', elem;
    END LOOP;
 END;
$$ LANGUAGE plpgsql;


knayak=# DO $$
knayak$# BEGIN
knayak$# PERFORM benchmark('ad','name',1,2,1);
knayak$# END
knayak$# $$;
NOTICE:  elem Value: TalG
NOTICE:  elem Value: John Doe
DO