我的PL / SQL过程在CSV文件中提供了我想要的值。但是我想使用一些值做一些数学除法。但是,当我运行代码时,在相关列中没有任何输出,我想知道为什么。
我尝试将变量说明放在过程的声明部分中,在“ BEGIN”之后,并在各个位置使用方括号。代码会编译并运行。它只是不会在我要获取输出的列中提供任何输出。
create or replace procedure THANOS is
--variables
l_dblink varchar2(100) := 'DB1';
TOTAL_ROW_COUNT varchar2(3000);
TOT_OBJECT_SIZE_MB varchar2(100);
EST_ONE_ROW varchar2(100);
file_handle UTL_FILE.file_type;
v_ts_name varchar2(30);
v_link_name varchar2(10);
v_csv_name varchar2(100);
--
begin
SELECT tablename into v_csv_name
FROM table_tracker
WHERE
CREATED_AT = (select MAX(CREATED_AT) from table_tracker);
EST_ONE_ROW := (TOTAL_ROW_COUNT / TOT_OBJECT_SIZE_MB);
select link_name into v_link_name from link_and_mail where mdate = (select max(mdate) from link_and_mail);
select distinct targetschema into v_ts_name from table;
file_handle := utl_file.fopen('ESTIMATES_CSV', v_csv_name||'_EST_PROC.csv', 'w', 32767);
UTL_FILE.PUT_LINE(file_handle, 'The below report shows total row counts in PROD');
UTL_FILE.PUT_LINE(file_handle, ' for all tables in the request:');
UTL_FILE.PUT_LINE(file_handle, ' ');
utl_file.put_line(file_handle, 'OWNER,TABLE_NAME,TOT_OBJECT_SIZE_MB,TOTAL_ROW_COUNT,EST_ONE_ROW');
for rws in (
select /*+parallel */ a.owner,a.table_name, sum(b.sum_bytes) TOT_OBJECT_SIZE_MB, EST_ONE_ROW
from dba_tables@DB1 a, V_SEG_DATA b
where a.table_name = b.segment_name
and a.table_name in
(select table_name from table)
and a.owner in (select distinct schema from table c)
group by a.owner,a.table_name
order by a.table_name
)
loop
execute immediate' select count(*) from ' ||rws.owner||'.'||rws.table_name || '@' || l_dblink into TOTAL_ROW_COUNT;
utl_file.put_line(file_handle,
rws.OWNER || ',' ||
rws.TABLE_NAME || ',' ||
rws.TOT_OBJECT_SIZE_MB || ',' ||
TOTAL_ROW_COUNT || ',' ||
EST_ONE_ROW
);
end loop;
utl_file.fclose(file_handle);
end THANOS;
此代码的结果是为.csv文件提供以下列:
OWNER TABLE_NAME TOT_OBJECT_SIZE_MB TOTAL_ROW_COUNT EST_ONE_ROW
但是,EST_ONE_ROW列始终为空。
我希望它具有行数的值除以所写内容的总对象大小:
EST_ONE_ROW := (TOTAL_ROW_COUNT / TOT_OBJECT_SIZE_MB);
免责声明-人们可能会说这不是找到我要寻找的东西的好方法,等等,但是,如果没有人做出判断并直接领导,那就太好了当我谈到代码本身的逻辑出了什么问题,“除法”逻辑出了什么问题时,我朝着正确的方向前进
谢谢你! :-)
答案 0 :(得分:3)
它们都是VARCHAR2,并且都为空。因此不会有任何结果。就像这样:
set serveroutput on
declare
TOTAL_ROW_COUNT varchar2(3000);
TOT_OBJECT_SIZE_MB varchar2(100);
EST_ONE_ROW VARCHAR2(100);
begin
EST_ONE_ROW := (TOTAL_ROW_COUNT / TOT_OBJECT_SIZE_MB);
dbms_output.put_line('EST_ONE_ROW:'||EST_ONE_ROW);
end;
输出:
EST_ONE_ROW:
PL/SQL procedure successfully completed.
但是看起来EST_ONE_ROW
是V_SEG_DATA
的一部分,因此您可能需要更改以下语句:
utl_file.put_line(file_handle,
rws.OWNER || ',' ||
rws.TABLE_NAME || ',' ||
rws.TOT_OBJECT_SIZE_MB || ',' ||
TOTAL_ROW_COUNT || ',' ||
rws.EST_ONE_ROW -- <<<<<<<<<<<<<<< change here
);
这是纯粹计算得出的另一种方法:
utl_file.put_line(file_handle,
rws.OWNER || ',' ||
rws.TABLE_NAME || ',' ||
rws.TOT_OBJECT_SIZE_MB || ',' ||
TOTAL_ROW_COUNT || ',' ||
(TOTAL_ROW_COUNT / rws.TOT_OBJECT_SIZE_MB)
);
如果TOT_OBJECT_SIZE_MB为零,则以上操作将失败。因为您将得到零故障的除法。您可能需要使用if语句来处理。
所以这可能有效:
create or replace procedure THANOS is
--variables
l_dblink varchar2(100) := 'DB1';
TOTAL_ROW_COUNT varchar2(3000);
TOT_OBJECT_SIZE_MB varchar2(100);
EST_ONE_ROW varchar2(100);
file_handle UTL_FILE.file_type;
v_ts_name varchar2(30);
v_link_name varchar2(10);
v_csv_name varchar2(100);
--
begin
SELECT tablename into v_csv_name
FROM table_tracker
WHERE
CREATED_AT = (select MAX(CREATED_AT) from table_tracker);
select link_name into v_link_name from link_and_mail where mdate = (select max(mdate) from link_and_mail);
select distinct targetschema into v_ts_name from table;
file_handle := utl_file.fopen('ESTIMATES_CSV', v_csv_name||'_EST_PROC.csv', 'w', 32767);
UTL_FILE.PUT_LINE(file_handle, 'The below report shows total row counts in PROD');
UTL_FILE.PUT_LINE(file_handle, ' for all tables in the request:');
UTL_FILE.PUT_LINE(file_handle, ' ');
utl_file.put_line(file_handle, 'OWNER,TABLE_NAME,TOT_OBJECT_SIZE_MB,TOTAL_ROW_COUNT,EST_ONE_ROW');
for rws in (
select /*+parallel */ a.owner,a.table_name, sum(b.sum_bytes) TOT_OBJECT_SIZE_MB, EST_ONE_ROW
from dba_tables@DB1 a, V_SEG_DATA b
where a.table_name = b.segment_name
and a.table_name in
(select table_name from table)
and a.owner in (select distinct schema from table c)
group by a.owner,a.table_name
order by a.table_name
)
loop
execute immediate' select count(*) from ' ||rws.owner||'.'||rws.table_name || '@' || l_dblink into TOTAL_ROW_COUNT;
if rws.TOT_OBJECT_SIZE_MB then
EST_ONE_ROW := TOTAL_ROW_COUNT / rws.TOT_OBJECT_SIZE_MB;
else
EST_ONE_ROW := null;
end if;
utl_file.put_line(file_handle,
rws.OWNER || ',' ||
rws.TABLE_NAME || ',' ||
rws.TOT_OBJECT_SIZE_MB || ',' ||
TOTAL_ROW_COUNT || ',' ||
EST_ONE_ROW
);
end loop;
utl_file.fclose(file_handle);
end THANOS;
答案 1 :(得分:0)
好吧,该过程现在的样子(即您发布的代码),EST_ONE_ROW
除了NULL之外别无其他。当TOTAL_ROW_COUNT
和TOT_OBJECT_SIZE_MB
均为NULL时,将在过程开始时计算其值。
看看是否可以放上
EST_ONE_ROW := (TOTAL_ROW_COUNT / TOT_OBJECT_SIZE_MB);
进入循环,就在UTL_FILE.put_line
调用之前,当时-用于计算其值的变量可能不再为NULL。