Error: ORA-01008: not all variables bound - node.js

I have this error for a few hours and I can't identify the problem. Error: ORA-01008: not all variables bound.
Controller
async bipagem(req: Request, res: Response) {
try {
let credentials = super.openToken(req)
let { p_fil_filial, p_set_cdgo, p_mini_fab, p_codigo_barra } = req.query
let info = await this.rep.bipagem(
p_fil_filial as string,
p_set_cdgo as string,
p_mini_fab as string,
p_codigo_barra as string,
credentials as string
)
res.json(info)
} catch (error) {
catchErr(res, error)
}
}
}
Repository
public async bipagem(
p_fil_filial: string,
p_set_cdgo: string,
p_mini_fab: string,
p_codigo_barra: string,
userPool: string
) {
let conn
try {
conn = await connection(userPool)
const ret = await conn.execute(
`DECLARE
c_result SYS_REFCURSOR;
BEGIN
-- Call the function
:result := brio.pck_fab0024.bipagem(p_fil_filial => :p_fil_filial,
p_set_cdgo => :p_set_cdgo,
p_mini_fab => :p_mini_fab,
p_codigo_barra => :p_codigo_barra,
p_msg => :p_msg);
DBMS_SQL.RETURN_RESULT(c_result);
END;`,
{
p_fil_filial,
p_set_cdgo,
p_mini_fab,
p_codigo_barra,
p_msg: { type: oracledb.STRING, dir: oracledb.BIND_OUT }
}
)
return { ...(ret.outBinds as object), conteudo: ret.implicitResults[0] }
} catch (e) {
console.log('Erro na fab0024: ', e.message)
return {
p_fil_filial,
p_set_cdgo,
p_codigo_barra,
p_msg: '',
conteudo: []
}
} finally {
if (conn && typeof conn !== 'string') conn.close()
}
}
}
I tried to include the p_msg parameter and got this return error TS2339: Property 'bipagem' does not exist on type 'unknown'.

Your PL/SQL block has six bind parameters but you are passing only five values. Hence it is not a surprise that you get an error saying that one of the local variables isn't bound.
I think you have missed the fact that :result in the line below is also a bind parameter:
:result := brio.pck_fab0024.bipagem(p_fil_filial => :p_fil_filial,
I suspect you meant to assign the result to the local variable c_result (to which you don't currently assign any value) instead of an extra bind parameter:
c_result := brio.pck_fab0024.bipagem(p_fil_filial => :p_fil_filial,

Related

ERROR ORA-01008 using nodeOracledb with TS

i have one problem in result of my code, i tring consult one script ORACLE with nodejs using TS but i don't know why this error apear in my console i tring many ways to fix this error and i can't fix them, i hope your can help me whit this, bellow follow my code and screenshot of my error.
Controller
async bipagem(req: Request, res: Response) {
try {
let credentials = super.openToken(req);
let { p_fil_filial, p_set_cdgo, p_mini_fab, p_codigo_barra } = req.query;
let info = await this.rep.bipagem(
p_fil_filial as string,
p_set_cdgo as string,
p_mini_fab as string,
p_codigo_barra as string,
credentials as string
);
res.json(info);
} catch (error) {
catchErr(res, error);
}
}
Repository
public async bipagem(
p_fil_filial: string,
p_set_cdgo: string,
p_mini_fab: string,
p_codigo_barra: string,
userPool: string
) {
let conn;
try {
conn = await connection(userPool);
const resultado = await conn.execute(
`DECLARE
result SYS_REFCURSOR;
BEGIN
-- Call the function
:result := brio.pck_fab0024.bipagem(p_fil_filial => :p_fil_filial,
p_set_cdgo => :p_set_cdgo,
p_mini_fab => :p_mini_fab,
p_codigo_barra => :p_codigo_barra,
p_msg => :p_msg);
END;`,
{
p_fil_filial,
p_set_cdgo,
p_mini_fab,
p_codigo_barra,
p_msg: { type: oracledb.STRING, dir: oracledb.BIND_OUT },
}
);
return resultado;
} catch (erro) {
console.log(erro);
} finally {
if (conn) conn.close();
}
}
Screenshot error
ORA-01008 means "not all variables bound". It looks like you have 6 variables in your PL/SQL block, but only 5 variables that are assigned to those. :result is not bound.

How can I convert from a firebase document to a custom class in Node JS

In node.js I'm getting the error below. Any ideas why?
Conversion of type 'Promise' to type 'Member[]' may be a mistake
because neither type sufficiently overlaps with the other. If this was
intentional, convert the expression to 'unknown' first. Type
'Promise' is missing the following properties from type
'Member[]': length, pop, push, concat, and 26 more.
export async function getFamilyMembers(tenantId: string, familyCode: string): Promise<Member[]> {
return db.collection(`tenants/${tenantId}/members`)
.where('familyCode', '==', familyCode)
.get()
.then(snaps => {
snaps.docs.forEach(doc => {
return { id: doc.id, ...doc.data()}
});
}) as Member[];
}
EDIT:
If I remove the types and change it to
export async function getFamilyMembers(tenantId: string, familyCode: string) {
return db.collection(`tenants/${tenantId}/members`)
.where('familyCode', '==', familyCode)
.get()
.then(snaps => {
snaps.docs.forEach(doc => {
return { id: doc.id, ...doc.data()}
});
});
}
I just have to deal with the problem later.
I get the error
Property 'length' does not exist on type 'void'.
const familyMembers: Member[] | void = await getFamilyMembers(tenantId, familyCode);
if (familyMembers === null) {
isVerified = false;
verificationFailMessage = `Sorry we can't find this code. Please check it is correct.`;
} else if (familyMembers.length === 0) {
I needed to add Promise in front of Member.
export async function getFamilyMembers(tenantId: string, familyCode: string): Promise<Member[]> {
return db.collection(`tenants/${tenantId}/members`)
.where('familyCode', '==', familyCode)
.get()
.then(snaps => {
snaps.docs.forEach(doc => {
return { id: doc.id, ...doc.data()}
});
}) as Promise<Member[]>;
}

This expression is not callable. Type 'string' has no call signatures

I'm trying to create a template file from an object where the key can be either a string or a function that returns a string:
export const createDynamicTemplate = (
templateParams: CreateDynamicTemplateParams
) => {
const { template, projectPath = '', param = '' } = templateParams
const updatedTemplateArr = Object.keys(template).map((key: string) => {
return {
[key]: {
filePath: `${projectPath}/${key}`,
template: typeof template[key] === 'function' ?
template[key](param) : template[key],
},
}
})
const updatedTemplate = Object.assign({}, ...updatedTemplateArr)
return updatedTemplate
}
My interfaces are:
export interface TemplateObject {
[key: string]: string
}
export interface FunctionalTemplateObject {
[key: string]: (param: string) => void
}
export interface CreateDynamicTemplateParams {
template: FunctionalTemplateObject | TemplateObject
projectPath: string
param: string
}
It keeps throwing this error in createDynamicTemplate though:
This expression is not callable.
Not all constituents of type 'string | ((param: string) => void)' are callable.
Type 'string' has no call signatures.
What am I doing wrong here?
Checking the type of a child property of a variable which references an object will not narrow the type of the variable-object. You can save the value at the key in a separate variable first, then check that value to narrow its type:
const updatedTemplateArr = Object.keys(template).map((key: string) => {
const item = template[key];
if (typeof item === 'function') {
return {
[key]: {
filePath: `${projectPath}/${key}`,
template: item(param),
},
}
}
})
Or, even better, use Object.entries to get the key and value at once. (Also note that there's no need to note the type of the .map parameters - TS can infer it automatically just fine)
const updatedTemplateArr = Object.entries(template).map(([key, value]) => {
if (typeof value === 'function') {
return {
[key]: {
filePath: `${projectPath}/${key}`,
template: value(param),
},
}
}
})

this is unset inside a function method when decorators are applied

I'm writing decorators for the following class method:
export default class API {
...
public async request(url_stub: string, options: any = {}): Promise<any> {
console.log(this)
const url = this.join_url(url_stub);
...
}
}
The functions run as expected when no decorators are applied, but when I apply one of the following decorators:
export function log_func(_target: any,
name: string,
descriptor: PropertyDescriptor): PropertyDescriptor {
const original_function = descriptor.value;
descriptor.value = (... args: any[]) => {
const parameters = args.map((a) => JSON.stringify(a)).join();
const result = original_function.apply(this, args);
const result_str = JSON.stringify(result);
console.log(`Call: ${name}(${parameters}) => ${result_str}`);
return result;
}
return descriptor;
}
export function uri_encode(parameter_index?: number) {
return (_target: any,
name: string,
descriptor: PropertyDescriptor): PropertyDescriptor => {
const original_function = descriptor.value;
descriptor.value = (... args: any[]) => {
args = args.map((arg, index) => {
if (parameter_index === undefined || index === parameter_index) {
arg = encodeURI(arg);
}
return arg;
});
const result = original_function.apply(this, args);
return result;
}
return descriptor;
}
}
as such:
#uri_encode(0)
#log_func
public async request(url_stub: string, options: any = {}): Promise<any> {
this inside the class method is now undefined. I'm guessing this is because the method is technically being called from outside the context of the class.
Is there a flaw in my design, or is this what I should expect? If so is there a way for me to retain the context while still using decorators?
The problem was in my decorator. Apparently modifying the original descriptor value with a () => {} function was the problem. Changing it to function () {} made it work.
God knows why.

node-oracledb giving Error: NJS-044: named JSON object is not expected in this context while executing stored procedure

I am facing an issue to call oracle db stored procedure using node-oracledb npm ("oracledb": "^3.1.2") and ("#types/oracledb": "^3.1.0") into node.js application. The stored procedure takes 3 input paramters of type string, string and array of oracleDB type respectively. However, while passing last parameter of DB type, node.js application throws an exception of "NJS-044: named JSON object is not expected in this context".
// DB payload
let obj = {
tableOwner: 'Mr X',
tableName: 'Demo',
retentionData: this.CreateArrayFromJSONObject(array_of_data)
}
// DB procedure
let procedure: string = `BEGIN PKG_ARCHIVAL_TOOL.P_RETENTION_POLICY_CREATE(:tableOwner, :tableName, :retentionData); END;`;
/// DB execution function call
DBService.getInstance().ExecuteDBProcedureRequest(procedure, userPolicyJSON);
// DB executing
public ExecuteDBProcedureRequest = (procedure: string, inputBody: any) : Promise<any> => {
return new Promise((resolve, reject) => {
DBConn.execute(procedure, inputBody, { autoCommit: true}, (err: oracledb.DBError, result: oracledb.Result) => {
if(err) {
reject(err);
}
if(result) {
resolve(Utils.CreateJSONObject(result));
}
})
});
}
// SQL procedure call
PKG_ARCHIVAL_TOOL.P_RETENTION_POLICY_CREATE(
P_TABLE_OWNER => P_TABLE_OWNER,
P_TABLE_NAME => P_TABLE_NAME,
P_RETEN_DATA => V_DATA,
P_ID => V_ID,
P_OUT => V_OUT
);
P_RETEN_DATA is a table of a record:-
Record - TYPE R_RETENTION_POLICY_DEF IS RECORD(
COLUMN_NAME VARCHAR2(40) NOT NULL DEFAULT ' ',
COLUMN_POS NUMBER NOT NULL DEFAULT 1,
COLUMN_TYPE VARCHAR2(10) NOT NULL DEFAULT 'NUMBER',
OPERATOR VARCHAR2(10) NOT NULL DEFAULT '=',
GATE VARCHAR2(10) DEFAULT NULL,
BRAC_ST NUMBER DEFAULT 0,
BRAC_ED NUMBER DEFAULT 0
);
Table :- TYPE T_RETENTION_POLICY_DEF IS TABLE OF R_RETENTION_POLICY_DEF;
array_of_data = [["FNAME, 1, "VARCHAR2", ">", "OR", 0, 0], ["LNAME, 1, "VARCHAR2", "=", "AND", 0, 0]]
Binding to a record will only work in node-oracledb 4, which is under development here.
Your code may also have other issues (number of parameters in the PL/SQL call, trying to pass some kind of array? to a record etc).
The general solution with node-oracledb 3.1 is to use a wrapper PL/SQL block that you can bind permissible types into. This wrapper block then massages the values into a record and calls your target procedure, P_RETENTION_POLICY_CREATE.
Given this SQL:
set echo on
create or replace package rectest as
type rectype is record (name varchar2(40), pos number);
procedure myproc (p_in in rectype, p_out out rectype);
end rectest;
/
show errors
create or replace package body rectest as
procedure myproc (p_in in rectype, p_out out rectype) as
begin
p_out := p_in;
end;
end rectest;
/
show errors
You would call it like:
// Node-oracledb 3.1
'use strict';
const oracledb = require('oracledb');
const config = require('./dbconfig.js');
let sql, binds, options, result;
async function run() {
let connection;
try {
connection = await oracledb.getConnection(config);
sql =
`declare
i_r rectest.rectype; -- input record
o_r rectest.rectype; -- output record
begin
i_r.name := :i_nm;
i_r.pos := :i_ps;
rectest.myproc(i_r, o_r);
:o_nm := o_r.name;
:o_ps := o_r.pos;
end;`;
binds = [
{i_nm: 'def', i_ps: 456},
{i_nm: 'ghi', i_ps: 789},
];
const options = {
bindDefs:
{ i_nm: { type: oracledb.STRING, maxSize: 40 },
i_ps: { type: oracledb.NUMBER },
o_nm: { type: oracledb.STRING, maxSize: 40, dir: oracledb.BIND_OUT },
o_ps: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT }
}
};
result = await connection.executeMany(sql, binds, options);
console.log(result);
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}
run();
The output is
{
outBinds: [ { o_nm: 'def', o_ps: 456 }, { o_nm: 'ghi', o_ps: 789 } ]
}

Resources