Preencha Azure Mobile Services a partir do Programador
-
21-12-2019 - |
Pergunta
Eu criei um código como este para obter notícias de exportação de xml a partir de outro site e estou tentando preencher com meu banco de dados.
function UpdateLunchTime() {
var httpRequest = require('request');
var xml2js = require('xml2js');
var parser = new xml2js.Parser();
var url = 'http://www...com/export/xml/actualities';
httpRequest.get({
url: url
}, function(err, response, body) {
if (err) {
console.warn(statusCodes.INTERNAL_SERVER_ERROR,
'Some problem.');
} else if (response.statusCode !== 200) {
console.warn(statusCodes.BAD_REQUEST,
'Another problem');
} else {
//console.log(body);
parser.parseString(body, function (err2, result) {
//console.log(result.Root.event);
var count = 0;
for (var i=0;i<result.Root.event.length;i++)
{
//console.log(result.Root.event[i]);
InsertActionToDatabase(result.Root.event[i]);
}
/*
result.Root.event.forEach(function(entry) {
InsertActionToDatabase(entry);
});
*/
});
}
});
}
function InsertActionToDatabase(action)
{
var queryString = "INSERT INTO Action (title, description, ...) VALUES (?, ?, ...)";
mssql.query(queryString, [action.akce[0], action.description[0],...], {
success: function(insertResults) {
},
error: function(err) {
console.log("Problem: " + err);
}
});
}
Para o indivíduo realidade ele está funcionando bem, mas quando eu executar sobre toda a xml recebo este erro:
Error: [Microsoft][SQL Server Native Client 10.0][SQL Server]Resource ID : 1. The request limit for the database is 180 and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance.
E por último objetos recebo este erro:
Error: [Microsoft][SQL Server Native Client 10.0]TCP Provider: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Obrigado pela ajuda
Solução
O problema é que você está tentando fazer muitas simultâneas (inserir) para as operações no banco de dados.Lembre-se que em node.js (quase) tudo é assíncrono, então quando você chamar InsertActionToDatabase
para um dos itens, esta operação irá iniciar imediatamente e não esperar antes de terminar para voltar.Então você está basicamente tentando inserir todos os eventos de uma só vez, e como a mensagem de erro disse que há um limite no número de conexões simultâneas que podem ser feitas para o SQL server.
O que você precisa fazer é alterar seu loop para executar de forma assíncrona, esperando por uma das operações para concluir antes de iniciar o seguinte (você também pode "lote" de enviar um número menor de operações de uma só vez, continuando depois de cada lote está completo, mas o código é um pouco mais complicado), conforme mostrado abaixo.
var count = result.Root.event.length;
var insertAction = function(index) {
if (index >= count) return;
InsertActionToDatabase(result.Root.event[i], function() {
insertAction(index + 1);
});
}
insertAction(0);
E o InsertActionToDatabase
função levaria um parâmetro de callback para ser chamado quando ele é feito.
function InsertActionToDatabase(item, done) {
var table = tables.getTable('event');
table.insert(item, {
success: function() {
console.log('Inserted event: ', item);
done();
}
});
}