node-oracledb bind variable of null - javascript

Using the node-oracledb package with node.js, I'm trying to delete a row in my oracle database that has a null value in it. I need to be able to pass a null value in as a bind variable but it is throwing an error:
var query = "delete from table where event IS :event";
var bind_vars = [null];
connection.execute(query, bind_vars, { autoCommit: true }, function(error, results) {});
The error returned is
{ Error: ORA-00908: missing NULL keyword errorNum: 908, offset: 46 }

You don't need a bind variable for that...
Given the following table:
create table t (
c number
);
insert into t values (1);
insert into t values (null);
insert into t values (3);
insert into t values (null);
insert into t values (5);
commit;
This should work:
const oracledb = require('oracledb');
const config = require('./dbConfig.js');
async function runTest() {
let conn;
try {
conn = await oracledb.getConnection(config);
let result;
let value = 1;
if (value === null) {
result = await conn.execute('delete from t where c is null');
} else { // other values should have a bind
result = await conn.execute('delete from t where c = :value', [value]);
}
// Note that the work was not committed.
console.log('Rows deleted:', result.rowsAffected);
} catch (err) {
console.error(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
console.error(err);
}
}
}
}
runTest();

what about change the query
var query = "delete from table where nvl(event, '__') = nvl(:event, '__')";
var bind_vars = [null];
connection.execute(query, bind_vars, { autoCommit: true }, function(error, results) {});
it change null column and value to another character
change (__) with your own character

Related

Building a criteria in mongoDB that doesn't return the proper values

I'm trying to builda criteria that would filter the entries in the DB ,yet i'm not getting the proper results when filtering the genre. (the text seems to work but i'm not sure if the code will support both filters).
This is my buildCriteria function, console logging returns the proper values.
function _buildCriteria(filterBy) {
const criteria = {};
const { text, genre } = filterBy;
console.log('genre:', genre);
if (text) {
const txtCriteria = { $regex: text, $options: 'i' };
criteria.name = txtCriteria;
}
if (genre) {
criteria.genre = { $eq: genre };
}
return criteria;
}
This is the query function :
async function query(filterBy) {
try {
const criteria = _buildCriteria(filterBy);
const collection = await dbService.getCollection('tab');
const tabs = await collection.find(criteria).toArray();
return tabs;
} catch (err) {
logger.error('Can not find tabs', err);
throw err;
}
}
Would appreciate your help greatly!

typescript node insert on mongodb database

im a total newbie in js (typescript, mongoDB, node.)
i just found that my code is not behaving as i expected, im getting 6 registers on the mongoDB instead of just one, it should check if the register exists and then update it, i dont know if it is something related to the await / async or i am doing something wrong, thanks in advace, here is my code.
fields.forEach((value) => {
try {
const mongoConnection = new DocumentDbRepository();
let checksIfExists = await mongoConnection.getValue(key, information[uniqueValue]);
if(checksIfExists==null){
let insert = await mongoConnection.insertValue(information);
console.log(insert);
}
if(checksIfExists?.passValue===information.passValue){
console.log('---------update---------');
let sons = Object.values(information.ticketToRide);
information.ticketToRide = sons;
let update = await mongoConnection.updateRegister(information, checksIfExists._id);
console.log(update);
} else {
console.log('---------insert---------');
let sons = Object.values(information.ticketToRide);
information = sons;
let insert = await mongoConnection.insertValue(information);
console.log(insert);
}
} catch (error) {
console.log(error)
}
}
async getValue(uniqueValue: any, keyValue:any) {
if (this._connection == null) {
await this.connect();
}
const db = this._connection.db(DocumentDbRepository.DbName);
const ticketToRide = db.collection("ticketToRide");
const query = {};
query[uniqueValue] = ''+keyValue+'';
const passInfo = await ticketToRide.findOne(query);
return passInfo;
}
async insertValue(information: any) {
if (this._connection == null) {
await this.connect();
}
const db = this._connection.db(DocumentDbRepository.DbName);
const ticketToRide = db.collection("ticketToRide");
let check = await ticketToRide.insertOne(
information
)
return check;
}
First, you don't need to create a connection inside the loop.
Second, mongodb has an update() or updateMany() method that has a special option { upsert: true }. If it is passed, insert will happen automatically.
Usage example:
Person.update( { name: 'Ted' }, { name: 'Ted', age : 50 }, { upsert: true })

NodeJS: Pass field value from ResolverQuery to another JS File

I would like to know, how can I pass a field value of a QueryResolver to another JS File (database.js) in GraphQL and NodeJS/Apollo. In the database.js file I connect with my MYSQL Database with MariaDB and get dynamically data information. The information should be get by the ID which the user enters in the query. The id is know in my QueryResolver but I don't know how I can pass this ID to my database.js file, so that my user gets the data that he wants.
Instead of the 0 in the code, there should be the ID the user entered.
What I tried:
I tried to save the ID in a variable and to return the id AND the articledatas ( these are my dynamic datas the user gets after the query ). And I tried to get access to the function get_result for getting the id, but then I get stuck, because I don't know I could access to this function outside the query. Could anyone help me please?
My resolver looks like this (this is my problem):
module.exports = {
Query: {
article: (parent, {id}) => {
var data = models.articledata.find((c) => c.id == id);
var id_work = id;
function get_returns(){return [data, id_work];}
var get_results = get_returns();
return get_results[0];
},
},
Node: {
__resolveType(node) {
if(node.toObject().name){
return 'Article';
}
}
}
}
This is my data.js (in Models folder):
//This works fine!
var read = function(){
return new Promise(function(resolve, reject){
var query_str = 'SELECT * FROM Artikel';
conn.query(query_str, function (err, rows, fields) {
if (err) {
return reject(err);
}
resolve(rows)
});
});
}
//Here I want to replace the 0 with the {id} of the resolver above->Problem how can I get a reference of the {id} from the resolver?
var title = read().then(function(rows){return rows[0].NAME});
var articledatas = [{
title: title,
}];
module.exports = { articledatas };
```
This question is a duplicate of How to return the response from an asynchronous call in most of the time. Please read the answer to the question I refer.
After some tries I figured out when I past the code of my data.js DIRECTLY into the Query, then I don't have to pass the ID outside the Query. This works:
module.exports = {
Query: {
article: (parent, {id}) => {
var read = function(){
return new Promise(function(resolve, reject){
var query_str = 'SELECT * FROM Artikel';
conn.query(query_str, function (err, rows, fields) {
if (err) {
return reject(err);
}
resolve(rows)
});
});
}
var title = read().then(function(rows){return rows[id].NAME});
var articledatas = [{
title: title,
}];
return = articledata.find((c) => c.id == id);
},
},
Node: {
__resolveType(node) {
if(node.toObject().name){
return 'Article';
}
}
}
}

NodeJS: map function will return an empty array

I tried to getting result using mssql database using mssql npm and push it to an array. It seems that response will return an empty array outside of the map function, your help will be much appreciated, thank you.
module.exports = {
someRouteHandler: async function(req, res, next) {
const fileStream = await readFileFromS3(req.body.filename); //a function to read file from AWS S3
if (req.body.productName === "Nike" && type === "Male") {
const result = await getBrandInformation(req.body, fileStream); //this function will parse data from the file and return object result
const { brandInformation, brandItems } = result;
const noneDuplicateArrayContainer = [];
const duplicateArrayContainer = [];
for ( const { itemNumber } of brandItems ) {
let items = await getMatchingList(itemNumber); // will query to database if itemNumber has duplicate or none
if (items.length > 1) {
items.map(async({ identifier }) => {
//if identifier not null query cost
if (identifier) {
let cost = await queryCostToDb(identifier); //will query cost from database
duplicateArrayContainer.push({
brandItems, identifier, cost
})
//if identifier is null no cost to save
} else {
duplicateArrayContainer.push({
brandItems, identifier
})
}
});
//if items length is not greater than 1 meaning no duplicate
} else {
items.map(({ identifier }) => {
let cost = await queryCostToDb(identifier); //will query cost from database
noneDuplicateArrayContainer.push({
brandItems, identifier, cost
});
})
}
}
// when sending response noneDuplicateArrayContainer and duplicateArrayContainer is [ ]
// in the console, it has data, but response is delay
return res.status(200).json({ brandInformation, noneDuplicateArrayContainer, duplicateArrayContainer })
}
}
}
I already fixed the issue, implemented await Promise.all in my code, thanks all for the help

Search Operators in Sequelize

I wanted to display all of the data which have gains of greater than 1. But I seem to encounter problems on running the request on my postman with the url of :
http://localhost:3000/api/betHistory/winners
I get the result of:
Executing (default): SELECT `id`, `user_id`, `type`, `league_id`, `team_id`, `amount`, `gains`, `ratio`, `match_id`, `created_at`, `updated_at`, `updatedAt` FROM `bets` AS `bets` WHERE `bets`.`gains` = false;
which should be 'gains' '>' '1'
This is my bet.js
router.get('/winners', async (req, res) => {
try {
const data = req.params.gains;
const bets = await BetRepository.getWinnersBets(data > 1);
res.json(bets);
} catch (error) {
res.status(400).send('No data found');
}
});
This is my BaseRepistory.js
findAll(fields) {
const options = {};
if (!!fields && fields) {
options.attributes = fields;
}
return this.model.findAll(options);
}
And this is my BetRepository.js
const BaseRepository = require('../../../shared/repository/BaseRepository');
const Bet = require('../models/Bet');
const Op = require('sequelize').Op;
class BetRepository extends BaseRepository {
constructor(model) {
super(model);
}
getWinnersBets(gains, fields) {
const options = {
where: { gains }
};
if (!!fields && fields) {
options.attributes = fields;
}
return this.model.findAll(options);
}
}
module.exports = new BetRepository(Bet);
Any ideas on how to work with this? TYIA.
When you do getWinnersBets(data > 1);, you are not passing the expression data > 1 to getWinnersBets, you are passing getWinnersBets(true) or getWinnersBets(false) to it, so in your query you are actually querying
'gains' '=' 'true'
and not
'gains' '>' '1'
I don't know the API of model.findAll so I can't give you a pointer on how to pass that expression to findAll
I have solved this problem by putting an operator on my getWinnersBets
getWinnersBets(fields) {
const options = {
where: {
gains: {
[Op.gte]: 1
}
}
};
if (!!fields && fields) {
options.attributes = fields;
}
return this.model.findAll(options);
}
and removed the > 1 line on my const bets = await BetRepository.getWinnersBets(data > 1)

Categories