sql >> Databáze >  >> RDS >> Oracle

Oracle PL/SQL - Jak uniknout dvojtečce (:), která je nesprávně interpretována pro proměnnou vazby

Při přiřazování poziční proměnné musíte kolem poziční proměnné umístit uvozovky, takže celá hodnota je v tomto bodě interpretována jako řetězec:

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

Nevěřím, že přiřazení proměnných PL/SQL podporuje escapování ve smyslu LIKE ano, a pokud ano, museli byste před voláním skriptu upravit své vstupy, což by nebylo ideální.

Trochu odbočím od původní otázky...

Budete také muset použít nějakou formu dynamického SQL k provedení akce na základě předávaných parametrů a hodnot kurzoru; a COPY je příkaz SQL*Plus, takže jej stejně nemůžete volat z PL/SQL. Navrhoval bych, abyste použili blok PL/SQL k vygenerování samostatného skriptu SQL obsahujícího všechny příkazy prostřednictvím spool a dbms_output , který poté spustíte po dokončení bloku. Něco jako:

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;

Ještě dále od vaší původní otázky...

K tomu ani nemusíte používat PL/SQL, pokud nechcete používat dynamické SQL a EXECUTE IMMEDIATE . Bude to stejné jako v předchozím příkladu:

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;


  1. Jak okamžitě zabít/zastavit dlouhý SQL dotaz?

  2. Vytvořte funkci prostřednictvím MySQLdb

  3. NHibernate Nelze převést hodnotu data/času MySQL na System.DateTime

  4. zobrazení dne prostřednictvím uložené procedury