我正在尝试将一些监视信息输出到.csv文件中。我必须坚持代码的“基本”框架。问题是使其输出到.csv /使代码得以编译。
我已经尝试了多种方法来完成此操作,但现在我陷入了困境,我发现自己几乎总是在移动引号和双引号。
create or replace procedure WRITE_EST_SIZE_01 is
file_handle UTL_FILE.file_type;
begin
file_handle := utl_file.fopen('ESTIMATES_CSV',
'csv_filename' ||
to_char(sysdate,'MONYYYY')||'.csv',
'w', 32767);
for rws in (SELECT 'OWNER' || ',' ||
'SEGMENT_NAME' || ',' ||
'U' || ',' ||
'SUM_BYTES'
FROM
union ALL
select /*+ parallel*/
s.owner || ',' ||
s.segment_name || ',' ||
'U' || ',' ||
sum(s.bytes)/1024/1024
from DBA_SEGMENTS s
where s.owner = (select distinct targetschema
from pdu.pdu_table) and
s.segment_name in (select table_name
from another_table) and
s.segment_type LIKE '%TABLE%'
group by s.owner, s.segment_name
union all
select /*+ parallel*/
i.table_owner || ',' ||
i.table_name || ',' ||
'I' || ',' ||
sum(s.bytes)/1024/1024
from DBA_SEGMENTS s,
DBA_INDEXES i
where i.table_owner = (select distinct targetschema
from pdu.pdu_table) and
i.table_name in (select table_name
from another_table) and
i.owner = s.owner and
i.index_name = s.segment_name and
s.segment_type like '%INDEX%'
group by i.table_owner, i.table_name
union all
select /*+ parallel*/
l.owner || ',' ||
l.table_name || ',' ||
'L' || ',' ||
sum(s.bytes)/1024/1024
from DBA_SEGMENTS s,
ALL_LOBS l
where l.owner = (select distinct targetschema
from another_table) and
l.table_name in (select table_name
from another_table) and
l.owner = s.owner and
l.segment_name = s.segment_name
group by l.owner, l.table_name
--order by 1, 2)
loop
utl_file.put_line(file_handle,
rws.OWNER || ',' ||
rws.SEGMENT_NAME || ',' ||
rws.U || ',' ||
rws.SUM_BYTES -- your columns here
);
end loop;
utl_file.fclose(file_handle);
end WRITE_EST_SIZE_01;
这实际上不会编译,但抱怨应该声明rws.OWNER。如果我放所有的行,它会编译。用引号引起来,但随后csv输出将用引号引起来。谁能看到一种这样做的方式,即实际上将“将” SQL输出转储到.csv吗?
答案 0 :(得分:2)
您的游标查询正在并集的每个分支中进行串联,因此,如果您以独立方式运行,则将看到只有一列的结果集。当您尝试处理循环时,您正在尝试查找单个所有者/段/等。 -但它们不是该游标查询的投影的一部分。
如果为生成的单个列值赋予别名,请至少在第一个分支中使用
SELECT 'OWNER'||','||'SEGMENT_NAME'||','||'U'||','||'SUM_BYTES' AS CSV_TEXT
或更简单地说:
SELECT 'OWNER,SEGMENT_NAME,U,SUM_BYTES' AS CSV_TEXT
然后在循环中可以引用该别名:
utl_file.put_line(file_handle, rws.CSV_TEXT);
尽管将标头行直接在光标循环之前写到文件中可能会更简单,而不是使其成为该查询的一部分:
utl_file.put_line(file_handle, 'OWNER,SEGMENT_NAME,U,SUM_BYTES');
然后,您可以使用相同的单个列值别名将串联保留在其余的并集分支中;或让并集分支不连接而获取原始列(所有者等),然后将连接保留在循环内。 [正如@BobJarvis的回答在做!]但是不要同时做这两个...
答案 1 :(得分:2)
在您的SQL中,当您只是想获取各个字段时,您正在创建一个串联字符串。我建议:
create or replace procedure WRITE_EST_SIZE_01 is
file_handle UTL_FILE.file_type;
begin
file_handle := utl_file.fopen('ESTIMATES_CSV',
'csv_filename' ||
to_char(sysdate,'MONYYYY')||'.csv',
'w', 32767);
for rws in (select s.owner,
s.segment_name,
'U' AS FLAG,
sum(s.bytes)/1024/1024 AS SUM_BYTES
from DBA_SEGMENTS s
where s.owner = (select distinct targetschema
from pdu.pdu_table) and
s.segment_name in (select table_name
from another_table) and
s.segment_type LIKE '%TABLE%'
group by s.owner, s.segment_name
union all
select i.table_owner AS OWNER,
i.table_name AS SEGMENT_NAME,
'I' AS FLAG,
sum(s.bytes)/1024/1024 AS SUM_BYTES
from DBA_SEGMENTS s,
DBA_INDEXES i
where i.table_owner = (select distinct targetschema
from pdu.pdu_table) and
i.table_name in (select table_name
from another_table) and
i.owner = s.owner and
i.index_name = s.segment_name and
s.segment_type like '%INDEX%'
group by i.table_owner, i.table_name
union all
select l.owner,
l.table_name AS SEGMENT_NAME,
'L' AS FLAG,
sum(s.bytes)/1024/1024 AS SUM_BYTES
from DBA_SEGMENTS s,
ALL_LOBS l
where l.owner = (select distinct targetschema
from another_table) and
l.table_name in (select table_name
from another_table) and
l.owner = s.owner and
l.segment_name = s.segment_name
group by l.owner, l.table_name
--order by 1, 2)
loop
utl_file.put_line(file_handle,
rws.OWNER || ',' ||
rws.SEGMENT_NAME || ',' ||
rws.FLAG || ',' ||
rws.SUM_BYTES -- your columns here
);
end loop;
utl_file.fclose(file_handle);
end WRITE_EST_SIZE_01;
答案 2 :(得分:2)
写时:
) loop
utl_file.put_line(file_handle, rws.OWNER||','||rws.SEGMENT_NAME||','||rws.U||','||rws.SUM_BYTES);
您使用的列名称应在for rws in (select ...) loop
内部的查询中进行描述。当前,该SELECT
语句只有一列自动生成的名称。您需要将其更改为:
SELECT 'OWNER' owner, 'SEGMENT_NAME' segment_name, 'U' u, 'SUM_BYTES' sum_bytes
FROM dual
union all
select /*+ parallel*/
s.owner, s.segment_name, 'U', sum(s.bytes)/1024/1024
from ...
此外,您还需要以这种方式更改所有其他子查询。
或者,您可以保持此查询不变,只是有一点改动:
for rws in (SELECT 'OWNER,SEGMENT_NAME,U,SUM_BYTES' row_data
FROM
union ALL
并更改最后一行:
...
) loop
utl_file.put_line(file_handle, rws._row_data);