Oracle PLSQL:如何使用变量作为表名创建游标
我正在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);
- 我有一个包含表名列表的表,类似于:表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您知道我是否可以使用相同的代码结构打印两个脚本的结果吗?(我不想重复复制(粘贴)