我正在尝试编写打开带有动态列名的游标的函数。我担心这里有明显的 SQL 注入可能性。我很高兴在精美的手册中看到这很容易做到,但是当我在我的示例中尝试时,它出错了
错误:列不存在。
我目前的尝试可以浓缩成这个 SQL Fiddle。下面,我展示了这个小提琴的格式化代码。
函数的目标tst()
是能够计算常量查询的任何给定列中值的不同出现次数。
我要求提示我做错了什么,或者以安全的方式实现相同目标的其他方法。
CREATE TABLE t1 (
f1 character varying not null,
f2 character varying not null
);
CREATE TABLE t2 (
f1 character varying not null,
f2 character varying not null
);
INSERT INTO t1 (f1,f2) VALUES ('a1','b1'), ('a2','b2');
INSERT INTO t2 (f1,f2) VALUES ('a1','c1'), ('a2','c2');
CREATE OR REPLACE FUNCTION tst(p_field character varying)
RETURNS INTEGER AS
$BODY$
DECLARE
v_r record;
v_cur refcursor;
v_sql character varying := 'SELECT count(DISTINCT(%I)) as qty
FROM t1 LEFT JOIN t2 ON (t1.f1=t2.f1)';
BEGIN
OPEN v_cur FOR EXECUTE format(v_sql,lower(p_field));
FETCH v_cur INTO v_r;
CLOSE v_cur;
return v_r.qty;
END;
$BODY$
LANGUAGE plpgsql;
测试执行:
SELECT tst('t1.f1')
提供错误信息:
ERROR: column "t1.f1" does not exist Hint: PL/pgSQL function tst(character varying) line 1 at OPEN