PLSQL:如何使用变量创建游标 table_name

PLSQL: How to create a cursor using a variable as table_name

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

到目前为止,我尝试将 table 个名称提取到一个变量中,然后遍历该变量,但它不起作用。

我有以下代码:

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;

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

提前致谢

i expect to obtain the same amount of files as tables on the table list

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

另外,变量命名需要保持一致(archivo|archivecur2|micursor)。一般来说,最好给变量起一个有意义的名字来反映它们的用途。 var1var2太容易混淆了。

我认为您希望将文件内容用引号引起来。我使用了双引号,这是 CSV 格式的标准。

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

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;
/

您可能不喜欢我对您的程序所做的外观更改(例如 .csv 文件扩展名),显然您可以自由恢复它们。毕竟,你是你的 executable 代码的 Josiah Spode。


"Do you know if I can print the result of two scripts using the same code structure?"

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

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