I have this table with a clob column. I connect to the database from my express app using the oracledb driver. I want to print out this clob. This is my code:
router.get('/:task_name', function (req,res) {
"use strict";
oracledb.getConnection(connAttrs.database, function (err, connection) {
if (err) {
// Error connecting to DB
res.set('Content-Type', 'application/json');
res.status(500).send(JSON.stringify({
status: 500,
message: "Error connecting to DB",
detailed_message: err.message
}));
return;
}
connection.execute("select solution from solvedtasks s join tasks t on t.TASK_ID = s.TASK_ID WHERE task_name= :task_name", [req.params.task_name],{
outFormat: oracledb.OBJECT //resultSet:true,
}, function (err, result) {
if (err) {
res.set('Content-Type', 'application/json');
res.status(500).send(JSON.stringify({
status: 500,
message: "Error getting the user profile",
detailed_message: err.message
}));
} else {
res.contentType('application/json').status(200);
res.send(JSON.stringify(result.rows[0]));
console.log(result.rows[0]);
// fetchRowsFromRS(connection,res,result.resultSet,10);
}
// Release the connection
connection.release(
function (err) {
if (err) {
console.error(err.message);
} else {
console.log("GET /SolvedTasks : Connection released");
}
});
});
});
});
Instead of printing the clob from my database I get something that looks like lob metadata. Has anyone else encountered this issue? Here is a screenshot of my output:
So I solved this, I am posting an answer in case anyone has this problem. Apparently the original oracledb driver has some issues handling clobs. But there is a library that enhances its functionality, called simple-oracledb, very easy to use and install: https://github.com/sagiegurari/simple-oracledb
by using connection.query, clobs are properly handled:
enter code here
connection.query('SELECT * FROM departments WHERE manager_id > :id', [110], {
splitResults: true, //True to enable to split the results into bulks, each bulk will invoke the provided callback (last callback invocation will have empty results)
bulkRowsAmount: 100 //The amount of rows to fetch (for splitting results, that is the max rows that the callback will get for each callback invocation)
}, function onResults(error, results) {
if (error) {
//handle error...
} else if (results.length) {
//handle next bulk of results
} else {
//all rows read
}
});
Related
i'm trying create first node js api.
i wroted this code but when i start server.js it's not working.
here code :
var executeQuery = function(res, query){
sql.connect(dbConfig, function (err) {
if (err) {
console.log("Error while connecting database :- " + err);
res.send(err);
}
else {
// create Request object
var request = new sql.Request();
// query to the database
request.query(query, function (err, res) {
if (err) {
console.log("Error while querying database :- " + err);
res.send(err);
}
else {
res.send(res);
}
});
}
});
}
when i start it error say :
C:\node\atlasErpApi\server.js:47 res.send(res);
TypeError: res.send is not a function at C:\node\atlasErpApi\server.js:47:43
You are declaring a new variable res as argument to your request.query callback which shadows the res the comes as argument to your executeQuery function.
This should be most obvious at the line res.send(res) which, if you think about it, doesn't make sense at all.
Use different variable names for the two. For example, change the inner one to sqlRes:
var executeQuery = function(res, query) {
sql.connect(dbConfig, function(err) {
if (err) {
console.log("Error while connecting database :- " + err);
res.send(err);
} else {
// create Request object
var request = new sql.Request();
// query to the database
request.query(query, function(err, sqlRes) { // <<< CHANGED to sqlRes
if (err) {
console.log("Error while querying database :- " + err);
res.send(err);
} else {
res.send(sqlRes); // This makes more sense now :-)
}
});
}
});
}
Note: Technically this also happens for err - you have an err from request.query's callback shadowing the err from sql.connect's callback. But this usually doesn't matter because you won't need to use the outer err in the inner callback.
I am trying to check if a user already exists in the database, I have managed to stop creating a user if one already exists with the same phone number , however I do not seem to get the error message displayed. I am not too sure why my error is not being handled correctly. Here is my code:
exports.usercreate = function (req, res)
{
users.create(req.body, function (err, result)
{
var phonenumber = req.body.phonenumber;
console.log(phonenumber);
if (phonenumber.length > 0)
{
res.status(200).json(
{
status: "error",
resCode: 400,
msg: 'cutomer added error'
});
}
else
{
res.status(200).json(
{
status: "success",
resCode: 200,
msg: "users Added Successfully",
});
}
else
{
console.log(error)
}
});
};
Getting error like customer added error. but records are inserted in couchbase
as #TommyBs mentioned, you are basically comparing an N1qlQuery object to whatever is coming on req.body.phonenumber
...
bucket.query(query, function(err, rows, meta) {
for (row in rows) {
if(row.phonenumber == req.body.phonenumber) {
res.status(500).json({status:"error", resCode: 500, msg:"users Already exist"});
}
}
}
I have picked up a project where when a node.js program starts for the first time, no database will exist. The program should create the database tables if they don't already exist.
However, in the sample program below, the data is not inserted if the database did not exist on first run because the select statement fails.
The output of the code below is:
$ node dbtest.js
finished initialise_database
program ended.
select err: { Error: SQLITE_ERROR: no such table: mytable errno: 1, code: 'SQLITE_ERROR' }
successfully created mytable table
database closed.
As you can see from the logging, the code assumes a synchronous execution.
I assume that what is happening is that the node.js runtime system uses different threads to schedule the database functions to run in parallel.
I need the CREATE TABLE command to complete before proceding. How would I achieve this?
Is there some standard way to achieve such a thing in node.js?
code below:
// npm install sqlite3 - to install sqlite3
const sqlite3 = require('sqlite3').verbose();
let db = initialise_database();
check_and_update(db); //Calling this function upon starting the server.
close_database(db);
console.log('program ended.');
function initialise_database() {
//Establishing a database connection.
let db = new sqlite3.Database('database1.db', (err)=>{
if(err) {
return console.error(err.message);
}
});
// // new db always succeeds even if no file exists - if empty file have to generate table structure
db.run("CREATE TABLE IF NOT exists 'mytable' ('num1' INTEGER, 'num2' INTEGER, 'text1' TEXT);", function(err) {
if (err) {
console.log("Create table error: ", err);
}
console.log("successfully created mytable table");
});
console.log("finished initialise_database");
return db;
}
function check_and_update(db) {
db.all("SELECT * FROM mytable", function(err, data){
if(err) {
console.log("select err: ", err);
} else {
db.run('INSERT INTO mytable (num1, num2, text1) VALUES (?, ?, ?)', [1, 2, 'hi guys!!!'], function(err){
if(err)
console.log("insert err: ", err);
});
}
});
}
function close_database(db) {
db.close((err) => {
if (err) {
return console.error(err.message);
}
console.log('database closed.');
});
}
Database requests are asynchronous, you have to deal with them in an asynchronous way.
Which can be :
Callback
Promise
Async/await
Otherwise you will try to perform a request on a database not initialized.
Here is an example using Promise.
const sqlite3 = require('sqlite3').verbose();
let dbPtr = false;
initialise_database()
.then((db) => {
dbPtr = db;
return check_and_update(dbPtr);
})
.then(() => {
close_database(dbPr);
// All is done
console.log('program ended.');
})
.catch((err) => {
// Deal with the error
});
function initialise_database() {
return new Promise((resolve, reject) => {
//Establishing a database connection.
const db = new sqlite3.Database('database1.db', (err) => {
if (err) {
console.error(err.message);
return reject(err);
}
db.run('...', function(err) {
if (err) {
console.log("Create table error: ", err);
return reject(err);
}
console.log("successfully created mytable table");
return resolve(db);
});
});
});
}
function check_and_update(db) {
return new Promise((resolve, reject) => {
db.all('...', function(err, data) {
if (err) {
console.log("select err: ", err);
return reject(err);
}
db.run('...', [1, 2, 'hi guys!!!'], function(err) {
if (err) {
console.log("insert err: ", err);
return reject(err);
}
return resolve();
});
});
});
}
function close_database(db) {
db.close();
}
#EDIT
Looking at the documentation it seems that db.close() do not take a callback in parameter. I've modified the snippet.
I am trying to get data from a SQL Server DB using node. I can make a connection and get data by running functions, but I would like to turn the functions into API endpoints.
Based on the error it seems to me that the res variable isn't getting passed down into the last if statement, but I'm not seeing the issue.
I get a res.send is not a function error when using a GET method on this address from Postman.
let mssqlQuery = function(query, res) {
sql.connect(dbConfig, function(err) {
if (err) {
console.log("Error while connecting database :- " + err)
res.send(err)
} else {
let request = new sql.Request();
request.query(query, function(err, res) {
if (err) {
console.log("Error while querying database :- " + err)
res.send(err)
} else {
res.send(res) // res.send is not a function
}
})
}
})
}
// GET API
app.get("/api/address", function(req, res) {
var query = "select * from address"
mssqlQuery(query, res)
})
Is the res variable improperly scoped or might I have the wrong approach entirely?
As #Sirko suggested, the res value was shadowed by an other variable. The corrected code:
let mssqlQuery = function(query, res) {
sql.connect(dbConfig, function(err) {
if (err) {
console.log("Error while connecting database :- " + err)
res.send(err)
} else {
let request = new sql.Request();
request.query(query, function(err, resp) { // Changed res to resp
if (err) {
console.log("Error while querying database :- " + err)
res.send(err)
} else {
res.send(resp) // res.send is not a function
}
})
}
})
}
I need to query 2 different collections and send it in the express response. I have a very vague idea of what is needed to do so. I tried to contact the query documents to an empty array and send that new array as the response. But I receive an empty array as a response.
This is my route.
site.route('/campus/development')
.get(function(req, res) {
var devPosts = [];
development.find().exec(function(err, docs) {
if (err) {
console.log('Error : ' + err);
} else {
if (docs != null) {
devPosts = devPosts.concat(docs);
console.log(docs);
} else {
console.log('No posts found');
}
}
});
jobs.find().exec(function(err, jobs) {
if (err) {
console.log('Error : ' + err);
} else {
if (jobs != null) {
devPosts = devPosts.concat(jobs);
console.log(jobs);
} else {
console.log('No jobs');
}
}
});
res.send(devPosts);
});
This is due to the async operation of the requests to the database. There are a variety of solutions to this but basically distill down to two types: callbacks or promises.
A callback solution might look like:
site.route('/campus/development')
.get(function(req, res) {
development.find().exec(function(err, devDocs) {
if (err) {
console.log('Error : ' + err);
} else {
if (devDocs != null) {
console.log(devDocs);
jobs.find().exec(function(err, jobs) {
if (err) {
console.log('Error : ' + err);
} else {
if (jobs != null) {
console.log(jobs);
res.send([devDocs, jobs]);
} else {
console.log('No jobs');
}
}
});
} else {
console.log('No posts found');
}
}
});
});
But this introduces a couple of interesting issues: one is the phenomenon known as callback hell and the other is that you should be responding with the errors which means you would need to have a response call for each error (albeit this is a very simplistic approach to it).
As mentioned earlier there is another type of solution which involves using promises. There are a bunch of libraries that you can use and actually Mongoose returns a promise from the exec method. However if you are on Node 0.12.x you can also use the native Promise (it was introduced in 0.11 but you should be using 0.12.x over 0.11.x). A benefit to using the native promise over the one returned from Mongoose is that you can execute these requests in parallel since they don't depend on each other.
site.route('/campus/development')
.get(function(req, res) {
Promise.all([
development.find().exec(), // returns a promise
jobs.find().exec() // returns a promise
]).then(function(results) {
// results is [devDocs, jobs]
console.log(results);
res.send(results);
}).catch(function(err) {
res.send(err);
});
});