How to convert number to words - ORACLE

后端 未结 2 747
生来不讨喜
生来不讨喜 2021-01-13 10:13

I have written a very simple query which result a value 500, i need to convert this value like following:-

old value =     500

new value =  FIVE HUNDERED/=
         


        
相关标签:
2条回答
  • 2021-01-13 10:42

    Use the force Luke ;)

    SqlFiddleDemo

    SELECT UPPER(TO_CHAR(TO_DATE(500,'J'),'Jsp')) || '/=' AS new_value
    FROM dual;  
    

    The clue is Date in spelled format.

    EDIT:

    Adding support for negative numbers:

    SqlFiddleDemo

    WITH cte AS
    (
      SELECT 10 AS num      FROM dual
      UNION ALL SELECT -500 FROM dual
      UNION ALL SELECT 0    FROM dual
    )
    SELECT num AS old_value,
           decode( sign( num ), -1, 'NEGATIVE ', 0, 'ZERO', NULL ) ||
           decode( sign( abs(num) ), +1, to_char( to_date( abs(num),'J'),'JSP') ) || '/=' AS new_value
    FROM cte
    

    EDIT 2:##

    Adding limited support for float:

    SqlFiddleDemo3

    WITH cte AS
    (
      SELECT 10 AS num       FROM dual
      UNION ALL SELECT -500  FROM dual
      UNION ALL SELECT 0     FROM dual
      UNION ALL SELECT 10.3  FROM dual
      UNION ALL SELECT -10.7 FROM dual
    )
    SELECT 
      num AS old_value,
      decode( sign( num ), -1, 'NEGATIVE ', 0, 'ZERO', NULL )
      || decode( sign( abs(num) ), +1, to_char( to_date( abs(TRUNC(num)),'J'),'JSP') )
      ||
      CASE
         WHEN INSTR (num, '.') > 0
         THEN  ' POINT ' || TO_CHAR (TO_DATE (TO_NUMBER (SUBSTR(num, INSTR (num, '.') + 1)),'J'),'JSP')
         ELSE NULL
      END AS new_value
    FROM cte
    

    EDIT 3:

    for 10.3 output is TEN POINT THREE but it should be TEN POINT THIRTY for 10.3 and TEN POINT THREE for 10.03. How could I achieve this?

    Depending of how many digits you want for identity it could be RPADed with 0:

    WITH cte AS
    (
      SELECT 10.03 AS num FROM dual
      UNION ALL
      SELECT 10.30 FROM dual
      UNION ALL
      SELECT 10.33 FROM dual
    )
    SELECT 
      num AS old_value,
      decode( sign( num ), -1, 'NEGATIVE ', 0, 'ZERO', NULL )
      || decode( sign( abs(num) ), +1, to_char( to_date( abs(TRUNC(num)),'J'),'JSP') )
      ||
      CASE
         WHEN INSTR (num, '.') > 0
         THEN  ' POINT ' || TO_CHAR (TO_DATE (TO_NUMBER (RPAD(SUBSTR(num, INSTR (num, '.') + 1)
                                                         ,2,'0')
                                                         ),'J'),'JSP')
         ELSE NULL
      END AS new_value
    FROM cte;
    

    db<>fiddle demo

    Output:

    +-------------+------------------------+
    |  OLD_VALUE  |       NEW_VALUE        |
    +-------------+------------------------+
    |      10.03  | TEN POINT THREE        |
    |       10.3  | TEN POINT THIRTY       |
    |      10.33  | TEN POINT THIRTY-THREE |
    +-------------+------------------------+
    
    0 讨论(0)
  • 2021-01-13 10:47

    You could use the J --> JSP trick:

    SQL> SELECT TO_CHAR(TO_DATE(500,'J'),'JSP')||'/=' num_2_words FROM dual;
    
    NUM_2_WORDS
    --------------
    FIVE HUNDRED/=
    

    To understand how it works, look at this explanation by Thomas Kyte.

    0 讨论(0)
提交回复
热议问题