Reputation: 42763
I need obtain table names from schema, except some tables
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
Then call function
select func('table1'',''table2');
This not works and returns in result table1
and table2
also.
Question is: How to pass text parameter to stored function, for IN
operator ?
Upvotes: 7
Views: 16013
Reputation: 4824
I don't think none of above answers are correct.
select pg_typeof(table_name),table_name::text
from information_schema.tables
where table_schema = 'public';
It will return:
pg_typeof | table_name
-----------------------------------+--------------------------
information_schema.sql_identifier | parent_tree
from Which means at least the table_name should be cast to text. Here is my solution:
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;
Then call it:
select * from n_fnd_tbl(array['tableb','tablea']::text[]);
Upvotes: 0
Reputation: 3298
To answer you exact question (How to pass to function text for IN
operator) You need:
SELECT func( '''table1'',''table2''');
The reason is that table names must by string, so they need to by inside quotes. To make it works there is one change in code needed which I did't see at first:
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
It's needed because USING
is aware of types and don't just "paste" parameter in place of $1
.
Upvotes: 3
Reputation: 125244
Pass a text array in instead of text:
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
Call it like:
select func(array['t1','t2']::text[]);
BTW the code above can be plain SQL in instead of PL/pgSQL
Upvotes: 11