Reputation: 11
I have a below function for rounding the value of an amount based on some logic -
Currently I use this round function in my SQL to get the rounded value of amount as
f_round_value(nom_ccy_cd,tran_amt)
-
However, my current requirement is to not use this function. Instead I am trying to achieve the same in SQL directly. Should I use case statements, or any other way to achieve the below logic..
I am using oracle 10i
Function f_round_value ( in_t_ccy_cd IN CCY.ccy_cd%TYPE, in_n_amt IN NUMBER)
RETURN VARCHAR2 AS
ln_dec_place_cnt CCY.decimal_place_cnt%TYPE;
ln_out_amt NUMBER;
lv_out_amt_str VARCHAR2(30);
lb_decimal_reqd BOOLEAN :=TRUE;
lb_neg_val BOOLEAN :=FALSE;
BEGIN
IF in_n_amt IS NULL THEN
lv_out_amt_str:=NULL;
ELSE IF in_n_amt < 0 THEN
lb_neg_val:=TRUE;
END IF;
IF in_t_ccy_cd IN (C_CCY_CD_JP, C_CCY_CD_IT, C_CCY_CD_IR, C_CCY_CD_KR) THEN
ln_dec_place_cnt :=0;
lb_decimal_reqd:=FALSE;
ELSE
ln_dec_place_cnt :=2; lb_decimal_reqd:=TRUE;
END IF;
ln_out_amt:=ROUND(in_n_amt,ln_dec_place_cnt);
IF lb_decimal_reqd THEN
lv_out_amt_str:=TRIM(TO_CHAR(ln_out_amt,'S999,999,999,999,990.99'));
ELSE
lv_out_amt_str:=TRIM(TO_CHAR(ln_out_amt,'S999,999,999,999,999'));
END IF;
IF lb_neg_val THEN
lv_out_amt_str:='('||SUBSTR(lv_out_amt_str,2)||')';
ELSE
lv_out_amt_str:= SUBSTR(lv_out_amt_str,2);
END IF;
END
Any help will be appreciated.
Upvotes: 0
Views: 166
Reputation: 5636
You do realize there are currencies with 3 decimal places don't you? Anyway, you don't show the complete contents of the CCY
table, but if it should contain the decimal places of each currency, you're in luck. You have everything you need. Here is a sample CCY
table with 4 currencies and a list with a value for each currency.
WITH
CCY AS(
SELECT 'BGN' ccy_cd, '975' ccy_id, 2 DecPlaces, 'Bulgarian lev' CCY_Name, 'Bulgaria' Cntry FROM dual UNION ALL
SELECT 'BHD', '048', 3, 'Bahraini dinar', 'Bahrain' FROM dual UNION ALL
SELECT 'BIF', '108', 0, 'Burundian franc', 'Burundi' FROM dual UNION ALL
SELECT 'BMD', '060', 2, 'Bermudian dollar', 'Bermuda' FROM dual
),
CcyValues as(
SELECT 'BGN' ccy_cd, 15.852 amt FROM dual UNION ALL
SELECT 'BHD', -15.852 FROM dual UNION ALL
SELECT 'BIF', 15.852 FROM dual UNION ALL
SELECT 'BMD', -15.852 FROM dual
)
SELECT v.ccy_cd, v.amt, y.DecPlaces,
translate( to_char( round( v.amt, y.DecPlaces ),
CASE y.DecPlaces
WHEN 2 THEN 'FM999,999,999,999,990.99PR'
WHEN 3 THEN 'FM999,999,999,999,990.999PR'
ELSE 'FM999,999,999,999,990PR'
END ), '<>', '()' ) Amt_Str
FROM CcyValues v
JOIN CCY y
on y.ccy_cd = v.ccy_cd;
Upvotes: 1