2016-06-09 7 views
0

Ich versuche, etwas ziemlich einfaches zu tun, ich versuche, die Entfernung und Sicherung von Tabellen aus meinem persönlichen Tabellenbereich zu automatisieren. Ich habe ungefähr 100 Tabellen und möchte sie alle loswerden (außer einer Tabelle, die ich verwende, um die Tabellennamen zu speichern), aber ich möchte die Daten aus den Tabellen behalten, falls ich sie irgendwann in der Zukunft brauche. Unten ist der Code, den ich versuche, dies zu erreichen. Ich erhalte einen Fehler beim Ref-Cursor, den ich unter meinem Code einfügen werde. Ich erwarte, dass mir jemand sagt, ich sei ein Idiot und erkläre einen einfacheren Weg, dies zu tun. Wenn nicht, sag mir bitte, was ich falsch mache mit der Art, wie ich es tue, danke.Fehler bei der Verwendung von Oracle Ref Cursor

DECLARE 
    v_folder_name  VARCHAR2(100) := 'MY_FOLDER'; 
    TYPE QRY_CURSOR  IS REF CURSOR; 
    v_qry_cursor   QRY_CURSOR; 
    v_file_name   VARCHAR2(320); 
    v_file    sys.utl_file.file_type; 
    v_max_buffer_length CONSTANT BINARY_INTEGER := 32767; 
    v_qry_str   VARCHAR2(4000); --I've tried this with 32767, made no difference 
    v_drop_string  VARCHAR2(4000); 
    v_dynamic_record  VARCHAR2(4000); --tried this with 32767 also 

CURSOR GET_TABLE_NAMES IS 
    SELECT * FROM TEMP_BACKUP_TABLE WHERE TABLE_NAME <> 'TEMP_BACKUP_TABLE'; 

FUNCTION startFile(file_name VARCHAR2) 
    --working function, used with many procedures, left out for brevity 
END startFile; 

FUNCTION closeFile(file_name VARCHAR2) 
    --working function, used with many procedures, left out for brevity 
END closeFile; 

BEGIN 
    INSERT INTO TEMP_BACKUP_TABLE SELECT DISTINCT TABLE_NAME FROM ALL_TAB_COLS WHERE OWNER = 'ME'; 
    COMMIT; 
FOR REC IN GET_TABLE_NAMES LOOP 
    v_file_name := REC.TABLE_NAME; 
    v_file := startFile(v_file_name); 
    v_qry_str := 'SELECT * FROM ' || v_file_name; 
    v_drop_string := 'DROP TABLE ' || v_file_name; 
    OPEN v_qry_cursor FOR v_qry_str; -- this is the line that returns an error 
    LOOP 
     FETCH v_qry_cursor INTO v_dynamic_record; 
     EXIT WHEN v_qry_cursor%NOTFOUND; 
     sys.utl_file.put_line(v_file, v_dynamic_record); 
    END LOOP; 

    CLOSE v_qry_cursor; 
    EXECUTE IMMEDIATE v_drop_string; 
    COMMIT; 

    v_file := closeFile(v_file_name); 
END LOOP; 
DELETE FROM TEMP_BACKUP_TABLE; 
END; 

Der Fehler Ich erhalte ist wie folgt:

Error report: 
ORA-00932: inconsistent datatypes: expected - got - 
ORA-06512: at line 73 
00932. 00000 - "inconsistent datatypes: expected %s got %s" 
*cause: 
*action: 

Vielen Dank für jede Hilfe.

+1

Zumindest nimmt 'utl_file.put_line' keinen beliebigen Datensatz und Sie können keine willkürliche Liste von Spalten in' varchar2' holen. Du könntest über jede Spalte iterieren und eine SQL-Anweisung konstruieren, die die Werte aus jeder Spalte zu einer einzigen Zeichenkette verkettet (einschließlich der Ausführung von 'to_char' an deinen 'date'- oder' timestamp'-Spalten, um sie in einem bestimmten Format zu speichern) . Anstatt einen Haufen Code zu schreiben, scheint es jedoch sinnvoller zu sein, die Tabellen nur über die Befehlszeilen 'exp' oder' expdp' zu exportieren. –

+0

@JustinCave Weißt du, ich hatte es die Spalten in eine Zeichenfolge verketten, als ich das zuerst schrieb (vor langer Zeit) und aus irgendeinem Grund änderte es, dachte nicht einmal. Jetzt bekomme ich einen "missing expression" -Fehler, also muss jetzt ein Problem mit dem SQL sein. Ich bin mir sicher, dass ich es jetzt herausfinden kann. Wenn Sie Ihren Kommentar als Antwort eingeben, akzeptiere ich ihn. Vielen Dank. –

Antwort

1

Mindestens utl_file.put_line nimmt keine willkürlichen Datensatz und Sie können nicht eine willkürliche Liste von Spalten in eine varchar2 abrufen.

Sie können über jede Spalte iterieren und eine SQL-Anweisung erstellen, die die Werte aus jeder Spalte in einer einzigen Zeichenfolge verkettet. Dazu gehören Dinge wie das Setzen eines to_char mit einer expliziten Formatmaske auf Ihre date oder timestamp Spalten, das Hinzufügen eines Trennzeichens, das Entweichen aller Begrenzer, die in Ihren Daten vorhanden sind, usw. Dies ist im Allgemeinen ein ziemlich mühsamer und fehleranfälliger Prozess. Und dann müssen Sie eine SQL*Loader Steuerungsdatei schreiben, um die Daten in Zukunft wieder zu laden.

Es klingt, als wäre es besser, wenn Sie die Tabelle mithilfe des Oracle-Exportdienstprogramms exportieren. Das ist ein Befehlszeilen-Dienstprogramm (exp oder expdp, je nachdem, ob Sie die klassische Version oder die DataPump-Version verwenden möchten), die Sie die Tabellendefinition und Daten in eine Datei exportieren können, die Sie später mithilfe des Oracle-Importdienstprogramms laden können.

Verwandte Themen