Tabela condition
: Esta tabela contém o nome da função na colunafn_name
create table condition(id int,name varchar(50),fn_name varchar(50));
Dados:
insert into condition values(1,'check id','fn_condition_1');
insert into condition values(2,'check name','fn_condition_2');
insert into condition values(3,'check salary','fn_condition_3');
Função:fn_condition_1
create or replace function fn_condition_1(p_id int)
returns boolean
as
$$
begin
if(select count(1) from emp where id = p_id) > 0
then
return 'true';
else
return 'false';
end if;
end
$$
language plpgsql;
Procedimento: prc_bsn_condition
dentro deste procedimento, chamando a função.
create or replace procedure prc_bsn_condition(p_id int)
language plpgsql
as
$$
declare v_out varchar(10);
v_sql varchar(200);
v_fn varchar(20);
begin
select * into v_fn from (select fn_name from condition where id = p_id);
v_sql := 'SELECT * FROM '||v_fn||'('||p_id||')';
execute v_sql into v_out;
raise info '%',v_out;
end
$$;
Saída:
true;
Nota : O procedimento acima funciona bem, mas eu gostaria de converter o sql dinâmico para o estático devido ao medo de injeções de sql. Ou há algum outro método para chamar ou executar essas funções que estão armazenadas na tabela.
Uma combinação de format() para criar a instrução SQL e USING para obter o conteúdo dessa instrução corrigirá o risco de injeção de SQL: