oracle / node-oracledb

Oracle Database driver for Node.js maintained by Oracle Corp.
http://oracle.github.io/node-oracledb/
Other
2.24k stars 1.07k forks source link

Associative Arrays are converted into arrays but incorrectly. Perhaps they could be converted into objects? #1627

Closed marianc000 closed 3 months ago

marianc000 commented 7 months ago

Hello

I am using oracledb 6.2.0. Your library is a very helpful and powerful tool. But there is a limitation. Associative arrays in javascript are more similar to objects. They can be represented as arrays when they are indexed by pls_integer but when the library converts an associative array into a javascript array, the keys are disregarded.

For example

CREATE OR REPLACE PACKAGE PKG AUTHID DEFINER AS
  TYPE IAT IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
  FUNCTION F  RETURN IAT;
END;

CREATE OR REPLACE PACKAGE BODY PKG  AS
FUNCTION F  RETURN IAT IS
  R IAT;
  BEGIN
    R(2):=22;
    R(5):=55;
   RETURN R;
  END ;
END PKG ;
    const r = await connection.execute(
        `BEGIN
           :ret := pkg.f;
         END;`,
        {
            ret: {
                dir: oracledb.BIND_OUT,
                type: "PKG.IAT"
            }
        });

    for (const o of r.outBinds.ret) {
        console.log(o);
    }

The result is: 22 55

But it should be undefined 22 undefined undefined 55

Or even better it could by an object {2: 22, 5: 55}

This limitation makes library not useful for work with associative arrays.

The keys are present in the source data image So it could be a great improvement with a minor change in the code.

Thank you Best regards, Marian

sudarshan12s commented 7 months ago

Thanks for the details. We are checking and will update.

sudarshan12s commented 7 months ago

@marianc000 For the object which is a collection of such key/values, Does the below code work for you? The iterable object returned from such collection is an array of values today and a new API might be needed to retain the existing behaviour.

const iat = r.outBinds.ret;
 for (const key of iat.getKeys()) {
         console.log(`${key}: ${iat[key]}`);
 } 

o/p:

2: 22
5: 55

or you can retrieve iat.getKeys() for keys and iat.getValues for values.

sharadraju commented 7 months ago

@marianc000 Request you to please try @sudarshan12s's suggestion from the comment above.

sharadraju commented 3 months ago

@marianc000 This has been fixed as part of node-oracledb 6.4. The fix is available here.