Reputation: 2412
I have a PostgresSQL function:
CREATE OR REPLACE FUNCTION public.replace_id_special_char(my_suf text)
RETURNS text
LANGUAGE 'plpgsql'
COST 100
VOLATILE
AS $BODY$
declare
c1 text;
c2 text;
cursor1 refcursor;
lc_time time with time zone;
begin
open cursor1 for execute 'SELECT column_name,data_type from information_schema.columns WHERE column_name not in(''qr_id'',''qr_nm'',''qr_op_id'',''qr_op_nm'',''qr_op_line_seq'',''date_start'',''date_end'',''qr_op_val_seq'',''qr_op_value'') AND table_name = lower(''tmp_qw_'||$1||''') AND table_schema =current_schema()';
loop
fetch cursor1 into c1,c2;
exit when not found;
raise notice 'column_name: %', c1;
if upper(c2)=upper('text') then
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id1__'',''!'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id2__'',''@'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id3__'',''#'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id4__'',''$'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id5__'',''%'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id6__'',''^'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id7__'',''&'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id8__'',''*'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id9__'',''('')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id10__'','')'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id11__'',''-'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id12__'',''='')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id13__'',''+'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id14__'',''"'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id15__'',''\'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id16__'',''.'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id17__'',''/'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id18__'','' '')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id19__'','':'')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id20__'','''')';
execute'update tmp_qw_'||$1||' set '||c1||'=replace('||c1||',''__id0__'','''')';
end if;
end loop;
close cursor1;
return 'values replaced.';
end; $BODY$;
I am running over 27 queries. This function is taking a lot of time to run. Is there a way where I can speed it up?
Upvotes: 0
Views: 80
Reputation: 246288
Rather than running 27 large UPDATE
s, run a single one that does
UPDATE ...
SET ... = replace(
...
replace(
replace(
..., '__id1__','!'
), '__id2__', '@'
), ...
)
FROM ...
WHERE ... LIKE '%\_\_id_\_\_%';
Besides, your function is vulnerable to SQL injection. Use format()
to correctly format identifiers and string literals in query strings:
EXECUTE format(
'update %I set %I = ...',
'tmp_qw_' || $1,
c1
);
Upvotes: 4