node.js mysql failing to insert - javascript

I'm messing around with node.js, using the Faker, underscore, mysql and randy libraries to add some test data to a web app.
So far so good-- but in one of my loops, the mysql call fails every time, but it also fails to generate any errors. I'm a bit stumped:
var sql = 'SELECT id FROM mytable WHERE 1';
client.query(sql, function(err, rows, fields){
// loop through results
_.each(rows, function (v, i){
// get the insert id
var id = v.id;
console.log (id); // prints valid ID
// generate other data
var stuff_count = randy.randInt(0,12);
_(stuff_count).times(function(n){
var sql = 'INSERT INTO other_table (linked_id, item_id) VALUES ('+id+','+randy.randInt(1,50)+')';
console.log(sql); // prints sql
client.query(sql, function(err, rows, fields) {
console.log(sql); // prints nothing
if (err){
console.log(sql); // prints nothing
throw err; // prints nothing
}
});
});
});
The looping logic is working fine and it gets all the way to where the sql should execute the INSERT against the other_table-- but tailing the mysql log shows nothing hitting the DB, and none of the debug statements inside the client.query block are printing anything, on success or failure.

assuming you are just running this standalone, your code probably finishes before it has a chance of doing the inserts.
place a setTimeout(..., 10000) after the _(stuff_count).times(...)
By using _().times(), you queue all the inserts, but are not waiting for completion. you should use a control flow library to ensure you wait for all inserts to complete.

Related

node / express js, get data after query

I know it will be a trivial thing, but for this, I have not found much around, I'm using node/express js to query a database (MySQL), I'm using the following mode for queries:
index.js
exports.view= function(req, res){
var name = req.params.name;
req.getConnection(function(err,connection){
var query = connection.query('SELECT * FROM event WHERE linkname = ?',[name],function(err,rows)
{
if(err){
console.log("Error Selecting : %s ",err );
res.redirect('/');
}else{
console.log("rows: %s",rows);
var body = JSON.parse(JSON.stringify(rows));
console.log("body: %s",body);
res.render('form_payment',{page_title:"Showroom",data:rows});
}
});
});
};
I would like to view the video, or in any case be able to use part of the query data, I read that you can use JSON.stringify(), JSON.parse() or both, but I always print the empty string on the screen, even when I try to print rows:
rows:
body:
The query works perfectly, in fact, I can pass the json of rows to the next activity with res.render (), but in this function (view) I just can not get and then use this data. My idea would be to be able to easily use the contents of rows, for example, something like rows[0].name, rows[0].id or rows.name, rows.code, ...
[SOLVED]
Remember to check if the variables that are passed to the query are correct, once this problem has been solved everything is back to work correctly and access to the rows elements, can occur with rows[0].id, rows[0].name, ...
I hope you can also help you find yourself in this situation.

Node mssql: return id after SQL insertion

I am working on an integration between Mongodb and SQL Server, inserting and updating registers from MongoDb to SQL Server database with a scheduled process, using the mssql package to achieve this.
Each time a new register is inserted, I want the new row id to be retrieved back, because I need it to perform another insertions of subregisters.
I tried the following, expecting to have some information retrieved in the result of the query. The query actually inserts the row, but result is returned as undefined:
var sql = require('mssql');
var connectionConfig = 'xxxxxxxxxxxx';
var insertionQuery = 'xxxxxxxxxxxx';
sql.connect(connectionConfig).then(pool => {
pool
.request()
.query(insertionQuery);
}).then(result => {
//I expect 'result' to have information of the inserted row, but it comes undefined instead
cosole.log(result);
}).catch(err => {
console.err(err);
});
I think using stored procedures may work around this, but I just want to avoid using a stored procedure for simple inserts.
Does anyone knows how to have the new row id back after insertion?
EDIT
I did include OUTPUT SCOPE_IDENTITY() in my SQL statement - my query now looks like:
INSERT INTO TABLE (columns...)
OUTPUT SCOPE_IDENTITY()
VALUES (values...)
If I run the query in my SQL Server Management Studio, it works just fine and I got my new row id returned, but when running the query through the mssql package's query method, result is returned like this:
[ { '': null } ]
I quote from node-mssql insert returning undefined recordset:
INSERT statement doesn't return a recordset so recordset is
undefined. Please see this section of the docs to learn more
about how to get number of affected rows.
An option to solve this is to add a SELECT statement after your INSERT and ask for SCOPE_IDENTITY() or ##IDENTITY. That will get you the ID of the last inserted objects, i.e.:INSERT INTO table (...) VALUES (...); SELECT SCOPE_IDENTITY() AS id;
If anyone comes having problems with GUID, since you cannot set it as an Identity column, you must do something like:
const result = await pool
.request()
.input('orgName', sql.VarChar, orgName)
.input('tier', sql.Int, tier)
.input('status', sql.Int, status)
.input('createDate', sql.Date, new Date())
.input('statusChangeDate', sql.Date, new Date())
.query(`INSERT INTO app.Organizations (OrgName,
Tier, Status, CreateDate, StatusChangeDate)
OUTPUT inserted.OrgID
VALUES (#orgName, #tier, #status, #createDate, #statusChangeDate);
`)
Where the orgID is the auto generated GUID. Also don't follow my new Date() example as it inserts the date as tomorrow... I need to fix that.

My nodeJS code is not asynchronous

Using the nodeJS package color-namer I'm naming an hex code by a color name. (ex: "#FF0000" will be turned to "red")
All my hex codes are stored in a mysql database (table = hex_codes ; colname = color), which I'm querying from nodejs.
Line by line I'm then retrieving the name of the hex code (colname = color) and I'm dumping the result in an other table (table = color_names).
My code is the following:
var mysql = require("mysql"),
namer = require('color-namer'),
connection = mysql.createConnection({
multipleStatements: true,
host : '***',
user : '***',
password : '***',
database : '***'
});
connection.connect();
connection.query(
`SELECT color from hex_codes`,
function(err, results, fields) {
results.forEach(function(elem){
var currentHex = elem['color'],
currentColor = namer(currentHex);
connection.query(
`INSERT INTO color_names (hex, basic) VALUES (?,?);`,
[currentHex,currentColor['basic'][0]['name']]
);
});
}
);
Since javascript is an asynchronous language, how come my lines are not dumped one by one but the whole dataframe is dumped once the script is done running?
The call back of the first connection.query is enough to prove its asynch and call backs are only executed when the stack is empty. so after getting the result u are doing an one by one insert but apart from putting a callback to second u will never get its asynch or synch because it will be quick try
connection.query(
`SELECT color from hex_codes`,
function(err, results, fields) {
results.forEach(function(elem){
var currentHex = elem['color'],
currentColor = namer(currentHex);
console.log("in loop");
connection.query(
`INSERT INTO color_names (hex, basic) VALUES (?,?);`,
[currentHex,currentColor['basic'][0]['name']]
,function(err,data){
console.log("insert callback")
});
});
});
The order of execution will say itself that its asynch. And its important to remember that callbacks are only executed when the stack is empty.
It will dump lines one by one only in case of streams .
Streams will start emitting output as soon as the first item arrives .It is an extension of event emitter pattern .
However if you use callback , your code will be asynchronous but the result will arrive all at once .
Hope this helps
The operation in your code sample is expected to be sequential. Here is how:
results.forEach(function(elem){
var currentHex = elem['color'],
currentColor = namer(currentHex);
connection.query(
`INSERT INTO color_names (hex, basic) VALUES (?,?);`,
[currentHex,currentColor['basic'][0]['name']]
);
});
Here, the forEach statement has the job of delegating the query to the connection object, but will not wait for the query to complete. All good.
But then, the connection.query method by default supports only sequential execution, which means, subsequent requests for inserts in your query are executed in sequence and not parallel. The mysqljs documentation says:
The MySQL protocol is sequential, this means that you need multiple connections to execute queries in parallel.
For them to be executed in parallel, you should use connection pooling which is described here.

Node/JSON Issues

So I am trying to figure out why my returned object every single time is just []?
Here is my code:
var returnObject = [];
db.query(queryString, function(err, rows, fields) {
if (err) throw err;
for (var i in rows)
{
console.log('Data: ', rows[i]);
var marker =
{
o_ID:rows[i].o_ID,
data:rows[i].data
};
returnObject[i]=marker;
console.log(chalk.red(returnObject[i].o_ID));
console.log(chalk.red(returnObject[i].data));
}
});
var sqsParams = {MessageBody: JSON.stringify(returnObject), QueueUrl :'---'};
For some reasons when I print the returnObject values they are correct but when it gets to the JSON.stringify something happens and sends to my SQS queue just [].
I thought maybe getting rid of the marker variable and just assigning
returnObject[i]= {
o_ID:rows[i].o_ID,
data:rows[i].data
};
But that still results in the same issue. Any ideas? Thanks!
Database queries in JavaScript are usually asynchronous. This means that the code inside your callback function function(err, rows, fields) will be run only after the database query has been done, whereas you assignment to sqsParams will be done right after the database query has been started. The result is that code inside your callback function has not been run before you returnObject with JSON.stringify and it is still in its original value [].
Your sqsParams variable is being set outside the db.query callback. As the db.query is asynchronous, your code is going to just fall through with an empty array.
Move your sqsParams variable into the callback you are supplying to db.query, eg:
console.log(chalk.red(returnObject[i].o_ID));
console.log(chalk.red(returnObject[i].data));
}
var sqsParams = {MessageBody: JSON.stringify(returnObject), QueueUrl :'---'};
// Use sqsParams here
});

Promise in node

I just started with node js and I'm in trouble in a procedure.
In my code, I get a list of items via json (array) and do a loop that list to see if there is a record in the database or not.
If there is no record in the database, I do an insert if there is I do an update.
The problem is that the system is going too fast over the query and does not wait for the result to see whether or not due to javascript asynchronously.
The need does he wait for the check query to return then continue and finally wait for the insert as well, for the insert must have the answer before continuing the loop "for".
The code would look like this:
var input = JSON.parse (req.param ('data'));
for (var i in input) {
iCode var = input [i] .codeOSNum;
qry = 'select count(*) as qtd from table where code = '+iCode; //need wait result from this query
var connection = new sql.Connection(config);
var request = new sql.Request(connection);
request.query(qry, function(err, recordset) {
if (recordset[0].qtd = 0) {
//do stuff to insert like: 'insert into blablabla' and need wait return.
} else {
//do stuff to update.
}
}); //and finally go to next item from loop 'for' and repeat until the end os json array.
}
I use indicated promise, but do not know how to use. I am newbie and desperate.

Categories

Resources