Функция PSQL не может экранировать кавычки - PullRequest
0 голосов
/ 08 мая 2018

У меня есть запрос, как показано ниже. проанализировать и сравнить количество строк в одной и той же таблице на разных серверах. это сработало, как и ожидалось, но столкнется с проблемой, если есть какие-либо имена таблиц со смешанным нижним и верхним регистром, например: 'stg.my_table_OTHER'.

это сработало, если я добавлю кавычки наподобие stg. "My_table_OTHER". но это не похоже на работу по функции. уже пытался сбежать с помощью '\ "stg.my_table_OTHER \"', но все равно не повезло.

пожалуйста, найдите ниже мой запрос.

С уважением, РИАН

CREATE OR REPLACE FUNCTION dwh.sync_update_analyze(schemaname varchar, tablename varchar)
        RETURNS integer AS $body$
        DECLARE

            passedSrc boolean;
            passedTgt boolean;
            rowcount bigint;                                                                                                  
            tgtcount bigint;
            query text; 
        BEGIN
            SELECT EXISTS (                                                                                                   
                    SELECT 1                                                                                                       
                    FROM   pg_catalog.pg_class c                                                                                   
                    JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace                                                     
                    WHERE  n.nspname = $1                                                                                          
                    AND    c.relname = $2                                                                                          
                    AND    c.relkind = 'r'    -- only tables                                                                       
            ) into passedSrc;

            passedTgt = ops.runcmd('psql -h 666.66.6.666 -Atc "SELECT EXISTS ( SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = ''' || schemaname || ''' AND c.relname = ''' || tablename || ''' AND c.relkind = ''r'');"');



            IF passedSrc = 't' and passedTgt = 't' THEN

            query = ops.runcmd('psql -h 666.66.6.666 -Atc "ANALYZE ' || schemaname || '.' || tablename || ';"'); 

                tgtcount = ops.runcmd('psql -h 666.66.6.666 -Atc "select count(*) from ' || schemaname || '.' || tablename || ';"'); 
                EXECUTE '(select count(1) from ' || quote_ident($1) || '.' || quote_ident($2) || ')' INTO rowcount;               
                         query := 'UPDATE dwh.table_list_2018 SET                                                                  
                         move_data_to_dca = ''D'',                                                                                 
                         row_count = '|| rowcount || ',
                         target_cnt = '|| tgtcount ||'
                         WHERE schema = ''' || $1 || ''' and table_name = ''' || $2 || '''';          
                         EXECUTE query;

            ELSE                                                                                                           
                         query := 'UPDATE dwh.table_list_2018 SET                                                                  
                         move_data_to_dca = ''D'',                                                                                 
                         purge_table = ''Y'',
                         backup_location = ''table maybe purge on source or relation doesnt exists''                                                                                       
                         WHERE schema = ''' || $1 || ''' and table_name = ''' || $2 || '''';          
                         EXECUTE query;                                                                                            

           END IF; 

                 return 0;

                    EXCEPTION WHEN OTHERS THEN
                 query := 'UPDATE dwh.table_list_2018 SET                                                                  
             move_data_to_dca = ''D'',                                                                                 
             purge_table = ''Y'',
             backup_location = ''table maybe purge on source or relation doesnt exists''                                                                                
             WHERE schema = ''' || $1 || ''' and table_name = ''' || $2 || '''';          
             EXECUTE query; 
             RETURN 1;


        END
        $body$ LANGUAGE plpgsql;

ошибка выдает в этой части

 tgtcount = ops.runcmd('psql -h 666.66.6.666 -Atc "select count(*) from ' || schemaname || '.' || tablename || ';"'); 

когда я перевожу в

 tgtcount = ops.runcmd('psql -h 666.66.6.666 -Atc "select count(*) from ' || schemaname || '.\"' || tablename || '\";"'); 

бросает

 HINT:  Use the escape string syntax for escapes, e.g., E'\r\n'
 INT:  Use the escape string syntax for escapes, e.g., E'\r\n'.
 QUERY:  SELECT  ops.runcmd('psql -h 666.66.6.666 -Atc "select count(*) from ' ||  $1  || '.\"' ||  $2  || '\";"')
 CONTEXT:  SQL statement in PL/PgSQL function "sync_update_analyze1" near line 26
 WARNING:  nonstandard use of escape in a string literal

только для информации. я использую

 "PostgreSQL 8.2.15 (Greenplum Database 4.3.18.0 build 1) on x86_64-unknown-linux-gnu, compiled by GCC gcc (GCC) 4.4.2 compiled on Nov 22 2017 18:54:31"

1 Ответ

0 голосов
/ 08 мая 2018

Я ничего не знаю о greenplum, но если бы он вел себя как PostgreSQL, я бы попробовал так:

tgtcount := ops.runcmd(
               'psql -h 666.66.6.666 -Atc ''select count(*) from '
               || quote_ident(schemaname) || '.'
               || quote_ident(tablename) || ';'''
            );

Таким образом, вы используете одинарные кавычки для оператора SQL, чтобы не было конфликта с двойными кавычками, которые может добавить quote_ident.

...