sql >> Database >  >> RDS >> Oracle

Oracle:valutabedrag in woorden converteren met PL/SQL

Hieronder geef ik een voorbeeld van een door Oracle opgeslagen functie om het valutabedrag in woorden om te zetten met behulp van PL/SQL. Het bedrag van $ 123,45 zou bijvoorbeeld worden vertaald als honderddrieëntwintig dollar en vijfenveertig cent. U kunt ook de valuta in functie wijzigen, bijvoorbeeld roepies en paise.

Oracle PL/SQL-functie om het valutabedrag in woorden om te zetten

De volgende in Oracle PL/SQL opgeslagen functie accepteert een numeriek argument en heeft geen beperkingen. Een getal kan een decimaal, geheel getal en negatief getal zijn. De functie amount_in_words heeft een functie binnen check_if_single , en check_if_single functie heeft een n_spell functie binnen om het valutabedrag in woorden om te zetten. Ik dacht erover om een ​​pakket te maken in plaats van deze functie, maar ik dacht dat alleen een functie gemakkelijker te onderhouden zou zijn.

CREATE OR REPLACE FUNCTION amount_in_words (i_amt IN NUMBER)
   RETURN VARCHAR2
IS
   n_dollar   NUMBER;
   n_cents    NUMBER;

   FUNCTION check_if_single (i_num IN NUMBER, currency IN VARCHAR2)
      RETURN VARCHAR2
   IS
      FUNCTION n_spell (i_num IN NUMBER)
         RETURN VARCHAR2
      AS
         TYPE w_Array IS TABLE OF VARCHAR2 (255);

         l_str w_array
               := w_array ('',
                           ' thousand ',
                           ' million ',
                           ' billion ',
                           ' trillion ',
                           ' quadrillion ',
                           ' quintillion ',
                           ' sextillion ',
                           ' septillion ',
                           ' octillion ',
                           ' nonillion ',
                           ' decillion ',
                           ' undecillion ',
                           ' duodecillion ');

         l_num           VARCHAR2 (50) DEFAULT TRUNC (i_num);
         l_is_negative   BOOLEAN := FALSE;
         l_return        VARCHAR2 (4000);
      BEGIN
         IF SIGN (i_num) = -1
         THEN
            l_is_negative := TRUE;
            l_num := TRUNC (ABS (i_num));
         END IF;

         FOR i IN 1 .. l_str.COUNT
         LOOP
            EXIT WHEN l_num IS NULL;

            IF (SUBSTR (l_num, LENGTH (l_num) - 2, 3) <> 0)
            THEN
               l_return :=
                  TO_CHAR (
                     TO_DATE (SUBSTR (l_num, LENGTH (l_num) - 2, 3), 'J'),
                     'Jsp')
                  || l_str (i)
                  || l_return;
            END IF;

            l_num := SUBSTR (l_num, 1, LENGTH (l_num) - 3);
         END LOOP;

         IF NOT l_is_negative
         THEN
            RETURN INITCAP (l_return);
         ELSE
            RETURN 'Negative ' || INITCAP (l_return);
         END IF;
      END n_spell;
   BEGIN
      IF i_num = 1
      THEN
         RETURN 'One ' || currency;
      ELSE
         RETURN n_spell (i_num) || ' ' || currency;
      END IF;
   END check_if_single;
BEGIN
   IF i_amt IS NULL
   THEN
      RETURN '';
   END IF;

   n_dollar := TRUNC (i_amt);
   n_cents := (ABS (i_amt) - TRUNC (ABS (i_amt))) * 100;

   IF NVL (n_cents, 0) > 0
   THEN
      RETURN    check_if_single (n_dollar, 'Dollar')
             || ' and '
             || check_if_single (n_cents, 'Cents');
   ELSE
      RETURN check_if_single (n_dollar, 'Dollar');
   END IF;
END amount_in_words;
/

Test

SELECT amount_in_words (89378.58) FROM DUAL;

Uitvoer

Eighty-Nine Thousand Three Hundred Seventy-Eight Dollar and Fifty-Eight Cents

Test via een tabel

SELECT client_code,
       balance_amt,
       amount_in_words (balance_amt) balance_amount_in_words
  FROM account_balance;

Uitvoer

CLIENT_CODE BALANCE_AMT BALANCE_AMOUNT_IN_WORDS
88499 7884.98 Achtenzeventig duizend achthonderd negenenveertig dollar en achtennegentig cent
77493 7738829.15 Zeven miljoen zevenhonderd achtendertig duizend achthonderd negenentwintig dollar en vijftien cent
88399 99836662388.98 Negenennegentig miljard achthonderd zesendertig miljoen zeshonderdtweeënzestigduizend driehonderdachtentachtig dollar en achtennegentig cent
97737 -88993.5 Negatief achtentachtigduizend negenhonderddrieënnegentig dollar en vijftig cent
88948 998349 Negenhonderd achtennegentigduizend driehonderdnegenenveertig dollar

U kunt de valuta wijzigen wanneer u de check_if_single . aanroept functie van amount_in_words functie. Ik ben bijvoorbeeld veranderd in Rupees en Paise in het volgende deel van de PL/SQL-code:

 IF NVL (n_cents, 0) > 0
   THEN
      RETURN    check_if_single (n_dollar, 'Rupees')
             || ' and '
             || check_if_single (n_cents, 'Paise');
   ELSE
      RETURN check_if_single (n_dollar, 'Rupees');
   END IF;

Test na het maken van de wijziging

SELECT amount_in_words (7836.58) in_words FROM DUAL;

Uitvoer

Seven Thousand Eight Hundred Thirty-Six Rupees and Fifty-Eight Paise

Misschien moet u het woord Roepies van de eind- naar de beginpositie van de regel verplaatsen, afhankelijk van uw valutanotatie en dit kan eenvoudig in de bovenstaande functie worden gewijzigd.

Zie ook:

  • Hulpprogramma:genereer PL/SQL-procedure om gegevens uit een tabel in 2 minuten te exporteren
  1. Hash join in Oracle met voorbeeld

  2. Entity Framework 6 transactie terugdraaien

  3. MySQL-gebruikersrechten op gedeelde servers

  4. Hoe SQL Developer op een Mac te installeren