2016-06-09 4 views
0

Я пытаюсь сделать что-то довольно просто, я пытаюсь автоматизировать удаление и резервное копирование таблиц из своего личного табличного пространства. У меня около 100 таблиц и я хочу избавиться от всех из них (кроме таблицы, которую я использую для хранения имен таблиц), но хочу сохранить данные из таблиц на случай, если они мне понадобятся когда-нибудь в будущем. Ниже приведен код, который я пытаюсь использовать для этого. Я получаю сообщение об ошибке в курсоре ref, который я буду включать ниже моего кода. Я почти ожидаю, что кто-нибудь скажет мне, что я идиот, и объясню, как это сделать проще. Если нет, скажите, пожалуйста, что я делаю неправильно с тем, как я это делаю, спасибо.Ошибка использования 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; 

ошибка я получаю следующим образом:

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

Спасибо за любую помощь.

+1

Как минимум, 'utl_file.put_line' не принимает произвольную запись, и вы не можете получить произвольный список столбцов в' varchar2'. Вы можете выполнить итерацию по каждому столбцу и построить инструкцию SQL, которая объединяет значения из каждого столбца в одну строку (включая выполнение таких операций, как «to_char» в столбцах «date» или «timestamp», чтобы сохранить их в определенном формате) , Однако вместо того, чтобы писать кучу кода, было бы разумнее просто экспортировать таблицы, используя исполняемые файлы командной строки 'exp' или' expdp'. –

+0

@JustinCave Знаете, мне пришлось конкатенации столбцов в строку, когда я впервые написал это (давным-давно) и по какой-то причине изменил его, даже не думал. Теперь я получаю ошибку «отсутствующего выражения», так что теперь проблема с SQL. Я уверен, что смогу понять это сейчас. Если вы поместите свой комментарий в качестве ответа, я приму его. Благодарю. –

ответ

1

Как минимум utl_file.put_line не принимает произвольную запись, и вы не можете получить произвольный список столбцов в varchar2.

Вы можете выполнить итерацию по каждому столбцу и построить инструкцию SQL, которая объединяет значения из каждого столбца в одну строку. Это включает в себя выполнение таких действий, как помещение to_char с явной формой маски на ваши столбцы date или timestamp, добавление разделителя, исключение любых разделителей, существующих в ваших данных, и т. Д. Это обычно довольно утомительный и подверженный ошибкам процесс. И тогда вам нужно будет написать файл управления SQL*Loader для загрузки данных в будущем.

Похоже, что вам лучше экспортировать таблицу с помощью утилиты экспорта Oracle. Это утилита командной строки (exp или expdp в зависимости от того, хотите ли вы использовать классическую версию или версию DataPump), которая позволяет экспортировать определение таблицы и данные в файл, который можно загрузить позже, используя утилиту импорта Oracle.

Смежные вопросы