【发布时间】:2018-06-24 06:36:16
【问题描述】:
我有不同数据类型的树形表。
我必须假脱机文件,但首先我必须将这个表中的每一个与另一个表连接起来并创建带有结果的文件。
例子:
TAB1
ID|CODE
-------
1 | A
2 | B
3 | A
TAB2
ID|CODE
-------
1 | C
2 | C
3 | A
TAB3
ID|CODE
-------
1 | C
2 | B
3 | B
NOM_CODES
CODE|DESC
A | desc1
B | desc1
C | desc1
D | desc1
这是一个树(每个表一个)过程:
procedure proc_tab1 is
l_File_Handle Utl_File.File_Type;
v_File_Name VARCHAR2(100);
begin
v_File_Name := 'TAB_1.TXT';
IF Utl_File.Is_Open(l_File_Handle) THEN
Utl_File.Fclose(l_File_Handle);
END IF;
l_File_Handle := Utl_File.Fopen(l_DIR, v_File_Name, 'W', l_Len);
for c in (select t.ID||','||t.code||','||c.desc
from tab1 t
join nom_codes c
on t.code = c.code) loop
Utl_File.Put_Line(l_File_Handle,
Convert(c.file_line, 'CL8MSWIN1251') || l_cr);
end loop;
Utl_File.Fclose(l_File_Handle);
end proc_tab1 ;
我想在一个新程序中重复(打开文件、加入、放置行、关闭文件)的事情。
类似这样的:
procedure proc_tab1 is
v_File_Name VARCHAR2(100);
begin
v_File_Name := 'TAB_1.TXT';
spool_file(v_File_Name, cursor(select t.id, t.code from t1));
end proc_tab1 ;
还有这个新程序:
procedure spool_file (p_file_name varchar2, p_curr sys_refcursor) is
l_File_Handle Utl_File.File_Type;
begin
IF Utl_File.Is_Open(l_File_Handle) THEN
Utl_File.Fclose(l_File_Handle);
END IF;
l_File_Handle := Utl_File.Fopen(l_DIR, p_file_name , 'W', l_Len);
for c in (select t.ID||','||t.code||','||c.desc
from table(p_curr) t
join nom_codes c
on t.code = c.code) loop
Utl_File.Put_Line(l_File_Handle,
Convert(c.file_line, 'CL8MSWIN1251') || l_cr);
end loop;
Utl_File.Fclose(l_File_Handle);
end spool_file ;
我想要以某种方式将行集从 tab1(以及 tab2 和 tab3)传递到 spool_file。在 spool_file 中将此行集转换为表并进行连接和其他常见的想法。
实际上我试过了,但我无法将 SYS_REFCURSOR 转换为 TABLE。我可以创建一个返回流水线结果的函数,但我认为这不是一个好主意,因为我必须对数据进行两次迭代(一次用于流水线,一次用于循环)。
我对想法持开放态度。
【问题讨论】:
-
我认为您需要编写一个流水线表函数,该函数接受一个引用游标并返回一个集合。没有内置功能可以做到这一点。
-
您可以考虑使用dynamic SQL 来代替,并使用通用函数来编写您的文件。你有很多关于 SO 的资源:@987654322@; stackoverflow.com/a/208892/6019417 ...
-
实际上,我的查询量很大,动态执行会很丑陋且不可读。
-
你能发布你希望输出文件的样子吗?
标签: sql oracle plsql cursor sys-refcursor