Oracle
 sql >> Database >  >> RDS >> Oracle

Oracle PL/SQL - Come evitare i due punti (:), interpretato erroneamente per la variabile di collegamento

Devi mettere le virgolette attorno alla variabile posizionale quando la assegni, quindi l'intero valore viene interpretato come una stringa a quel punto:

destination_connstring VARCHAR(20) := '&6';

Non credo che l'assegnazione di variabili PL/SQL supporti l'escape nel senso che LIKE lo fa, e se così fosse dovresti modificare i tuoi input prima di chiamare lo script, il che non sarebbe l'ideale.

Allontanandoti un po' dalla tua domanda originale...

Dovrai anche utilizzare una qualche forma di SQL dinamico per agire in base ai parametri passati e ai valori del cursore; e COPY è un comando SQL*Plus quindi non puoi comunque chiamarlo da PL/SQL. Ti suggerirei di utilizzare il blocco PL/SQL per generare uno script SQL separato contenente tutti i comandi, tramite spool e dbms_output , che quindi eseguire al completamento del blocco. Qualcosa come:

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;

Allontanandoci ancora di più dalla tua domanda originale...

Non hai nemmeno bisogno di usare PL/SQL per questo, a meno che tu non voglia usare SQL dinamico e EXECUTE IMMEDIATE . Questo farà lo stesso dell'esempio precedente:

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;