I have an array of customer objects, that I wish to insert to the SQL database. The customer objects are retrieved from the req data.
I am using Tedious for the request, and Tedious Connectionpool in order to have multiple connections at the same time.
When looping over the objects i am getting an error when trying to insert, the error being
{ [RequestError: Violation of PRIMARY KEY constraint `'PK__Customer__A4AE64D873A5400C'. Cannot insert duplicate key in object 'dbo.Customer'. The duplicate key value is (2).]`
Note that I only have 3 object being send in the req at this time. It looks to me that it is only the last object that are being handled and inserted. But since I am new to using tedious with Node.js i cant spot my mistake. Any suggestions ?
router.post('/',jsonParser, function(req, res) {
var customers = req.body.customers;
var companies = req.body.companies;
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
var config = {
userName: '*************',
password: '*************',
server: '***********.database.windows.net',
// When you connect to Azure SQL Database, you need these next options.
options: {encrypt: true, database: '*******'}
};
var poolConfig = {
min: 1,
max: 3,
log: true
};
var pool = new ConnectionPool(poolConfig, config);
for (var i = 0; i < customers.length; i++) {
console.log('Inserting '+customers[i].firstname);
var firstname = customers[i].firstname;
var count = i;
pool.acquire(function (err, connection) {
if (err)
console.error(err);
//use the connection as normal
var request = new Request("INSERT INTO dbo.Customer" +
" (Firstname,CustomerId)" +
"VALUES" +
" (@Firstname,@CustomerId);", function (err, rowCount) {
if (err)
console.error(err);
console.log('rowCount: ' + rowCount);
//release the connection back to the pool when finished
connection.release();
});
request.addParameter('Firstname', TYPES.VarChar,firstname);
request.addParameter('CustomerId', TYPES.Int, count);
request.on('row', function (columns) {
console.log('value: ' + columns[0].value);
});
connection.execSql(request);
});
pool.on('error', function (err) {
console.error(err);
});
}
});
The scope of your variables count
and firstName
are global. By the time the pool.acquire(
function get's executed the for loop has completed and it is inserting the last customer twice. One possible solution would be to put an anonymous function inside the for loop e.g. (it doesn't have to be anonymous though)
for (var i = 0; i < customers.length; i++) {
(function(count, firstName) {
...do insert here...
}(i, customers[i].firstname));
}