【问题标题】:How to pass text parameter to stored function for `IN` operator如何将文本参数传递给“IN”运算符的存储函数
【发布时间】:2015-12-01 12:59:06
【问题描述】:

我需要从模式中获取表名,除了一些表

CREATE OR REPLACE FUNCTION  func(unnecessary_tables TEXT)
returns void
as $$
begin
      EXECUTE 'SELECT table_name FROM information_schema.tables   
      WHERE 
      table_schema=''public''
      AND 
      table_name NOT IN( $1 )
      ' USING unnecessary_tables

      --here execute retrieved result, etc ...

end;
$$language plpgsql

然后调用函数

select func('table1'',''table2');

这不起作用并返回结果 table1table2 也。

问题是:IN 运算符如何将文本参数传递给存储函数?

【问题讨论】:

  • 不应该是select func('table1, table2');吗?
  • @Gabriel's 不,我也在尝试这个,但不起作用
  • 你试过SELECT func( '''table1'',''table2''');吗?我认为有问题。

标签: postgresql plpgsql postgresql-9.5


【解决方案1】:

传入一个文本数组而不是文本:

create or replace function func(unnecessary_tables text[])
returns void as $$
begin
    select table_name
    from information_schema.tables   
    where
        table_schema = 'public'
        and
        not(table_name = any($1))
    ;
end;
$$language plpgsql    

这样称呼:

select func(array['t1','t2']::text[]);

顺便说一句,上面的代码可以是纯 SQL 而不是 PL/pgSQL

【讨论】:

  • 可以通过VARIADIC参数增强-然后可以通过SELECT func('t1','t2')调用函数
【解决方案2】:

要回答您的确切问题(如何传递给IN 运算符的函数文本)您需要:

SELECT func( '''table1'',''table2''');

原因是表名必须是字符串,所以它们需要在引号内。 为了使其正常工作,需要对代码进行一个我一开始没有看到的更改:

  CREATE OR REPLACE FUNCTION  func(unnecessary_tables TEXT)
returns void
as $$
begin
      EXECUTE 'SELECT table_name FROM information_schema.tables   
      WHERE 
      table_schema=''public''
      AND 
      table_name NOT IN(' || unnecessary_tables || ')'; 

      --here execute retrieved result, etc ...

end;
$$language plpgsql

之所以需要它,是因为USING 知道类型,而不仅仅是“粘贴”参数来代替$1

【讨论】:

  • 这对你有用吗?我也在尝试这个,但它不起作用
  • 哦,我没注意到你使用EXECUTE ... USING ...。我已经编辑了我的答案。
【解决方案3】:

我认为以上答案都不正确。

select pg_typeof(table_name),table_name::text 
   from information_schema.tables   
   where table_schema = 'public';

它会返回:

             pg_typeof             |        table_name
-----------------------------------+--------------------------
 information_schema.sql_identifier | parent_tree

from 这意味着至少应该将 table_name 转换为文本。 这是我的解决方案:

create or replace function n_fnd_tbl(_other_tables text[])
returns table(__table_name text) as 
$$
begin
  return query EXECUTE format('
    select table_name::text
    from information_schema.tables   
    where table_schema = ''public''
    and table_name  <> ''%s''',_other_tables );
end
$$language plpgsql;

然后调用它:

select * from n_fnd_tbl(array['tableb','tablea']::text[]);

【讨论】:

    猜你喜欢
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-03
    • 1970-01-01
    相关资源
    最近更新 更多