PostgreSQL PL/pgSQL:表各列非空行数统计异常问题排查
问题分析与解决
你的函数错误在于把列名当作值参数传递,而非动态拼接为SQL标识符:
- 原代码中
$1通过USING传入的是列名字符串(比如'last_name'),不是实际的列引用 WHERE $1 IS NOT NULL判断的是这个字符串本身非空(永远为真),所以count($1)统计的是全表行数,而非目标列的非空行数
修正后的函数代码
create or replace function new_cnt_test_ho(in_table text, out out_table text, out cnt_rows int) returns setof record AS $$ DECLARE i text; BEGIN FOR i IN select column_name from information_schema."columns" where table_schema = 'public' and table_name = in_table LOOP execute ' select $1, count(' || quote_ident(i) || ') from '|| quote_ident(in_table) ||' where ' || quote_ident(i) || ' is not null ' INTO out_table, cnt_rows using i; -- 仅传递列名作为返回的out_table值 return next; END LOOP; END; $$LANGUAGE plpgsql;
关键修正点
- 用
quote_ident(i)动态拼接列名到SQL中,确保标识符的安全性(避免SQL注入) count(quote_ident(i))和WHERE quote_ident(i) IS NOT NULL直接引用目标列- USING仅传递列名字符串,用于填充
out_table输出字段
执行结果
执行select * from new_cnt_test_ho('actor_new')后将得到期望结果:
| out_table | cnt_rows |
|---|---|
| actor_id | 203 |
| first_name | 203 |
| last_name | 200 |
| last_update | 200 |
内容的提问来源于stack exchange,提问作者In Norm
相关产品推荐
相关产品推荐

