SQLITE_RANGE: bind or column index out of range - node.js

I'm trying to insert rows into a database and I've tried to simplify my code as much as possible, but I'm still getting the error 'SQLITE_RANGE: bind or column index out of range'
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database(':memory:', (err) => {
if (err) {
return console.error(err.message);
}
console.log('Connected to the in-memory SQlite database.');
});
db.serialize(function(){
db.run('CREATE TABLE parks ' +
'(' +
'Name text' +
')'
);
});
csv.fromPath("parks.csv", {renameHeaders : true, headers : [,
'Name',
]})
.on("data", function(data){
query = "INSERT INTO parks VALUES ('Arbutus_Village_Park')"
db.run(query, ['C'], function(err) {
if (err) {
return console.log(err.message);
}
});
})
Could someone please point out something that I might be missing out on? Thanks

Check your syntax on db.run, see API documentation.
Your code fails because you try to pass 'C' as a bound parameter, but the query contains no placeholders.

Related

node js SQL Insert Query with Constructor / JSON text as values parameter

First real app and I'm stuck trying to insert a new row into SQL.
//This is the API endpoint
Sponsor.create = (newSponsor, result)=> {
var sqlStmt = 'insert into sponsors (SponsorName, SponsorState, SponsorDesc, pnfpExperience, Status) values ?'
sql.query(sqlStmt, [newSponsor], (err, res)=> {
if(err) {
console.log(" error: ", err);
result(null, err);
}
else{
console.log(res);
result(null, res);
}
});
};
request.body returns the JSON text but not an array of values that can be used in the query. I keep getting a COUNT error or syntax error. I've tried JSON.parse but I get an undefined error. I know there has to be a simple way to convert the JSON text to the right format but I don't know what I'm missing. The "findAll" and "findById" routes work and I can insert static values. I've also tried "newSponsor" with and without brackets. I'll refine the connection method in time but I'm just trying to understand why this doesn't work. Any help is greatly appreciated.
// Controller.js for Reference
exports.create = function(req, res) {
const new_sponsor = new Sponsor(req.body);
//handles null error
if(req.body.constructor === Object && Object.keys(req.body).length === 0){
res.status(400).send({ error:true, message: 'Please provide all required field' });
}else{
Sponsor.create(new_sponsor, function(err, sponsor) {
if (err)
res.send(err);
res.json({error:false,message:"Sponsor added successfully!",data:sponsor});
});
}
};

Delete last Sqlite row that have same certain name value

How can I write a function that will delete just one row (ideally the last one) that has a given name (which may not be unique).
I have tried using row count, limits, and my own built in function (below). None of these have worked.
app.delete('/FamilyMember/:db', (req, res) => {
let db = openDB("ClientsDatabases/"+req.params.db);
let ids = [];
db.serialize(()=>{
db.each('select * from family', (err, row)=> {
if (row.name == req.body.name) {
ids.push(row.id);
}
})
db.run("DELETE FROM family WHERE id = ?",ids[ids.length-1], (err)=> {
console.log("Here is the err "+err);
if (!err) console.log('Succesful # deleting', req.body.name);
});
})
res.send();
}, () => {
db.close();
})
My expected output is for only one row with the given name to be deleted, but the table doesn't change and no errors are caught.
Any particular reason you've got single quotes (') around your ? parameter in your call to Statement#run? Nothing in the API documentation suggests that this is correct practice, could be an explanation as to why your query is mangled to the point where it doesn't delete anything, but also doesn't throw an error. I'd expect your call to .run() to look something more like the below:
db.run("DELETE FROM family WHERE id = ?",ids[ids.length-1], (err)=> {
console.log("Here is the err "+err);
if (!err) console.log('Succesful # deleting', req.body.name);
});
You may alternatively be interested in simplifying your queries into a single statement that will grab the maximum id (provided the id is incremented each time) and delete that record:
db.run("DELETE FROM family WHERE id = MAX(id)", (err)=> {
console.log("Here is the err "+err);
if (!err) console.log('Succesful # deleting', req.body.name);
});
This eliminates the need to load all the contents of family first just to grab a single id from it.

How to query azure SQL from node.js server

I'm having some trouble with querying my DB on azure sql (I am very new to sql). I'm following the steps on https://learn.microsoft.com/en-us/azure/sql-database/sql-database-connect-query-nodejs, but it only includes tutorial steps on how to read tables, not manipulate them. I am trying to do INSERT and DELETE requests on my Node.js server, but I am getting a request error in one of the node modules, which makes me think that I'm going about requesting the operations wrong.
Here's some code:
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
// Create connection to database
var config =
{
userName: 'user_name',
password: 'password',
server: 'server_name',
options:
{
database: '_dbname'
, encrypt: true
}
}
var connection = new Connection(config);
// Attempt to connect and execute queries if connection goes through
connection.on('connect', function (err) {
if (err) {
console.log(err)
}
else {
queryDatabase();
}
}
//this works fine, it's for initially loading the data from the database
function queryDatabase() {
console.log('\nReading rows from the Table...');
let obj = {};
let objs = [];
let request;
// Read all rows from table
request = new Request(
"SELECT * FROM [dbo].[TABLE_NAME]",
function (err, rowCount, rows) {
console.log('-- Done');
}
);
//this is for when an admin adds content to the app, SQL table not changing,
//node.js throws error
socket.on('add item', item => {
let index = getCollectionIndexById(item.id);
collections[index].items.push(item.item);
io.sockets.emit('add item', item);
request = new Request(`INSERT INTO [dbo].[TABLE_NAME](Id, attr1, attr2, attr3, attr4)
VALUES (`
+ item.id + ','
+ item.item.attr2 + ','
+ item.item.attr3 + ','
+ item.item.attr4 + ','
+ null, function (err, rowCount, rows) {
if (err) throw err;
console.log('> requested db to insert item');
});
connection.execSql(request);
console.log('> item sent to app');
});
//for when the admin removes content from the app, same error
socket.on('rm item', item => {
collections[getCollectionIndexById(item.id)].items.splice(item.index, 1);
io.sockets.emit('rm item', { "id": item.id, index: item.index });
request = new Request(`DELETE FROM [dbo].[TABLE_NAME] WHERE Id= `
+ item.id + ` AND attr1= ` + item.item.attr1, function (err, rowCount, rows) {
if (err) throw err;
console.log('> requested db to remove item')
});
connection.execSql(request);
console.log('> sent request to remove item');
});
The exact error msg is RequestError: Incorrect syntax near 'esse'., and its in one of the node modules called tedious in request.js.
So in summary, if anyone knows of a way to query Azure SQL Db's to make inserts and deletes, any help is appreciated!
You missed ) in the 'insert' SQL. Also, you'd need to set string value with single quotes of course.
Change the following lines of code
request = new Request(`INSERT INTO [dbo].[TABLE_NAME](Id, attr1, attr2, attr3, attr4)
VALUES (`
+ item.id + ','
+ item.item.attr2 + ','
+ item.item.attr3 + ','
+ item.item.attr4 + ','
+ null, function (err, rowCount, rows) {
if (err) throw err;
console.log('> requested db to insert item');
});
connection.execSql(request);
to
request = new Request(`INSERT INTO [dbo].[TABLE_NAME](Id, attr1, attr2, attr3, attr4) VALUES ('${item.id}', '${item.item.attr2}', '${item.item.attr3}', '${item.item.attr4}' null)`, function (err, rowCount, rows) {
if (err) throw err;
console.log('> requested db to insert item');
});
connection.execSql(request);
You will find an example here of how to INSERT records on a table using NodeJs and queryRaw.
conn.queryRaw("INSERT SalesLT.Product (Name, ProductNumber, StandardCost, ListPrice, SellStartDate) OUTPUT INSERTED.ProductID VALUES ('SQL Server Express 102', 'SQLEXPRESS 102', 0, 0, CURRENT_TIMESTAMP)", function (err, results)
You can use queryRaw also to DELETE records on a table.
Hope this helps.

Nodejs with Mysql Database

I'm using nodejs with MySQL for the first time , I'm struggling to properly preparing statements ,I have no problems when writing and executing some insertion statements but when i tried to write the selection statements i can't know what is the correct syntax .I can't find tutorial for the beginner
This is the selection code
io.sockets.on('connection', function(client) {
client.on('check_id', function(login_feilds) {
console.log(login_feilds);
var login_feilds_as_json = login_feilds ,
Email = login_feilds_as_json.email ,
password = login_feilds_as_json.password ;
var sql = "SELECT * FROM ?? WHERE ?? = ? AND ?? = ?";
var inserts = ['users', 'email', Email,'password',password];
sql = mysql.format(sql, inserts);
console.log(sql);
connection.query( sql , function(err, rows){
if(error){
console.log(error.message);
}else{
console.log('found it'); };
});
});
});
when I run the above code I got this
{ email: 'user#windowslive.com', password: 'user' }
SELECT * FROM `users` WHERE `email` = 'user#windowslive.com' AND `password` =
'user'
C:\Users\jiil\Desktop\our-project\node_modules\mysql\lib\protocol\Parser.js:82
throw err;
^
ReferenceError: error is not defined
could you help me to figure out what i have to do or give me any good resources' links .
The problem is that you wrongly use variable name in your callback function. You need to change error to err.
connection.query(sql, function(err, rows){
if (err) {
console.log(err.message);
} else {
console.log('found it');
}
});
Hope it will be useful for you.

how to join the result of two node-mysql.js functions in express.js

I'm trying to export some legacy data from a mysql db as JSON using express and node-mysql. The SQL below works fine. I'm struggling with a simple way to join the 'result' of getOwnerID and to the data for each row returned in compVouchers.
I'm also using async.js having followed another thread, though I'm not sure this is helping. But if I can get away with not using this that might be better.
//join some tables to get comprehensive voucher data
exports.compVouchers = function(req, res) {
var advertType = '"discount_voucher_all_CANCELLED"';
if (connection) {
connection.query('SELECT V.id AS voucher_id, V.title, V.description, V.discount, V.customers_total, V.advert_type, ' +
'V.customers_redeemed, V.start_date, V.expiry_date, V.redemption_code, ' +
'K.image, G.latitude, G.longitude FROM '+dbname+'.vouchers AS V ' +
'LEFT JOIN '+dbname+'.iag_key_tags AS K ON ( V.id = K.id ) ' +
'LEFT JOIN '+dbname+'.iag_geo_tags AS G ON ( V.id = G.id ) ' +
'WHERE V.advert_type like '+advertType , function(err, rows, fields) {
if (err) throw err;
console.log("Got "+rows.length+" Vouchers:");
// now get each vouchers owner id
async.map(rows, getOwnerID, function(err, results){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(JSON.stringify(results));
res.end();
});
});
}
};
function getOwnerID(voucher, callback) {
connection.query('SELECT parent_tagid AS owner_id FROM '+dbname+'.iag_key_tag_relationships WHERE TYPE =2 AND tagid = '+ voucher.voucher_id, function(err, info) {
if(err) {
console.log(err);
return callback(err);
}
else {
return callback(null, info);
}
});
}
so
res.end(JSON.stringify(results)); // prints all the owner_id of each voucher only
res.end(JSON.stringify(rows)); // prints the data for each voucher but not the owner_id
Combining node-mysql result rows into single JSON return for node.js doesn't solve the problem but as you can see I have tried to follow the suggestion in that thread.
Here this is some more beauty than in coments :)
Try this:
var result={}, c=rows.length;
function getOwnerID(voucher, cb){
connection.query('SELECT ...', function(err, info) {
if(err) console.log(err);
else result[info] = voucher;
if(!--c)return cb();
});
}
while(rows.length){
getOwnerID(rows.pop(), function(){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(JSON.stringify(results));// {"owner1":{voucher1}, "owner2":{voucher2}}
res.end();
})
}
OK guys (thanks #vp_arth for nudging me in an interesting direction that got me close, the typo results should be result btw)
So anyhow, I ended up with a hack solution, I'm using .push underscore.js and .replace to help me clean up the JSON data so I could use it later / next in a nosql database like MongoDB.
//declare global array variable... there must be a more elegant solution
var compV = [];
exports.compVouchers = function(req, res) {
var advertType = '"discount_voucher_all_CANCELLED"';
if (connection) {
connection.query('SELECT V.id AS voucher_id, V.title, V.description, V.discount, V.customers_total, V.advert_type, ' +
'V.customers_redeemed, V.start_date, V.expiry_date, V.redemption_code, ' +
'K.image, G.latitude, G.longitude FROM '+dbname+'.vouchers AS V ' +
'LEFT JOIN '+dbname+'.iag_key_tags AS K ON ( V.id = K.id ) ' +
'LEFT JOIN '+dbname+'.iag_geo_tags AS G ON ( V.id = G.id ) ' +
'WHERE V.advert_type like '+advertType , function(err, rows, fields) {
if (err) throw err;
// now get each vouchers owner id
console.log("Got "+rows.length+" Vouchers:");
async.each(rows, getOwnerID, function(err, results){
res.writeHead(200, {'Content-Type': 'text/plain'});
// now user underscore.js to clean up JSON
var finalComp = JSON.stringify(un.flatten(un.compact(compV)));
// finally use replace to customise the known output to merging the voucher and owner into single JSON documents
var finalComp2 = finalComp.replace(/},{"owner_id/g,',"owner_id'); //not happy with this but it works
res.write(finalComp2);
res.end();
});
});
}
};
function getOwnerID(voucher, callback) {
connection.query('SELECT parent_tagid AS owner_id FROM '+dbname+'.iag_key_tag_relationships WHERE TYPE =2 AND tagid = '+ voucher.voucher_id, function(err, owner) {
if(err) {
console.log(err);
return callback(err);
}
else {
var arr = [];
arr.push(voucher);
arr.push(owner);
compV.push(arr); //append to global array variable
return callback(null, compV); // doesn't return anything??
}
});
}
perhaps there is a more elegant way to merge
[{"F1_field1":"F1_value1","F1_field2":"F1_value2"},{"F2_field1":"F2_value2"}]
into
[{"F1_field1":"F1_value1","F1_field2":"F1_value2","F2_field1":"F2_value2"}]
here is my final code with comments / thoughts
you would now also need to npm install underscore addition to async and declare them in variables... not to mention node-mysql and express... I have used "un" instead of "_" so I don't get confused with code that might look like jquery shorthand later.

Resources