PL/SQL объём НDD

Эта процедура возвращает объём свободной памяти на диске D в Гб. Выполняет внешнюю команду fsutil volume diskfree D:  под Windows. Для этого должна быть запущена OracleJobSchedulerSID

Эта процедура выполняется секунду, а принцип работы такой: создается BATник, создается JOB, задание выполняется, удаляется BATник, удаляется JOB, парсится лог файл, удаляется лог файл.

create or replace procedure P_R_TASK(sOUT out varchar2) as
PRAGMA AUTONOMOUS_TRANSACTION;
sBAT_TXT varchar2(4000);
sBCP_DIRNAME constant varchar2(200) := 'BCP_DIR';
sDIR_BCP varchar2(200) := 'D:\bcp';
sBAT_NAME1 varchar(20) := 'Task.bat';
sLOG_NAME1 varchar(20) := 'diskfree.txt';

procedure CREATE_BAT(sNAME in varchar2, sTXT in varchar2) as
F1 UTL_FILE.FILE_TYPE;
begin
F1 := UTL_FILE.FOPEN(sBCP_DIRNAME, sNAME, 'W', 4048);
UTL_FILE.PUT_LINE(file => F1, buffer => sTXT);
UTL_FILE.fclose(file => F1);
end CREATE_BAT;

procedure DELETE_FILE(sFILENAME in varchar2) as
begin
begin
UTL_FILE.FREMOVE(sBCP_DIRNAME, sFILENAME);
exception
when others then
null;
end;
end DELETE_FILE;

procedure DROP_JOB as
begin
begin
dbms_scheduler.drop_job('P_R_TASK_JOB', TRUE);
exception
when others then
null;
end;
end DROP_JOB;

procedure CREATE_JOB as
begin
DROP_JOB;
begin
dbms_scheduler.create_job('P_R_TASK_JOB',
job_action => sDIR_BCP || '\' ||
sBAT_NAME1 || ' > null',
job_type => 'executable',
enabled => false,
auto_drop => false);
end;
end CREATE_JOB;

/* Конвертация блоб в клоб */
FUNCTION blob_to_clob(plob IN BLOB) RETURN CLOB IS
lclob_Result CLOB := 'X';
l_dest_offsset INTEGER := 1;
l_src_offsset INTEGER := 1;
l_lang_context INTEGER := dbms_lob.default_lang_ctx;
l_warning INTEGER;
BEGIN
IF plob IS NOT NULL AND LENGTH(plob) > 0 THEN
dbms_lob.converttoclob(dest_lob => lclob_Result,
src_blob => plob,
amount => dbms_lob.lobmaxsize,
dest_offset => l_dest_offsset,
src_offset => l_src_offsset,
blob_csid => nls_charset_id('AL32UTF8'),
lang_context => l_lang_context,
warning => l_warning);
RETURN(lclob_Result);
ELSE
RETURN NULL;
END IF;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END blob_to_clob;

procedure PARSE_LOG as
sMESSAGE VARCHAR2(1000);
SRC_LOC BFILE;
cCLOB CLOB;
bBLOB BLOB;
begin
src_loc := BFILENAME(sBCP_DIRNAME, sLOG_NAME1);

if (DBMS_LOB.FILEEXISTS(src_loc) = 1) then

DBMS_LOB.CREATETEMPORARY(bBLOB, TRUE, DBMS_LOB.SESSION);
DBMS_LOB.OPEN(src_loc, DBMS_LOB.LOB_READONLY);
DBMS_LOB.OPEN(bBLOB, DBMS_LOB.LOB_READWRITE);
DBMS_LOB.LOADFROMFILE(dest_lob => bBLOB,
src_lob => src_loc,
amount => DBMS_LOB.getLength(src_loc));
DBMS_LOB.CLOSE(bBLOB);
DBMS_LOB.CLOSE(src_loc);
cCLOB := blob_to_clob(bBLOB);

if cCLOB is not null then
--sMESSAGE := regexp_substr(cCLOB, 'Total # of avail free bytes :\s\d{5,40}');
sMESSAGE := regexp_substr(cCLOB, '\d{5,40}');
sMESSAGE := round(sMESSAGE/1024/1024/1024, 2);
end if;
else
sMESSAGE := 'Лог файл не найден';
end if;
sOUT:=sMESSAGE;

end PARSE_LOG;

begin

sBAT_TXT := '@echo off
fsutil volume diskfree D: > D:\bcp\'||sLOG_NAME1;

CREATE_BAT(sBAT_NAME1, sBAT_TXT);

CREATE_JOB;
begin
DBMS_SCHEDULER.RUN_JOB('P_R_TASK_JOB');
exception
when others then
null;
end;

DELETE_FILE(sBAT_NAME1);
DROP_JOB;
COMMIT;
PARSE_LOG;
DELETE_FILE(sLOG_NAME1);

end P_R_TASK;