PostgresSQL Функция занимает много времени - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть функция PostgresSQL:

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$;

Я выполняю более 27 запросов. Эта функция занимает много времени для запуска. Есть ли способ, где я могу ускорить его?

1 Ответ

4 голосов
/ 21 апреля 2020

Вместо запуска 27 больших UPDATE с, запустите один, который выполняет

UPDATE ...
SET ... = replace(
             ...
             replace(
                replace(
                   ..., '__id1__','!'
                ), '__id2__', '@'
             ), ...
          )
FROM ...
WHERE ... LIKE '%\_\_id_\_\_%';

Кроме того, ваша функция уязвима для SQL инъекции. Используйте format() для правильного форматирования идентификаторов и строковых литералов в строках запроса:

EXECUTE format(
           'update %I set %I = ...',
           'tmp_qw_' || $1,
           c1
        );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...