简体   繁体   中英

convert a function into SQL statement

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.

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM