Oracle PLSQL:如何使用变量作为表名创建游标

Oracle PLSQL:如何使用变量作为表名创建游标,oracle,plsql,cursor,dynamic-sql,Oracle,Plsql,Cursor,Dynamic Sql,我正在PLSQL中尝试以下操作: 我有一个包含表名列表的表,类似于:表1、表2、表3等等 我每天都重写这个表,所以表的列表是动态的,一天可能会有3个表,明天可能会有7个表,以此类推 基于该表列表,我想使用UTL_文件导出这些表的内容 到目前为止,我试图将表名提取到一个变量中,然后在该变量上循环,但没有成功 我有以下代码: Declare var1 SYS_REFCURSOR; var2 varchar2(20); var3 varchar2(20);

我正在PLSQL中尝试以下操作:

  • 我有一个包含表名列表的表,类似于:表1、表2、表3等等

  • 我每天都重写这个表,所以表的列表是动态的,一天可能会有3个表,明天可能会有7个表,以此类推

  • 基于该表列表,我想使用UTL_文件导出这些表的内容

到目前为止,我试图将表名提取到一个变量中,然后在该变量上循环,但没有成功

我有以下代码:

Declare
    var1 SYS_REFCURSOR;
    var2 varchar2(20);
    var3 varchar2(20);    
    ARCHIVE UTL_FILE.FILE_TYPE;
    Cursor cur2 IS SELECT TABLE_NAME FROM LIST_OF_TABLES; 

BEGIN   

ARCHIVO:=UTL_FILE.FOPEN('test_path','test.txt','W');

        for i in cur2 loop

        var2:= i.table_name;

        OPEN var1 for 'SELECT SKUID, CMRPRICE FROM '||VAR2;
        loop

       FOR C IN MICURSOR LOOP
  UTL_FILE.PUT_LINE(ARCHIVE,(''||C.SKUID||''||','||''||  C.CMRPRICE||''));
      END LOOP;
      UTL_FILE.FCLOSE(ARCHIVE);
        close var1;
        end loop;

END;
我希望获得与表列表中的表相同数量的文件

提前谢谢

我希望获得与表列表中的表相同数量的文件

在这种情况下,您需要为每个表打开不同的文件

此外,您还需要与变量命名保持一致(
archivo
|
archive
cur2
|
micursor
)。一般来说,最好给变量起一个有意义的名称,以反映它们的用法。很容易混淆
var1
var2

我想你应该把文件的内容用引号括起来。我使用了双引号,这是CSV格式的标准

此代码定义了PL/SQL记录类型,
tgt_rec
,其投影与查询字符串的投影相匹配。我们打开一个动态ref游标,然后在循环中将记录提取到该记录变量中,直到游标用尽为止

declare
    file_handle utl_file.file_type;

    rc sys_refcursor;          
    cursor cur_tables is 
        select table_name from list_of_tables; 
    type tgt_rec is record ( skuid number, cmrprice number); 
    l_rec tgt_rec;

begin   

    << tables >>
    for i in cur_tables loop

        file_handle := utl_file.fopen('test_path', i.table_name||'.csv','w');

        open rc for 'select skuid, cmrprice from '||i.table_name;

        << table_rows >>
        loop

           fetch rc into l_rec;
           exit when rc%not found;

            utl_file.put_line(file_handle, '"'||l_rec.skuid||'","'||  l_rec.cmrprice||'"');

        end loop table_rows;        

        utl_file.fclose(file_handle);

        close rc;

    end loop tables;

end;
/
声明
file\u handle utl\u file.file\u类型;
rc系统参考光标;
游标cur_表为
从表格列表中选择表格名称;
类型tgt\U rec为记录(skuid编号、cmrprice编号);
l_rec tgt_rec;
开始
>
for i in cur_tables循环
file_handle:=utl_file.fopen('test_path',i.table_name | |'.csv','w');
打开“选择skuid,cmrprice from”| | i.table_name;
>
环
将rc放入l_rec;
未找到rc%时退出;
utl|U file.put|u line(文件句柄“,”l|u rec.skuid“,”l|u rec.cmrprice“);
结束循环表_行;
utl_file.fclose(文件句柄);
关闭rc;
结束循环表;
结束;
/
您可能不喜欢我对您的程序所做的表面性更改(例如文件扩展名的
.csv
),显然您可以自由恢复这些更改。毕竟,您是可执行代码的Josiah Spode


“您知道我是否可以使用相同的代码结构打印两个脚本的结果吗?”

视情况而定。您可以将此匿名块转换为一个过程,并将查询字符串-
'select skuid,cmrprice from'
-作为参数传递。这将允许您更改已执行的查询。但是,您仍然需要将结果集提取到一些内容中,这些内容必须与投影的结构相匹配:相同的列数和相同的数据类型。所以这限制了你的灵活性


幸运的是,PL/SQL是一种合适的编程语言,具有很多功能(尽管不是Java风格的反射)。因此,您可以选择编写一些非常模块化的程序套件,其中包含用于一般事务的子例程,如文件处理和用于查询特定数据争用的子例程

你能详细说明“不起作用”对你意味着什么吗?你有错误吗?代码是否没有做您期望的事情?至少,您只打开一个文件,这是循环之外的。如果希望将每个表写入不同的文件,则需要在循环中打开和关闭一个文件。并且,假设使用与表名相关的文件名。您使用了两列--
SKUID、CMRPRICE
。那么,每个表中都存在列吗?顺便说一句,当其他表出现时,您可以尝试将
放入dbms\u output.put\u行(dbms\u utility.format\u error\u stack);dbms_output.put_line(dbms_utility.format_error_backtrace)就在
结束之前在底部声明。什么是
MICURSOR
?你可以打开和关闭动态光标
var1
,但你不能从中获取信息。“x的约西亚·斯波德”是英国的一个表达吗?那个肯定没有穿过池塘:-)@JustinCave-事实上,“你是纽约时报的押韵之物”是一句即兴的话。@APC谢谢你的回答,但是我在执行脚本时遇到了一个问题:ORA-06550:LINE 19,column 21:PLS-00221:“RC”不是一个过程或者是未定义的。第19行:适用于rc中的RECloop@APC非常感谢你!Regards@APC您知道我是否可以使用相同的代码结构打印两个脚本的结果吗?(我不想重复复制(粘贴)