PostgreSQL如何执行存储在数据表字段内的查询语句?
PostgreSQL是否可以执行存储在数据表内的查询语句
完全可以,通过PL/pgSQL提供的动态SQL能力即可实现,以下是针对对应场景的具体实现方案:
- 实现逻辑:先从存储SQL语句的业务表中读取出对应条件匹配的SQL文本,再通过动态执行语法运行这段SQL,最终返回查询结果。
- 第一步:创建通用执行函数
假设存储查询规则的表包含sla_id(规则ID)、query_sql(存储的查询语句文本)两个核心字段,可创建如下函数:
CREATE OR REPLACE FUNCTION run_sla_query(target_sla_id integer) RETURNS SETOF record AS $$ DECLARE target_sql text; run_date date := current_date; -- 测试场景下执行日为2022-06-14时,可直接赋值为'2022-06-14'::date BEGIN -- 读取对应sla_id绑定的查询语句 SELECT query_sql INTO target_sql FROM 存储查询规则的表名 WHERE sla_id = target_sla_id; IF target_sql IS NULL THEN RAISE EXCEPTION 'SLA ID % 未配置对应查询规则', target_sla_id; END IF; -- 如果存储的SQL中用了固定日期占位符,可在此处替换为实际执行日期,比如把SQL里的{exec_date}替换为run_date target_sql := REPLACE(target_sql, '{exec_date}', QUOTE_LITERAL(run_date)); -- 动态执行SQL返回结果 RETURN QUERY EXECUTE target_sql; END; $$ LANGUAGE plpgsql;
- 第二步:调用函数获取结果
由于动态SQL返回的是通用record类型,调用时需要明确声明返回结果的字段名和字段类型,和预期查询的表结构保持一致即可,对应执行sla_id=1001的查询场景,调用写法如下:
SELECT * FROM run_sla_query(1001) AS res( -- 以下字段请替换为实际查询返回的字段、对应类型,和预期结果的列一一对应 id integer, sla_id integer, stat_date date, sla_target numeric, actual_value numeric );
重要注意事项
- 动态执行SQL存在天然的SQL注入风险,必须严格控制存储SQL语句的表的写入权限,仅允许管理员账号维护表内的SQL内容,禁止将外部用户传入的不可信内容直接存入该表的SQL字段。
- 每次调用函数时,AS后声明的返回字段结构必须和该条存储SQL实际查询返回的列数量、类型、顺序完全一致,否则会抛出类型匹配错误。
- 如果需要统一给所有存储SQL追加过滤条件,可在执行前对
target_sql做字符串拼接处理,不需要逐条修改表内存储的语句。
内容的提问来源于stack exchange,提问作者doniramdani
相关产品推荐
相关产品推荐

