绕过字符串数组作为参数并在PostgreSQL中使用动态查询

时间:2017-03-23 09:04:09

标签: arrays postgresql parameter-passing

我过去几年在PostgreSQL工作,但我不知道数组概念以及如何在PostgreSQL中处理数组。我需要一个动态查询来选择多个表中的列,结果将在游标中,列名称应该动态地改变。

例如

在多表中共有30列,如果用户需要col1,col5,col6,col25),那么select语句查询将动态地改变如下:

select col1, col5,col6,col25 from table ....

另一个用户需要col2,col5,col7,col29,col26,select语句将动态更改为

select col2,col5,col7,col29,col26 from table .... and so on.

存储过程传递参数将是数组

create or replace function func_my_method(check_in character varying, sel character varying[])...

此sel []包含类似

          sel[0]:='col1_name'
          sel[1]:='col5_name'
          sel[2]:='col6_name'
          sel[3]:='col25_name'

所以首先我们必须将数组值拆分为单独的变量,这些变量将在select语句中假设为

'select'||col1, col5,col6,col25||'from......'

最后想简单地说我需要在参数中传递数组并且必须分离数组值,它将分配给单独的变量。这些变量将用于以动态方式选择语句

1 个答案:

答案 0 :(得分:2)

refcursor可以包含任意数量的列。虽然您需要一个特殊声明来阅读它:FETCH ...

CREATE OR REPLACE FUNCTION func_my_method(check_in text, sel text[], ref refcursor)
  RETURNS refcursor
  LANGUAGE plpgsql
AS $func$
BEGIN
  OPEN ref FOR EXECUTE 'SELECT ' || (SELECT string_agg(quote_ident(c), ', ')
                                     FROM   unnest(sel) c) || ' FROM ...';
  RETURN ref;
END;
$func$;

SELECT func_my_method('check_in', ARRAY['col1', 'col2'], 'sample_name');
FETCH ALL IN sample_name;

http://rextester.com/ZCZT84224

注意:您可以省略refcursor参数&你的函数体中有DECLARE个。这样,PostgreSQL将为refcursor生成一个(非冲突的)名称,在调用SELECT func_my_method(...)时将返回该名称。您在FETCH ...声明中需要该名称。

更新:如果您想完全限定(某些)列(即写表名称和列),您需要:

CREATE OR REPLACE FUNCTION func_my_method2(check_in text, sel text[], ref refcursor)
  RETURNS refcursor
  LANGUAGE plpgsql
AS $func$
BEGIN
  OPEN ref FOR EXECUTE 'SELECT ' || (SELECT string_agg((SELECT string_agg(quote_ident(c), '.')
                                                        FROM   unnest(string_to_array(fq, '.')) c), ', ')
                                     FROM   unnest(sel) fq) || ' FROM ...';
  RETURN ref;
END;
$func$;

SELECT func_my_method2('check_in', ARRAY['col1', 'check_in.col2'], 'sample_name2');
FETCH ALL IN sample_name2;

(这会将sel参数拆分为.上完全限定名称的"部分" - 但是有一个缺点:表格和列名称不能包含{ {1}})

或者:

.

(但这有一个令人不安的后果:由于数组需要是矩形的,所有列子数组都需要具有相同的精确尺寸;因此您需要为所有列提供表名,或者都不需要他们。)

http://rextester.com/JNI24740