您好,登錄后才能下訂單哦!
有時候需要顯示某個欄位的匯總數量,且在例如新增、刪除、修改記錄的時候,匯總項的值要相應地改變,如果直接使用Form中的SUM屬性功能,對于清除等操作要進行復雜處理。Oracle提供了APP_CALCULATE.RUNNING_TOTAL來實現這種需求,封裝在APPCORE.PLL中。
For Example:
要匯總的ITEM為:LINES.QUANTITY,要顯示匯總結果的BLOCK為HEADERS
1.HEADERS里建立要顯示的匯總結果ITEM,如QTY_SUM
2.HEADERS里建立兩個非數據庫項,分別命名為QTY_SUM_RTOT_OLD和QTY_SUM_RTOT_DB(Number型)
3.LINES里建立兩個非數據庫項,分別命名為QUANTITY_RTOT_OLD和QUANTITY_RTOT_DB(Number型)
4.建立存儲過程來包裝APP_CALCULATE.RUNNING_TOTAL
例:
PROCEDURE RUNNING_TOTAL_QUANTITY(EVENT VARCHAR2) IS
BEGIN
APP_CALCULATE.RUNNING_TOTAL(EVENT, 'LINES.QUANTITY', 'HEADERS.QTY_SUM');
END;
--在TRIGGER中調用RUNNING_TOTAL_QUANTITY來進行計算處理
5.:LINES.QUANTITY的WHEN-VALIDATE-ITEM Trigger中寫RUNNING_TOTAL_QUANTITY('WHEN-VALIDATE-ITEM');
如果要匯總的欄位來自多個欄位的運算,需要在每個欄位的WHEN-VALIDATE-ITEM時寫運算重新計算值賦給要匯總的欄位。
6.:HEADERS的POST-QUERY Trigger中從數據庫中抓取初始的匯總值,例:
Declare
V_SUM NUMBER;
BEGIN
SELECT NVL(SUM(QUANTITY), 0)
INTO V_SUM
FROM LINES
WHERE HEADER_ID = :HEADERS.HEADER_ID;
:HEADERS.QTY_SUM := V_SUM;
:HEADERS.QTY_SUM_RTOT_DB := V_SUM;----------------------注①
END;
7.:LINES的如下TRIGGER中寫相應代碼:
--KEY-DELREC
RUNNING_TOTAL_QUANTITY('KEY-DELREC');
DELETE_RECORD;
RUNNING_TOTAL_QUANTITY('UNDELETE');----------------------注③
--KEY-DUPREC
RUNNING_TOTAL_QUANTITY('KEY-DUPREC');
DUPLICATE_RECORD;
--KEY-CLRREC
RUNNING_TOTAL_QUANTITY('KEY-CLRREC');
CLEAR_RECORD;--(網上例子為:APP_FOLDER.EVENT('KEY-CLRREC');)
--POST-QUERY
RUNNING_TOTAL_QUANTITY( 'POST-QUERY' );
--WHEN-CLEAR-BLOCK
RUNNING_TOTAL_QUANTITY( 'WHEN-CLEAR-BLOCK' );----------------------注②
注:網上例子中還有post_insert,post_update,pre_record中寫,我目前沒寫,測試OK,不知道會有什么漏洞,暫時沒測出來。
另外上面的鏈接中,作者的例子會有問題,像鏈接文章評論所說,作者需增加 注① 的代碼 ,即 WHEN-CLEAR-BLOCK的代碼需和注①同時存在(查詢發現EBS中PO的畫面也是這么做的)。
最初我沒有寫 注② 和 注① 的代碼 ,后經測試, 缺少這兩部分會出現問題 ,還是舉個例子說吧:
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
例: Line項只有一條記錄,值為100,
1)正常查詢出來記錄后,匯總欄顯示100;
2)修改記錄值為99,匯總欄變為99;
3)按F11,會提示“是否保存記錄”,選擇“否”;
--此時匯總欄值為99(正常情況下此時匯總欄顯示100)。
4)執行Ctrl+F11;
--此時匯總欄值依然為99(正常情況下此時匯總欄顯示100,(且很大問題是此時Line值為100,匯總為99))。
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
所以:注② + 注①一定要寫。
注③: Block的Delete Allowed設置為No,由于種種原因,Delete按鈕是亮的。這種情況下,點擊 Delete按鈕 的時候會提示
FRM-41049:You cannot delete this record.但是匯總量會被減掉,一直點下去,會一直減掉..直至負NNNN...
所以加上 注③,以避免這種情況時匯總量的錯誤。
至于其它在 APP_CALCULATE.RUNNING_TOTAL 中涉及到的 Trigger中是否要寫以及如何寫,還未測試,目前為止,應用正常。
(有一點問題,即"新增一條記錄,保存,然后點擊clear-record按鈕",數量會減掉,還未解決,其余Trigger應該也需要加上,但是有幾個Trigger好像在Block下面沒有,但又有其它Trigger調用在它們中產生的全局變量,暫時未過多測試。。Busy。。)
另外,如果匯總結果要拿來與其它值作比較,比如超過了某個值則raise error,則要注意running_total和比較大小兩者的先后順序。
如在when-validate-item時比較,則在此trigger中先running_total,后比較,否則...
--------------------------------------------------------------------------------------------------------------------------------------------------
附APP_CALCULATE.RUNNING_TOTAL原代碼:
PACKAGE BODY app_calculate IS
PROCEDURE running_total(event VARCHAR2,
source_field VARCHAR2,
total_field VARCHAR2) IS
Last_Val_Field VARCHAR2(61) := Source_Field || '_RTOT_OLD';
DB_Source_Field VARCHAR2(61) := Source_Field || '_RTOT_DB';
DB_Total_Field VARCHAR2(61) := Total_Field || '_RTOT_DB';
Last_Value NUMBER;
Source_Value NUMBER;
DB_Source_Value NUMBER;
Total_Value NUMBER := NVL(name_in(Total_Field), 0);
DB_Total_Value NUMBER := NVL(name_in(DB_Total_Field), 0);
New_Total NUMBER;
Form_Id FORMMODULE;
BEGIN
COPY('Entering app_calculate.running_total. Event is ' || event || '.',
'global.frd_debug');
IF (event <> 'WHEN-CLEAR-BLOCK') THEN
Last_Value := NVL(name_in(Last_Val_Field), 0);
Source_Value := NVL(name_in(Source_Field), 0);
DB_Source_Value := NVL(name_in(DB_Source_Field), 0);
END IF;
IF (event = 'POST-QUERY') THEN
copy(to_char(Source_Value), DB_Source_Field);
copy(to_char(Source_Value), Last_Val_Field);
ELSIF (event = 'WHEN-CLEAR-BLOCK') THEN
IF (Total_Value <> DB_Total_Value) THEN
copy(to_char(DB_Total_Value), Total_Field);
END IF;
ELSIF (event = 'WHEN-VALIDATE-ITEM') THEN
IF (Source_Value <> Last_Value) THEN
New_Total := Total_Value - Last_Value + Source_Value;
copy(to_char(New_Total), Total_Field);
copy(to_char(Source_Value), Last_Val_Field);
END IF;
ELSIF (event = 'KEY-DELREC') THEN
IF (Last_Value <> 0) THEN
New_Total := Total_Value - Last_Value;
copy(to_char(New_Total), Total_Field);
END IF;
copy(to_char(Source_Value), Last_Val_Field);
ELSIF (event IN ('POST-INSERT', 'POST-UPDATE')) THEN
IF (Source_Value <> DB_Source_Value) THEN
copy(to_char(DB_Source_Value), Last_Val_Field);
copy(to_char(Source_Value), DB_Source_Field);
END IF;
ELSIF (event = 'PRE-RECORD') THEN
IF (Source_Value <> Last_Value) THEN
Form_Id := Find_Form(Get_Application_Property(Current_Form_Name));
IF (Name_In('GLOBAL.RTOT_' ||
substr(source_field,
1,
least(instr(source_field, '.') - 1, 15)) ||
to_char(Form_id.id)) = 'N') THEN
copy(to_char(Last_Value), DB_Source_Field);
END IF;
copy(to_char(Source_Value), Last_Val_Field);
END IF;
ELSIF (event = 'PRE-COMMIT') THEN
Form_Id := Find_Form(Get_Application_Property(Current_Form_Name));
copy('N',
'GLOBAL.RTOT_' ||
substr(source_field, 1, least(instr(source_field, '.') - 1, 15)) ||
to_char(Form_id.id));
ELSIF (event = 'POST-FORMS-COMMIT') THEN
Form_Id := Find_Form(Get_Application_Property(Current_Form_Name));
copy('Y',
'GLOBAL.RTOT_' ||
substr(source_field, 1, least(instr(source_field, '.') - 1, 15)) ||
to_char(Form_id.id));
IF (Total_Value <> DB_Total_Value) THEN
copy(to_char(Total_Value), DB_Total_Field);
END IF;
ELSIF (event = 'UNDELETE') THEN
New_Total := Total_Value + Source_Value;
copy(to_char(New_Total), Total_Field);
copy(to_char(Source_Value), Last_Val_Field);
ELSIF (event = 'KEY-DUPREC') THEN
New_Total := Total_Value + Source_Value;
copy(to_char(New_Total), Total_Field);
copy(to_char(Source_Value), Last_Val_Field);
copy(NULL, DB_Source_Field);
ELSIF (event = 'KEY-CLRREC') THEN
IF (Last_Value <> DB_Source_Value) THEN
New_Total := Total_Value - Last_Value + DB_Source_Value;
copy(to_char(New_Total), Total_Field);
END IF;
ELSE
message('Invalid event ' || event ||
' in app_calulate.running_total');
END IF;
COPY('Completed app_calculate.running_total. Event is ' || event || '.',
'global.frd_debug');
END running_total;
END app_calculate;
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。