AWS Redshift PL/pgSQL存储过程如何从RECORD动态取字段值
解决方法
在Redshift PL/pgSQL中无法直接用变量作为字段名访问RECORD类型的属性,你可以通过将RECORD转为JSON对象,再用field参数作为键提取对应值来实现需求。
你要填充的????位置直接替换为以下内容即可:
quote_literal(to_jsonb(rec) ->> field)
修改后的完整存储过程
CREATE OR REPLACE PROCEDURE test3(source_table varchar(100), target_table varchar(100), field varchar(100) ) LANGUAGE plpgsql AS $$ declare query1 text; query2 text; rec RECORD; begin query1 := 'SELECT id, ' || field ||', load_date, end_date FROM ' || quote_ident(source_table) || ' ORDER BY id, load_date'; FOR rec IN execute query1 loop query2 := 'insert into '|| quote_ident(target_table) ||' values ('||quote_literal(rec.id)||', '||quote_literal(field)||','||quote_literal(to_jsonb(rec) ->> field)||','||quote_literal(rec.load_date)||')'; execute query2; END LOOP; RETURN; END; $$;
性能优化建议
Redshift是列式存储数据库,逐行循环插入的性能极低,你完全可以省去循环逻辑,直接用单条INSERT ... SELECT语句实现相同逻辑,执行效率会有数量级提升:
CREATE OR REPLACE PROCEDURE test3(source_table varchar(100), target_table varchar(100), field varchar(100) ) LANGUAGE plpgsql AS $$ declare query text; begin query := 'INSERT INTO ' || quote_ident(target_table) || ' SELECT id, ' || quote_literal(field) || ', ' || quote_ident(field) || ', load_date FROM ' || quote_ident(source_table) || ' ORDER BY id, load_date'; execute query; RETURN; END; $$;
注:上面的代码额外增加了
quote_ident函数对表名、字段名做转义,避免SQL注入风险,同时处理带特殊字符的标识符。
内容的提问来源于stack exchange,提问作者Prithvi
相关产品推荐
相关产品推荐

