在PL / SQL过程中使用算术除法

时间:2019-05-06 05:42:53

标签: oracle plsql

我的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);

免责声明-人们可能会说这不是找到我要寻找的东西的好方法,等等,但是,如果没有人做出判断并直接领导,那就太好了当我谈到代码本身的逻辑出了什么问题,“除法”逻辑出了什么问题时,我朝着正确的方向前进

谢谢你! :-)

2 个答案:

答案 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_ROWV_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_COUNTTOT_OBJECT_SIZE_MB均为NULL时,将在过程开始时计算其值。

看看是否可以放上

EST_ONE_ROW := (TOTAL_ROW_COUNT / TOT_OBJECT_SIZE_MB);

进入循环,就在UTL_FILE.put_line调用之前,当时-用于计算其值的变量可能不再为NULL。