简体   繁体   中英

Inserting more than one record with Node.js and Tedious

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 eg (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));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM