使用 Oracle Ref Cursor 时出错

Error using Oracle Ref Cursor

我正在尝试做一些相当简单的事情,我正在尝试从我的个人 table space 中自动删除和备份 tables。我有大约 100 个 table 并想摆脱所有这些(我用来存储 table 名称的 table 除外),但想保留来自tables 以防将来我需要它们。下面是我试图用来完成此操作的代码。我在引用游标上收到错误,我将在我的代码下方包含该错误。我希望有人告诉我我是个白痴,并解释一种更简单的方法来做到这一点。如果不是,请告诉我我这样做的方式有什么问题,谢谢。

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:

感谢您的帮助。

至少,utl_file.put_line 不会获取任意记录,您不能将任意列列表提取到 varchar2 中。

您可以遍历每一列并构建一个 SQL 语句,将每一列的值连接成一个字符串。这将包括做一些事情,比如在你的 datetimestamp 列上放置一个带有显式格式掩码的 to_char,添加一个分隔符,转义数据中存在的任何分隔符,等等。这是通常是一个相当乏味且容易出错的过程。然后您需要编写一个 SQL*Loader 控制文件以在将来加载数据。

听起来您最好使用 Oracle 导出实用程序导出 table。这是一个命令行实用程序(expexpdp 取决于您是要使用经典版本还是 DataPump 版本),它允许您将 table 定义和数据导出到一个文件您可以稍后使用 Oracle 导入实用程序加载。