从过程中执行函数,函数名称存储在表列中

问题描述 投票:0回答:1

condition
:该表在列
fn_name

中包含函数名称
create table condition(id int,name varchar(50),fn_name varchar(50));

数据:

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');

功能:

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;

过程:

prc_bsn_condition
在此过程中调用函数。

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
$$;

输出:

true;

注意:上面的过程工作正常,但我想将动态sql转换为静态sql 由于担心sql注入。或者是否有其他方法来调用或执行这些函数 存储在表中。

postgresql function stored-procedures postgresql-16
1个回答
0
投票

使用 format() 来创建 SQL 语句并使用 USING 来获取该语句中的内容,将修复 SQL 注入风险:

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 fn_name
    INTO v_fn
    FROM condition
    WHERE id = p_id;

    v_sql := FORMAT('SELECT * FROM %I($1)', v_fn);

    EXECUTE v_sql 
    INTO v_out 
    USING p_id;
    
    RAISE INFO '%',v_out;
END
$$;
© www.soinside.com 2019 - 2024. All rights reserved.