Использование арифметического деления в процедуре PL / SQL - PullRequest
0 голосов
/ 06 мая 2019

Моя процедура 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 ]

3 голосов
/ 06 мая 2019

Все они 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;
0 голосов
/ 06 мая 2019

Что ж, теперь, как выглядит процедура (т. Е. Код, который вы разместили), 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...