Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Oracle PL/SQL - Como escapar de dois pontos (:), sendo mal interpretado para a variável de ligação


Você precisa colocar aspas em torno da variável posicional ao atribuí-la, para que todo o valor seja interpretado como uma string nesse ponto:
destination_connstring VARCHAR(20) := '&6';

Não acredito que a atribuição de variável PL/SQL suporte escape no sentido de que LIKE faz e, se tivesse, você teria que modificar suas entradas antes de chamar o script, o que não seria o ideal.


Afastando-se um pouco da sua pergunta original...
Você também precisará usar alguma forma de SQL dinâmico para agir com base nos parâmetros passados ​​e nos valores do cursor; e COPY é um comando SQL*Plus, então você não pode chamá-lo de PL/SQL de qualquer maneira. Eu sugiro que você use o bloco PL/SQL para gerar um script SQL separado contendo todos os comandos, via spool e dbms_output , que você executa após a conclusão do bloco. Algo como:
SET SERVEROUTPUT ON SIZE 100000 FORMAT WRAPPED;
SET TRIMOUT ON
SET TRIMSPOOL ON
SET VERIFY OFF
SET LINES 1024

SPOOL tmp_copy_commands.sql
SET TERMOUT OFF
SET FEEDBACK OFF

DECLARE
    src_username VARCHAR2(20) := '&1';
    src_password VARCHAR2(20) := '&2';
    src_connstring VARCHAR2(40) := '&3';
    dest_username VARCHAR2(20) := '&4';
    dest_password VARCHAR2(20) := '&5';
    dest_connstring VARCHAR(40) := '&6';

    CURSOR user_table_cur IS
        SELECT table_name
        FROM user_tables
        ORDER BY table_name DESC;

BEGIN
    FOR user_table IN user_table_cur LOOP
        dbms_output.put_line('COPY FROM '
            || src_username ||'/'|| src_password ||'@'|| src_connstring
            || ' TO '
            || dest_username ||'/'|| dest_password ||'@'|| dest_connstring
            || ' APPEND ' || user_table.table_name
            || ' USING SELECT * FROM '
            || user_table.table_name ||';');
    END LOOP;
END;
/

SPOOL OFF
SET TERMOUT ON
SET FEEDBACK ON

@tmp_copy_commands

EXIT 0;

Afastando-se ainda mais da sua pergunta original ...

Você nem precisa usar PL/SQL para isso, a menos que queira usar SQL dinâmico e EXECUTE IMMEDIATE . Isso fará o mesmo que o exemplo anterior:
SET TRIMOUT ON
SET TRIMSPOOL ON
SET VERIFY OFF
SET LINES 1024
SET PAGES 0
SET HEAD OFF

SPOOL tmp_copy_commands.sql
SET TERMOUT OFF
SET FEEDBACK OFF

SELECT 'COPY FROM &1./&[email protected]&3. TO &4./&[email protected]&6. APPEND '
    || table_name || ' USING SELECT * FROM ' || table_name || ';'
FROM user_tables
ORDER BY table_name DESC;

SPOOL OFF
SET TERMOUT ON
SET FEEDBACK ON

@tmp_copy_commands

exit 0;