Open mostafa-gado opened 1 year ago
Thanks for reporting the issue. We are looking into it.
Note that the default behavior after node-oracledb 6.0 is the Thin mode.
So unless you have called initOracleClient()
, the program will invoke the Thin mode of node-oracledb.
@mostafa-gado The parameter 2 qty: "1"
in your bind variables array dummyItems
is assigned a string instead of a NUMBER.
Please change this to qty: 1
as qty is a NUMBER.
Please specify the exact INSERT statement that you used, which ran correctly. Does it have the same bind values?
Did you run the INSERT statement in a Node.js program or as a separate SQL?
@mostafa-gado since you have binds with input and output, Can you provide bindDefs
something like this.
const dummyItems = [
{
sale_cont_no: 10274,
item_no: 328,
qty: 1,
item_price: 10274,
disc_percentage: 0,
disc_amount: 0,
price_after_disc: 12,
total_price: 12,
comments: "xyz",
rec_user: 42,
upd_user: 42
},
];
const options = {
bindDefs: {
sale_cont_no: { dir: oracledb.BIND_IN, type: oracledb.NUMBER},
item_no: { dir: oracledb.BIND_IN, type: oracledb.NUMBER },
qty: { dir: oracledb.BIND_IN, type: oracledb.NUMBER},
item_price: { dir: oracledb.BIND_IN, type: oracledb.NUMBER},
disc_percentage: { dir: oracledb.BIND_IN, type: oracledb.NUMBER},
disc_amount: { dir: oracledb.BIND_IN, type: oracledb.NUMBER},
price_after_disc: { dir: oracledb.BIND_IN, type: oracledb.NUMBER},
total_price: { dir: oracledb.BIND_IN, type: oracledb.NUMBER},
comments: { dir: oracledb.BIND_IN, type: oracledb.STRING, maxSize: 20},
rec_user: { dir: oracledb.BIND_IN, type: oracledb.NUMBER},
upd_user: { dir: oracledb.BIND_IN, type: oracledb.NUMBER},
R_STATE: { dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 200 }
}
};
result = await connection.executeMany(
contItemsSql,
dummyItems,
options
);
@sharadraju Yes I called initOracleClient()
@sudarshan12s Changing the qty to int doesn't solve the issue. I updated the post with the insert statement.
@sudarshan12s Using bindDefs raised a different error:
Error: Error: NJS-011: encountered bind value and type mismatch
at Object.throwErr (D:\Apps\ERP\etit-erp-backend\node_modules\oracledb\lib\errors.js:592:10)
at checkType (D:\Apps\ERP\etit-erp-backend\node_modules\oracledb\lib\transformer.js:71:16)
at Object.transformValueIn (D:\Apps\ERP\etit-erp-backend\node_modules\oracledb\lib\transformer.js:245:3)
at Connection._processBindValue (D:\Apps\ERP\etit-erp-backend\node_modules\oracledb\lib\connection.js:303:37)
at Connection._processExecuteManyBinds (D:\Apps\ERP\etit-erp-backend\node_modules\oracledb\lib\connection.js:454:20)
at async Connection.executeMany (D:\Apps\ERP\etit-erp-backend\node_modules\oracledb\lib\connection.js:936:15)
at async Connection.<anonymous> (D:\Apps\ERP\etit-erp-backend\node_modules\oracledb\lib\util.js:162:14)
at async createContractDb (D:\Apps\ERP\etit-erp-backend\db\sales\contractDb.js:313:31)
at async createContract (D:\Apps\ERP\etit-erp-backend\controllers\sales\contractController.js:60:18) {
code: 'NJS-011'
}
Can you give me the complete program or the executeMany arguments you passed. I passed same as in my comment, it works .
Above error can come if the bind values doesn't match the type mentioned in bindDefs like if we pass string but its type is defined asoracledb.NUMBER
qty: '1',
I modified your program to something like this which works. similar examples are in test folder
const myProc = `CREATE OR REPLACE PROCEDURE CR_CONTRACT_ITEM(
p_sale_cont_no IN NUMBER,
p_item_no IN NUMBER,
p_qty IN NUMBER,
p_item_price IN NUMBER,
p_disc_percentage IN NUMBER,
p_disc_amount IN NUMBER,
p_price_after_disc IN NUMBER,
p_total_price IN NUMBER,
p_comments IN VARCHAR2,
p_rec_user IN NUMBER,
p_upd_user IN NUMBER,
R_STATE OUT VARCHAR2
)
AS
BEGIN
R_STATE := 'OUTVAL';
END;`;
const contItemsSql = `BEGIN
CR_CONTRACT_ITEM(
:sale_cont_no,
:item_no,
:qty,
:item_price,
:disc_percentage,
:disc_amount,
:price_after_disc,
:total_price,
:comments,
:rec_user,
:upd_user,
:R_STATE
);
END;`;
const dummyItems = [
{
sale_cont_no: 10274,
item_no: 328,
qty: 1,
item_price: 10274,
disc_percentage: 0,
disc_amount: 0,
price_after_disc: 12,
total_price: 12,
comments: "xyz",
rec_user: 42,
upd_user: 42
},
];
const options = {
bindDefs: {
sale_cont_no: { dir: oracledb.BIND_IN, type: oracledb.NUMBER },
item_no: { dir: oracledb.BIND_IN, type: oracledb.NUMBER },
qty: { dir: oracledb.BIND_IN, type: oracledb.NUMBER },
item_price: { dir: oracledb.BIND_IN, type: oracledb.NUMBER },
disc_percentage: { dir: oracledb.BIND_IN, type: oracledb.NUMBER },
disc_amount: { dir: oracledb.BIND_IN, type: oracledb.NUMBER },
price_after_disc: { dir: oracledb.BIND_IN, type: oracledb.NUMBER },
total_price: { dir: oracledb.BIND_IN, type: oracledb.NUMBER },
comments: { dir: oracledb.BIND_IN, type: oracledb.STRING, maxSize: 20 },
rec_user: { dir: oracledb.BIND_IN, type: oracledb.NUMBER },
upd_user: { dir: oracledb.BIND_IN, type: oracledb.NUMBER },
R_STATE: { dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 200 }
}
};
//oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
async function run() {
let connection;
try {
connection = await oracledb.getConnection(dbConfig);
let result = await connection.execute(myProc);
result = await connection.executeMany(
contItemsSql,
dummyItems,
options
);
console.log("Query outbinds :", result.outBinds);
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
// Connections should always be released when not needed
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}
run();
@sudarshan12s Ok I found the issue. After carefully examining your code I noticed you are only adding the R_STATE definition in the bindDefs. But I was adding the R_STATE definition twice. Once in the dummyItems and again in the bindDefs. Once I removed it from the dummyItems It worked. Thanks!
I think I found some inconsistency between execute()
and executeMany()
. It seems that in executeMany()
you can't include the out params definition in the parameters passed to the function, And you must include them in options.bindDefs
.
But in execute()
you must include the out params in the params passed and you don't have to include them in options.bindDefs
.
Don't you think this is confusing?
Give your database version. Oracle Cloud ATP 21c
process.platform: 'win32' process.version: 'v18.12.1' process.arch: 'x64' require('oracledb').versionString: '6.0.3' require('oracledb').oracleClientVersionString: Uncaught: Error: NJS-089: getting the Oracle Client version is not supported by node-oracledb in Thin mode at throwErr (D:\Apps\ERP\etit-erp-backend\node_modules\oracledb\lib\errors.js:592:10) at Object.throwNotImplemented (D:\Apps\ERP\etit-erp-backend\node_modules\oracledb\lib\errors.js:601:3) at get oracleClientVersionString [as oracleClientVersionString] (D:\Apps\ERP\etit-erp-backend\node_modules\oracledb\lib\oracledb.js:1064:14) { code: 'NJS-089' }
But I am running in Thick mode!
Is it an error or a hang or a crash? Error
What error(s) or behavior you are seeing? Error: NJS-012: encountered invalid bind data type in parameter 2
I am trying to use executeMany to run a procedure in the database but I am getting this error "Error: NJS-012: encountered invalid bind data type in parameter 2".
The database proc:
The node.js code:
The strange thing is If I ran the same executeMany with the same parameters but instead of calling the proc I call the same insert statement, It works. The same insert statement that is inside the proc.
The insert statement as requested by @sudarshan12s :