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

Arrays 在PostgreSQL中绕过字符串数组作为参数并使用动态查询,arrays,postgresql,parameter-passing,Arrays,Postgresql,Parameter Passing,过去几年我在PostgreSQL工作,但我不知道数组的概念以及如何在PostgreSQL中处理数组。我需要一个动态查询来选择多个表中的列,结果将显示在游标中,列名称将动态更改 例如,在一个多表中,如果用户需要col1、col5、col6、col25,总共有30列,所以select语句查询将动态更改,如下所示: select col1, col5,col6,col25 from table .... 另一个用户需要col2、col5、col7、col29、col26,select语句将动态更改为

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

例如,在一个多表中,如果用户需要col1、col5、col6、col25,总共有30列,所以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[]包含like

          sel[0]:='col1_name'
          sel[1]:='col5_name'
          sel[2]:='col6_name'
          sel[3]:='col25_name'
因此,首先我们必须将数组值拆分为单独的变量,这些变量将在select语句中假定为

'select'||col1, col5,col6,col25||'from......'
最后,我想简单地说,我需要在参数中传递一个数组,并且必须分离一个数组值,它将分配给不同的变量。这些变量将用于以动态方式选择语句

裸语句可以包含任意数量的列。尽管您需要一份特别声明来阅读:

注意:可以省略refcursor参数&在函数体中声明一个参数。这样,PostgreSQL将为refcursor生成一个不冲突的名称,调用SELECT func_my_方法时将返回该名称。。。。您需要在获取中使用该名称。。。声明

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

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参数拆分为上的完全限定名称的一部分。-但是有一个缺点:表和列名不能包含

或:

但这有一个令人不安的结果:因为数组需要是矩形的,所以所有列子数组需要具有相同的精确尺寸;因此,您需要为所有列提供表名,或者为其中任何一列提供表名

裸表可以包含任意数量的列。尽管您需要一份特别声明来阅读:

注意:可以省略refcursor参数&在函数体中声明一个参数。这样,PostgreSQL将为refcursor生成一个不冲突的名称,调用SELECT func_my_方法时将返回该名称。。。。您需要在获取中使用该名称。。。声明

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

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参数拆分为上的完全限定名称的一部分。-但是有一个缺点:表和列名不能包含

或:

但这有一个令人不安的结果:因为数组需要是矩形的,所以所有列子数组需要具有相同的精确尺寸;因此,您需要为所有列提供表名,或者为其中任何一列提供表名


所以您创建了动态语句。你用它做什么?。。还什么?一套?桌子行数?@VaoTsun我没有为此创建任何语句或过程,我所提到的只是供您参考。我需要一个用于上述条件的过程,并将作为游标返回。请帮我解决这个问题。那么,你需要什么样的尽管请不要忘了用format或quote_ident引用列名,以最小化SQL注入的可能性。@pozs-Ya完全正确!当您创建动态语句时,它将返回refcursors。你用它做什么?。。还什么?一套?桌子行数?@VaoTsun我没有为此创建任何语句或过程,我所提到的只是供您参考。我需要一个用于上述条件的过程,并将作为游标返回。请帮我解决这个问题。那么,你需要什么样的尽管请不要忘了用format或quote_ident引用列名,以最小化SQL注入的可能性。@pozs-Ya完全正确!它会回来的refcursor@dineshdanny是,完全限定名不能直接与format或quote_-ident一起使用。如果只想从1个表中进行选择,只需在参数中省略它们并使用“选择mm_项”。| |选择字符串,mm_项。“@丹尼。。。如果您想使用多个表,那么您要么在函数中不使用引号,要么始终从可信源调用该函数;可能需要撤销一些特权来实现这一点——或者,您需要解析sel参数。f、 前。拆分为..@pozs您能给我一个这个多表的示例吗?选择func_my_方法'CDM',数组['mm_items.id','mm_items.nm_code','um.code']@是的,完全限定名不能直接与format或quote_ident一起使用。如果只想从1个表中进行选择,只需在参数中省略它们并使用“选择mm_项”。| |选择字符串,mm_项。“@丹尼。。。如果您想使用多个表,那么您要么在函数中不使用引号,要么始终从可信源调用该函数;可能需要撤销一些特权来实现这一点——或者,您需要解析sel参数。f、 前。
拆分为..@pozs您能给我一个这个多表的示例吗?选择func_my_方法'CDM',数组['mm_items.id','mm_items.nm_code','um.code'];
CREATE OR REPLACE FUNCTION func_my_method3(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(sel[i][j]), '.')
                                                        FROM   generate_subscripts(sel, 2) j), ', ')
                                     FROM   generate_subscripts(sel, 1) i) || ' FROM ...';
  RETURN ref;
END;
$func$;

SELECT func_my_method3('check_in', ARRAY[ARRAY['check_in', 'col1'], ARRAY['check_in', 'col2']], 'sample_name3');
FETCH ALL IN sample_name3;