Search code examples
jsonplsqlfloating-pointoracle-apexoracle-xe

Reserve Number Format from Original JSON Data


I am using Oracle Apex 22.2 and Oracle Database XE 21c on CentOS7. I am traversing all the nested elements of JSON data with the procedure shown below. However when I get the value of a number, the number loses its original format. For example, instead of getting 100.0, I get 100. How can I reserve the original format of the number? As you can see in my code below, I am using to_String to get value of the number. This is was one of my attempts to reserve the original number format. I have also tried with TO_CHAR & TO_NUMBER() . All give the same output. Your help is really appreciated.

Procedure Code

create or replace PROCEDURE ETA_JSON_SERIALIZE (
  json_in    IN     JSON_ELEMENT_T,
  can_str    IN OUT VARCHAR2,
  object_key IN     VARCHAR2 DEFAULT NULL
)
IS
BEGIN
  IF json_in.is_Object() THEN
    DECLARE
      l_object JSON_OBJECT_T := TREAT(json_in AS JSON_OBJECT_T);
      l_keys   JSON_KEY_LIST := l_object.get_Keys();
    BEGIN
      FOR i IN 1 .. l_keys.COUNT LOOP
        can_str := can_str || '"'||UPPER(l_keys(i))||'"';
        ETA_JSON_SERIALIZE(l_object.get(l_keys(i)), can_str, l_keys(i));
      END LOOP;
    END;
  ELSIF json_in.is_Array() THEN
    DECLARE
      l_array JSON_ARRAY_T := TREAT(json_in AS JSON_ARRAY_T);
    BEGIN
      FOR i IN 0 .. l_array.get_size - 1 LOOP
        IF object_key IS NOT NULL THEN
          can_str := can_str || '"'||UPPER(object_key)||'"';
        END IF;
        ETA_JSON_SERIALIZE(l_array.get(i), can_str);
      END LOOP;
    END;
  ELSIF json_in.is_Scalar() THEN
    IF json_in.is_String() THEN
        can_str := can_str || json_in.to_String();
    ELSIF json_in.is_Number() THEN
        can_str := can_str || '"' || TO_NUMBER(json_in.to_String) || '"';
    END IF;
  END IF;
END;

Sample Code - PL/SQL Block

SET SERVEROUTPUT ON
DECLARE
   can_str     VARCHAR2(32767);
   l_doc       CLOB := '{
    "issuer": {
        "address": {
            "branchID": "1",
            "country": "EG",
            "governate": "Cairo",
            "regionCity": "Nasr City",
            "street": "580 Clementina Key",
            "buildingNumber": "Bldg. 0",
            "postalCode": "68030",
            "floor": "1",
            "room": "123",
            "landmark": "7660 Melody Trail",
            "additionalInformation": "beside Townhall"
        },
        "type": "B",
        "id": "113317713",
        "name": "Issuer Company"
    },
    "receiver": {
        "address": {
            "country": "EG",
            "governate": "Egypt",
            "regionCity": "Mufazat al Ismlyah",
            "street": "580 Clementina Key",
            "buildingNumber": "Bldg. 0",
            "postalCode": "68030",
            "floor": "1",
            "room": "123",
            "landmark": "7660 Melody Trail",
            "additionalInformation": "beside Townhall"
        },
        "type": "B",
        "id": "313717919",
        "name": "Receiver"
    },
    "documentType": "I",
    "documentTypeVersion": "0.9",
    "dateTimeIssued": "2020-10-27T23:59:59Z",
    "taxpayerActivityCode": "4620",
    "internalID": "IID1",
    "purchaseOrderReference": "P-233-A6375",
    "purchaseOrderDescription": "purchase Order description",
    "salesOrderReference": "1231",
    "salesOrderDescription": "Sales Order description",
    "proformaInvoiceNumber": "SomeValue",
    "payment": {
        "bankName": "SomeValue",
        "bankAddress": "SomeValue",
        "bankAccountNo": "SomeValue",
        "bankAccountIBAN": "",
        "swiftCode": "",
        "terms": "SomeValue"
    },
    "delivery": {
        "approach": "SomeValue",
        "packaging": "SomeValue",
        "dateValidity": "2020-09-28T09:30:10Z",
        "exportPort": "SomeValue",
        "countryOfOrigin": "EG",
        "grossWeight": 10.50,
        "netWeight": 20.50,
        "terms": "SomeValue"
    },
    "invoiceLines": [
        {
            "description": "Computer1",
            "itemType": "GPC",
            "itemCode": "10001774",
            "unitType": "EA",
            "quantity": 5,
            "internalCode": "IC0",
            "salesTotal": 947.00,
            "total": 2969.89,
            "valueDifference": 7.00,
            "totalTaxableFees": 817.42,
            "netTotal": 880.71,
            "itemsDiscount": 5.00,
            "unitValue": {
                "currencySold": "EUR",
                "amountEGP": 189.40,
                "amountSold": 10.00,
                "currencyExchangeRate": 18.94
            },
            "discount": {
                "rate": 7,
                "amount": 66.29
            },
            "taxableItems": [
                {
                    "taxType": "T1",
                    "amount": 272.07,
                    "subType": "T1",
                    "rate": 14.00
                },
                {
                    "taxType": "T2",
                    "amount": 208.22,
                    "subType": "T2",
                    "rate": 12
                },
                {
                    "taxType": "T3",
                    "amount": 30.00,
                    "subType": "T3",
                    "rate": 0.00
                },
                {
                    "taxType": "T4",
                    "amount": 43.79,
                    "subType": "T4",
                    "rate": 5.00
                },
                {
                    "taxType": "T5",
                    "amount": 123.30,
                    "subType": "T5",
                    "rate": 14.00
                },
                {
                    "taxType": "T6",
                    "amount": 60.00,
                    "subType": "T6",
                    "rate": 0.00
                },
                {
                    "taxType": "T7",
                    "amount": 88.07,
                    "subType": "T7",
                    "rate": 10.00
                },
                {
                    "taxType": "T8",
                    "amount": 123.30,
                    "subType": "T8",
                    "rate": 14.00
                },
                {
                    "taxType": "T9",
                    "amount": 105.69,
                    "subType": "T9",
                    "rate": 12.00
                },
                {
                    "taxType": "T10",
                    "amount": 88.07,
                    "subType": "T10",
                    "rate": 10.00
                },
                {
                    "taxType": "T11",
                    "amount": 123.30,
                    "subType": "T11",
                    "rate": 14.00
                },
                {
                    "taxType": "T12",
                    "amount": 105.69,
                    "subType": "T12",
                    "rate": 12.00
                },
                {
                    "taxType": "T13",
                    "amount": 88.07,
                    "subType": "T13",
                    "rate": 10.00
                },
                {
                    "taxType": "T14",
                    "amount": 123.30,
                    "subType": "T14",
                    "rate": 14.00
                },
                {
                    "taxType": "T15",
                    "amount": 105.69,
                    "subType": "T15",
                    "rate": 12.00
                },
                {
                    "taxType": "T16",
                    "amount": 88.07,
                    "subType": "T16",
                    "rate": 10.00
                },
                {
                    "taxType": "T17",
                    "amount": 88.07,
                    "subType": "T17",
                    "rate": 10.00
                },
                {
                    "taxType": "T18",
                    "amount": 123.30,
                    "subType": "T18",
                    "rate": 14.00
                },
                {
                    "taxType": "T19",
                    "amount": 105.69,
                    "subType": "T19",
                    "rate": 12.00
                },
                {
                    "taxType": "T20",
                    "amount": 88.07,
                    "subType": "T20",
                    "rate": 10.00
                }
            ]
        },
        {
            "description": "Computer2",
            "itemType": "GPC",
            "itemCode": "10003752",
            "unitType": "EA",
            "quantity": 7,
            "internalCode": "IC0",
            "salesTotal": 662.90,
            "total": 2226.61,
            "valueDifference": 6.00,
            "totalTaxableFees": 621.51,
            "netTotal": 652.90,
            "itemsDiscount": 9.00,
            "unitValue": {
                "currencySold": "EUR",
                "amountEGP": 94.70,
                "amountSold": 5.00,
                "currencyExchangeRate": 18.94
            },
            "discount": {
                "rate": 0,
                "amount": 10.00
            },
            "taxableItems": [
                {
                    "taxType": "T1",
                    "amount": 205.47,
                    "subType": "T1",
                    "rate": 14.00
                },
                {
                    "taxType": "T2",
                    "amount": 157.25,
                    "subType": "T2",
                    "rate": 12
                },
                {
                    "taxType": "T3",
                    "amount": 30.00,
                    "subType": "T3",
                    "rate": 0.00
                },
                {
                    "taxType": "T4",
                    "amount": 32.20,
                    "subType": "T4",
                    "rate": 5.00
                },
                {
                    "taxType": "T5",
                    "amount": 91.41,
                    "subType": "T5",
                    "rate": 14.00
                },
                {
                    "taxType": "T6",
                    "amount": 60.00,
                    "subType": "T6",
                    "rate": 0.00
                },
                {
                    "taxType": "T7",
                    "amount": 65.29,
                    "subType": "T7",
                    "rate": 10.00
                },
                {
                    "taxType": "T8",
                    "amount": 91.41,
                    "subType": "T8",
                    "rate": 14.00
                },
                {
                    "taxType": "T9",
                    "amount": 78.35,
                    "subType": "T9",
                    "rate": 12.00
                },
                {
                    "taxType": "T10",
                    "amount": 65.29,
                    "subType": "T10",
                    "rate": 10.00
                },
                {
                    "taxType": "T11",
                    "amount": 91.41,
                    "subType": "T11",
                    "rate": 14.00
                },
                {
                    "taxType": "T12",
                    "amount": 78.35,
                    "subType": "T12",
                    "rate": 12.00
                },
                {
                    "taxType": "T13",
                    "amount": 65.29,
                    "subType": "T13",
                    "rate": 10.00
                },
                {
                    "taxType": "T14",
                    "amount": 91.41,
                    "subType": "T14",
                    "rate": 14.00
                },
                {
                    "taxType": "T15",
                    "amount": 78.35,
                    "subType": "T15",
                    "rate": 12.00
                },
                {
                    "taxType": "T16",
                    "amount": 65.29,
                    "subType": "T16",
                    "rate": 10.00
                },
                {
                    "taxType": "T17",
                    "amount": 65.29,
                    "subType": "T17",
                    "rate": 10.00
                },
                {
                    "taxType": "T18",
                    "amount": 91.41,
                    "subType": "T18",
                    "rate": 14.00
                },
                {
                    "taxType": "T19",
                    "amount": 78.35,
                    "subType": "T19",
                    "rate": 12.00
                },
                {
                    "taxType": "T20",
                    "amount": 65.29,
                    "subType": "T20",
                    "rate": 10.00
                }
            ]
        }
    ],
    "totalDiscountAmount": 76.29,
    "totalSalesAmount": 1609.90,
    "netAmount": 1533.61,
    "taxTotals": [
        {
            "taxType": "T1",
            "amount": 477.54
        },
        {
            "taxType": "T2",
            "amount": 365.47
        },
        {
            "taxType": "T3",
            "amount": 60.00
        },
        {
            "taxType": "T4",
            "amount": 75.99
        },
        {
            "taxType": "T5",
            "amount": 214.71
        },
        {
            "taxType": "T6",
            "amount": 120.00
        },
        {
            "taxType": "T7",
            "amount": 153.36
        },
        {
            "taxType": "T8",
            "amount": 214.71
        },
        {
            "taxType": "T9",
            "amount": 184.04
        },
        {
            "taxType": "T10",
            "amount": 153.36
        },
        {
            "taxType": "T11",
            "amount": 214.71
        },
        {
            "taxType": "T12",
            "amount": 184.04
        },
        {
            "taxType": "T13",
            "amount": 153.36
        },
        {
            "taxType": "T14",
            "amount": 214.71
        },
        {
            "taxType": "T15",
            "amount": 184.04
        },
        {
            "taxType": "T16",
            "amount": 153.36
        },
        {
            "taxType": "T17",
            "amount": 153.36
        },
        {
            "taxType": "T18",
            "amount": 214.71
        },
        {
            "taxType": "T19",
            "amount": 184.04
        },
        {
            "taxType": "T20",
            "amount": 153.36
        }
    ],
    "totalAmount": 5191.50,
    "extraDiscountAmount": 5.00,
    "totalItemsDiscountAmount": 14.00
}';

BEGIN 
   ETA_JSON_SERIALIZE(JSON_ELEMENT_T.parse( l_doc ), can_str);
   DBMS_OUTPUT.PUT_LINE(can_str);
END;
/

Output

"ISSUER""ADDRESS""BRANCHID""1""COUNTRY""EG""GOVERNATE""Cairo""REGIONCITY""Nasr City""STREET""580 Clementina Key""BUILDINGNUMBER""Bldg. 0""POSTALCODE""68030""FLOOR""1""ROOM""123""LANDMARK""7660 Melody Trail""ADDITIONALINFORMATION""beside Townhall""TYPE""B""ID""113317713""NAME""Issuer Company""RECEIVER""ADDRESS""COUNTRY""EG""GOVERNATE""Egypt""REGIONCITY""Mufazat al Ismlyah""STREET""580 Clementina Key""BUILDINGNUMBER""Bldg. 0""POSTALCODE""68030""FLOOR""1""ROOM""123""LANDMARK""7660 Melody Trail""ADDITIONALINFORMATION""beside Townhall""TYPE""B""ID""313717919""NAME""Receiver""DOCUMENTTYPE""I""DOCUMENTTYPEVERSION""0.9""DATETIMEISSUED""2020-10-27T23:59:59Z""TAXPAYERACTIVITYCODE""4620""INTERNALID""IID1""PURCHASEORDERREFERENCE""P-233-A6375""PURCHASEORDERDESCRIPTION""purchase Order description""SALESORDERREFERENCE""1231""SALESORDERDESCRIPTION""Sales Order description""PROFORMAINVOICENUMBER""SomeValue""PAYMENT""BANKNAME""SomeValue""BANKADDRESS""SomeValue""BANKACCOUNTNO""SomeValue""BANKACCOUNTIBAN""""SWIFTCODE""""TERMS""SomeValue""DELIVERY""APPROACH""SomeValue""PACKAGING""SomeValue""DATEVALIDITY""2020-09-28T09:30:10Z""EXPORTPORT""SomeValue""COUNTRYOFORIGIN""EG""GROSSWEIGHT""10.5""NETWEIGHT""20.5""TERMS""SomeValue""INVOICELINES""INVOICELINES""DESCRIPTION""Computer1""ITEMTYPE""GPC""ITEMCODE""10001774""UNITTYPE""EA""QUANTITY""5""INTERNALCODE""IC0""SALESTOTAL""947""TOTAL""2969.89""VALUEDIFFERENCE""7""TOTALTAXABLEFEES""817.42""NETTOTAL""880.71""ITEMSDISCOUNT""5""UNITVALUE""CURRENCYSOLD""EUR""AMOUNTEGP""189.4""AMOUNTSOLD""10""CURRENCYEXCHANGERATE""18.94""DISCOUNT""RATE""7""AMOUNT""66.29""TAXABLEITEMS""TAXABLEITEMS""TAXTYPE""T1""AMOUNT""272.07""SUBTYPE""T1""RATE""14""TAXABLEITEMS""TAXTYPE""T2""AMOUNT""208.22""SUBTYPE""T2""RATE""12""TAXABLEITEMS""TAXTYPE""T3""AMOUNT""30""SUBTYPE""T3""RATE""0""TAXABLEITEMS""TAXTYPE""T4""AMOUNT""43.79""SUBTYPE""T4""RATE""5""TAXABLEITEMS""TAXTYPE""T5""AMOUNT""123.3""SUBTYPE""T5""RATE""14""TAXABLEITEMS""TAXTYPE""T6""AMOUNT""60""SUBTYPE""T6""RATE""0""TAXABLEITEMS""TAXTYPE""T7""AMOUNT""88.07""SUBTYPE""T7""RATE""10""TAXABLEITEMS""TAXTYPE""T8""AMOUNT""123.3""SUBTYPE""T8""RATE""14""TAXABLEITEMS""TAXTYPE""T9""AMOUNT""105.69""SUBTYPE""T9""RATE""12""TAXABLEITEMS""TAXTYPE""T10""AMOUNT""88.07""SUBTYPE""T10""RATE""10""TAXABLEITEMS""TAXTYPE""T11""AMOUNT""123.3""SUBTYPE""T11""RATE""14""TAXABLEITEMS""TAXTYPE""T12""AMOUNT""105.69""SUBTYPE""T12""RATE""12""TAXABLEITEMS""TAXTYPE""T13""AMOUNT""88.07""SUBTYPE""T13""RATE""10""TAXABLEITEMS""TAXTYPE""T14""AMOUNT""123.3""SUBTYPE""T14""RATE""14""TAXABLEITEMS""TAXTYPE""T15""AMOUNT""105.69""SUBTYPE""T15""RATE""12""TAXABLEITEMS""TAXTYPE""T16""AMOUNT""88.07""SUBTYPE""T16""RATE""10""TAXABLEITEMS""TAXTYPE""T17""AMOUNT""88.07""SUBTYPE""T17""RATE""10""TAXABLEITEMS""TAXTYPE""T18""AMOUNT""123.3""SUBTYPE""T18""RATE""14""TAXABLEITEMS""TAXTYPE""T19""AMOUNT""105.69""SUBTYPE""T19""RATE""12""TAXABLEITEMS""TAXTYPE""T20""AMOUNT""88.07""SUBTYPE""T20""RATE""10""INVOICELINES""DESCRIPTION""Computer2""ITEMTYPE""GPC""ITEMCODE""10003752""UNITTYPE""EA""QUANTITY""7""INTERNALCODE""IC0""SALESTOTAL""662.9""TOTAL""2226.61""VALUEDIFFERENCE""6""TOTALTAXABLEFEES""621.51""NETTOTAL""652.9""ITEMSDISCOUNT""9""UNITVALUE""CURRENCYSOLD""EUR""AMOUNTEGP""94.7""AMOUNTSOLD""5""CURRENCYEXCHANGERATE""18.94""DISCOUNT""RATE""0""AMOUNT""10""TAXABLEITEMS""TAXABLEITEMS""TAXTYPE""T1""AMOUNT""205.47""SUBTYPE""T1""RATE""14""TAXABLEITEMS""TAXTYPE""T2""AMOUNT""157.25""SUBTYPE""T2""RATE""12""TAXABLEITEMS""TAXTYPE""T3""AMOUNT""30""SUBTYPE""T3""RATE""0""TAXABLEITEMS""TAXTYPE""T4""AMOUNT""32.2""SUBTYPE""T4""RATE""5""TAXABLEITEMS""TAXTYPE""T5""AMOUNT""91.41""SUBTYPE""T5""RATE""14""TAXABLEITEMS""TAXTYPE""T6""AMOUNT""60""SUBTYPE""T6""RATE""0""TAXABLEITEMS""TAXTYPE""T7""AMOUNT""65.29""SUBTYPE""T7""RATE""10""TAXABLEITEMS""TAXTYPE""T8""AMOUNT""91.41""SUBTYPE""T8""RATE""14""TAXABLEITEMS""TAXTYPE""T9""AMOUNT""78.35""SUBTYPE""T9""RATE""12""TAXABLEITEMS""TAXTYPE""T10""AMOUNT""65.29""SUBTYPE""T10""RATE""10""TAXABLEITEMS""TAXTYPE""T11""AMOUNT""91.41""SUBTYPE""T11""RATE""14""TAXABLEITEMS""TAXTYPE""T12""AMOUNT""78.35""SUBTYPE""T12""RATE""12""TAXABLEITEMS""TAXTYPE""T13""AMOUNT""65.29""SUBTYPE""T13""RATE""10""TAXABLEITEMS""TAXTYPE""T14""AMOUNT""91.41""SUBTYPE""T14""RATE""14""TAXABLEITEMS""TAXTYPE""T15""AMOUNT""78.35""SUBTYPE""T15""RATE""12""TAXABLEITEMS""TAXTYPE""T16""AMOUNT""65.29""SUBTYPE""T16""RATE""10""TAXABLEITEMS""TAXTYPE""T17""AMOUNT""65.29""SUBTYPE""T17""RATE""10""TAXABLEITEMS""TAXTYPE""T18""AMOUNT""91.41""SUBTYPE""T18""RATE""14""TAXABLEITEMS""TAXTYPE""T19""AMOUNT""78.35""SUBTYPE""T19""RATE""12""TAXABLEITEMS""TAXTYPE""T20""AMOUNT""65.29""SUBTYPE""T20""RATE""10""TOTALDISCOUNTAMOUNT""76.29""TOTALSALESAMOUNT""1609.9""NETAMOUNT""1533.61""TAXTOTALS""TAXTOTALS""TAXTYPE""T1""AMOUNT""477.54""TAXTOTALS""TAXTYPE""T2""AMOUNT""365.47""TAXTOTALS""TAXTYPE""T3""AMOUNT""60""TAXTOTALS""TAXTYPE""T4""AMOUNT""75.99""TAXTOTALS""TAXTYPE""T5""AMOUNT""214.71""TAXTOTALS""TAXTYPE""T6""AMOUNT""120""TAXTOTALS""TAXTYPE""T7""AMOUNT""153.36""TAXTOTALS""TAXTYPE""T8""AMOUNT""214.71""TAXTOTALS""TAXTYPE""T9""AMOUNT""184.04""TAXTOTALS""TAXTYPE""T10""AMOUNT""153.36""TAXTOTALS""TAXTYPE""T11""AMOUNT""214.71""TAXTOTALS""TAXTYPE""T12""AMOUNT""184.04""TAXTOTALS""TAXTYPE""T13""AMOUNT""153.36""TAXTOTALS""TAXTYPE""T14""AMOUNT""214.71""TAXTOTALS""TAXTYPE""T15""AMOUNT""184.04""TAXTOTALS""TAXTYPE""T16""AMOUNT""153.36""TAXTOTALS""TAXTYPE""T17""AMOUNT""153.36""TAXTOTALS""TAXTYPE""T18""AMOUNT""214.71""TAXTOTALS""TAXTYPE""T19""AMOUNT""184.04""TAXTOTALS""TAXTYPE""T20""AMOUNT""153.36""TOTALAMOUNT""5191.5""EXTRADISCOUNTAMOUNT""5""TOTALITEMSDISCOUNTAMOUNT""14"

Output Instances How to make it reserve the original number format? So "EXTRADISCOUNTAMOUNT""5.00"instead of"EXTRADISCOUNTAMOUNT""5"`

OR

"NETWEIGHT""20.50" instead of "NETWEIGHT""20.5"

OR

"TOTALITEMSDISCOUNTAMOUNT""14.00" instead of "TOTALITEMSDISCOUNTAMOUNT""14"

OR

"RATE""0.00" instead of "RATE""0"


Solution

  • You cannot.

    Once you have parsed the JSON then Oracle has converted it to JSON_ELEMENT_T then there is no documented method that allows you to extract the underlying JSON text for that element so you can only use the serialization methods:

    Serialization

    Serialization is the inverse of the parse function. The serialization operation takes the in-memory representation of the JSON data and prints it to a string. The serialization functions and procedures are:

    MEMBER FUNCTION to_String    RETURN VARCHAR2
    MEMBER FUNCTION to_Number    RETURN NUMBER
    MEMBER FUNCTION to_Date      RETURN DATE
    MEMBER FUNCTION to_Timestamp RETURN TIMESTAMP
    MEMBER FUNCTION to_Boolean   RETURN BOOLEAN
    MEMBER FUNCTION to_Clob      RETURN CLOB
    MEMBER FUNCTION to_Blob      RETURN BLOB
    
    MEMBER PROCEDURE to_Clob(c IN OUT CLOB)
    MEMBER PROCEDURE to_Blob(c IN OUT BLOB)
    

    As noted in the documentation, "The serialization operation takes the in-memory representation of the JSON data and ...". Therefore if the parser converts the JSON to a NUMBER data type then only a NUMBER value will be stored and the formatting of the original JSON text is NOT stored. Since 10.00 is exactly the same value as 10 and a NUMBER does not store formatting then you can only retrieve the value 10 and not 10.00.


    If you want to get the original text then you will have to use a different parser that lets you extract the underlying JSON text.


    Alternatively, if all the numbers want to be formatted to 2 decimal places then you could use:

    can_str := can_str || '"' || TO_CHAR(json_in.to_Number(), 'FM9999990D00') || '"';
    

    fiddle