Как при выполнении долгой операции в Oracle показать прогресс бар?
Ниже приведен пример, как это сделать при помощи Direct Oracle Access, надеюсь этот кусок кода несложно запустить в отдельном процессе, а в другом можно запустить перемесчатель прогресс бара. Есть готовая компонента, могу поделиться.
//на создании потока вставим то, что будет выбирать необходимую информацию Self.fods.SQL.Text:='SELECT SOFAR FROM V$SESSION_LONGOPS WHERE CONTEXT=:FK_ID'; Self.fods.DeclareVariable('FK_ID',otInteger); Self.fods.SetVariable('FK_ID',ID); //На выполнение потока вешаем открытие/закрытие TOracleDataSet while (Terminated = false) do begin Self.fods.Close; Self.fods.Open; Self.fpb.Progress := Self.fods.FieldByName('SOFAR').AsInteger; //^^^^Эта строчка как раз и устанавливает нужный прогрессбар в нужную позицию... end;
Ну и соответсвенно перед выполнением всего этого дела необходимо выставить максимальное число (100%) :
PROCEDURE SETMaxValue(nVal IN NUMBER);
Минимальное:
PROCEDURE SETMinValue(nVal IN NUMBER);
Значение шага:
PROCEDURE SetStepValue(nValue IN NUMBER);
Вышеприведенный кусок кода - клиентская часть, но есть и "подводный камень" - серверная часть... Данный метотод подкодит только для функций, процедур и пактеов, в которых вы можете написать вставить следущую строчку:
PROGRESS_BAR.STEPIT;
Код пакета PROGRESS_BAR приведен ниже:
create or replace package PROGRESS_BAR IS -- Wrote by Philip A. Milovanov nMaxValue NUMBER:=0; nMinValue NUMBER:=0; nCurrentValue NUMBER:=0; nStepValue NUMBER:=1; nID PLS_INTEGER; slno PLS_INTEGER; target PLS_INTEGER; PROCEDURE SETMaxValue(nVal IN NUMBER); PROCEDURE SETMinValue(nVal IN NUMBER); FUNCTION INIT RETURN NUMBER; PROCEDURE StepIt; PROCEDURE SetStepValue(nValue IN NUMBER); PROCEDURE StepIt(C IN NUMBER); END; -- Package Specification PROGRESS_BAR / --Сам пакет: Create or Replace Package Body PROGRESS_BAR IS -- Wrote by Philip A. Milovanov PROCEDURE SETMaxValue(nVal IN NUMBER) IS BEGIN if nVal<nMinValue THEN RAISE_APPLICATION_ERROR(-20001,'Ìèíèìàëüíîå çíà÷åíèå íå äîëæíî áûòü áîëüøå ìàêñèìàëüíîãî ìèí:'||nMinValue||' ,ìàêñ:'||nVal); END IF; nMaxValue:=nVal; END; PROCEDURE SETMinValue(nVal IN NUMBER) IS BEGIN if nVal>nMaxValue THEN RAISE_APPLICATION_ERROR(-20001,'Ìèíèìàëüíîå çíà÷åíèå íå äîëæíî áûòü áîëüøå ìàêñèìàëüíîãî ìèí:'||nVal||' ,ìàêñ:'||nMaxValue); END IF; nMinValue:=nVal; END; FUNCTION INIT RETURN NUMBER IS CURSOR c IS SELECT OBJECT_ID FROM ALL_OBJECTS WHERE OBJECT_NAME='PROGRESS_BAR'; i NUMBER; BEGIN OPEN c; FETCH c INTO target; CLOSE c; SELECT SEQ_TPROCESS_BAR.NEXTVAL INTO i FROM DUAL; nCurrentValue:=nMinValue; nID:=DBMS_APPLICATION_INFO.set_session_longops_nohint; DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS(nID,slno,'CALCULATING REPORT',target,i,nCurrentValue,nMaxValue,'PROGRESS BAR INFO',NULL); RETURN i; END; PROCEDURE StepIt IS BEGIN nCurrentValue:=nCurrentValue+nStepValue; DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS(nID,slno,'CALCULATING REPORT',target,nMinValue,nCurrentValue,nMaxValue,'PROGRESS BAR INFO',NULL); END; PROCEDURE SetStepValue(nValue IN NUMBER) IS BEGIN nStepValue:=nValue; END; PROCEDURE StepIt(C IN NUMBER) IS BEGIN nCurrentValue:=nCurrentValue+c; DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS(nID,slno,'CALCULATING REPORT',target,nMinValue,nCurrentValue,nMaxValue,'PROGRESS BAR INFO',NULL); END; END;
Взято из https://forum.sources.ru