我目前的任务是编写一个应用程序,使用带有xlsx包的NodeJS将数据从Excel工作表传输到SQL Server表。
首先,我对异步编程的概念非常陌生,而且我也是使用NodeJS的新手。如果你能够彻底解释它,那将非常有帮助。
问题: 我的Excel表有8个列标题,我应该从第2行到结尾获取数据(类似于A2到H2,A3到H3,依此类推,直到行结束)。
我打电话 节点服务 在我的git-bash中。它将读取文件excel文件,每行循环访问它,console.log()就像这样:
Data of index 2000 7/10/16 20161007142953_BP12350 COV_DEB_20161007142953_BP12350 0 50000 3896 51 A 0145 Takengon / 3986 UNIT SIMPANG BALIK TAKENGON
Data of index 2001 7/10/16 20161007142954_BP12350 FEE_DEB_20161007142953_BP12350 0 50000 3896 51 A 0145 Takengon / 3986 UNIT SIMPANG BALIK TAKENGON
,然后我使用INSERT INTO查询它,如下面的runner.js所示。我想要做的是每次读取1000行间隔15000ms(因为每个excel文件大约有40,000行数据)。
有时我会收到Connection Timeout或UnhandledPromiseRejectionWarning错误。我该如何处理?
这是我的service.js
var util = require('util');
var sql = require('mssql');
var db = require('./doSql');
var runner = require('./runner');
var timeInterval = 15000;
var readData = setInterval(runner.readDataXL, timeInterval);
这是我的runner.js
var util = require('util');
var fs = require('fs');
var sql = require('mssql');
var db = require('./doSql');
var settings = require('./settings')
var async = require('async');
if (typeof require !== 'undefined') XLSX = require('xlsx');
var add = 50;
var runner = {
readDataXL: function () {
var workbook = XLSX.readFile(__dirname + '/file/test2.xlsx');
// var sheetname = workbook.Props.DocParts[0];
var sheetname = workbook.Props.SheetNames[0];
var length = (workbook.Sheets[sheetname]['!ref']).substr(4, workbook.Sheets[sheetname]['!ref'].length);
var effdate, kodebatch, transdesc, debit, kredit, user, id, branch = "";
// console.log(workbook);
var index = 1;
var indexj = 1;
async.each(workbook.Sheets[sheetname], function (item, callback) {
var dataAwal = item;
if (index > 9) {
switch (indexj) {
case 1:
effdate = dataAwal['w'];
indexj++;
break;
case 2:
kodebatch = dataAwal['w'];
indexj++;
break;
case 3:
transdesc = dataAwal['w'];
indexj++;
break;
case 4:
debit = dataAwal['w'];
indexj++;
break;
case 5:
kredit = dataAwal['w'];
indexj++;
break;
case 6:
user = dataAwal['w'];
indexj++;
break;
case 7:
id = dataAwal['w'];
indexj++;
break;
case 8:
branch = dataAwal['w'];
indexj++;
var all = util.format("Data of index " + parseInt(index / 8) + " " + effdate + " " + kodebatch + " " + transdesc + " " + debit + " " + kredit + " " + user + " " + id + " " + branch);
console.log(all);
var sqlgiropremi = "INSERT INTO [ownerList].dbo.Rekonsiliasi_Premi_Fahmi_Test values('" + effdate + "','" + kodebatch + "','" + transdesc + "','" + debit + "','" + kredit + "','" + user + "','" + id + "','" + branch + "','" + parseInt(index / 8) + "')";
db.executeSql(sqlgiropremi, function (data, err) {
if (err) {
console.log("sql : " + sqlgiropremi + "error : " + err)
} else {
console.log("success ");
}
});
indexj = 1;
break;
}
}
index++;
});
}
}
module.exports = runner;
这是我的doSql.js
var sqlDB = require('mssql');
var util = require('util');
var settings = require('./settings');
module.exports.executeSql = function (sql, callback) {
var conn = new sqlDB.ConnectionPool(settings.dbConfig);
conn.connect()
.then(function () {
var transaction = new sqlDB.Transaction(conn);
transaction.begin()
.then(function () {
var rolledBack = false;
transaction.on('rollback', function (aborted) {
rolledBack = true;
});
var request = new sqlDB.Request(transaction);
request.query(sql)
.then(function (recordset) {
transaction.commit()
.then(function (err) {
callback(recordset);
})
.catch(function (err) {
console.log("transaction error : ", err);
});
})
.catch(function (err) {
if (!rolledBack) {
transaction.rollback()
.then(function (err_) {
console.log(err);
callback(null, err);
})
.catch(function (err_) {
console.log("request error : ", err);
callback(null, err);
})
}
})
})
.catch(function (err) {
console.log("begin error : ", err);
callback(null, err);
});
})
.catch(function (err) {
console.log("connect error : ", err);
callback(null, err);
})
sqlDB.close();
}
有时我会获得成功条目,有时会出现这样的错误:
sql : INSERT INTO [ownerList].dbo.Rekonsiliasi_Premi_Fahmi_Test values('7/10/16','20161007142953_BP12350','COV_DEB_20161007142953_BP12350','0','50000','3896','51','A 0145 Takengon / 3986 UNIT
SIMPANG BALIK TAKENGON','2000')error : ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
connect error : { ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
at Connection.tedious.once.err (C:\Users\DELL\Node JS\XLSX\node_modules\mssql\lib\tedious.js:216:17)
at Connection.g (events.js:291:16)
at emitOne (events.js:96:13)
at Connection.emit (events.js:188:7)
at Connection.socketError (C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connection.js:699:14)
at C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connection.js:590:25
at Socket.onError (C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connector.js:48:9)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at emitErrorNT (net.js:1276:8)
code: 'ESOCKET',
originalError:
{ ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
at ConnectionError (C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\errors.js:12:12)
at Connection.socketError (C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connection.js:699:30)
at C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connection.js:590:25
at Socket.onError (C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connector.js:48:9)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at emitErrorNT (net.js:1276:8)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
message: 'Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433',
code: 'ESOCKET' },
name: 'ConnectionError' }
sql : INSERT INTO [ownerList].dbo.Rekonsiliasi_Premi_Fahmi_Test values('7/10/16','20161007142954_BP12350','FEE_DEB_20161007142953_BP12350','0','50000','3896','51','A 0145 Takengon / 3986 UNIT
SIMPANG BALIK TAKENGON','2001')error : ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
(node:3576) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
(node:3576) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 4): ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
(node:3576) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 6): ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
(node:3576) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 8): ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
(node:3576) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 10): ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
如果有更好的方法来循环或如何实现它,请指导我。
答案 0 :(得分:0)
我意识到我正在回答一个非常老的问题,但是由于发现该问题的代码很有帮助,所以我认为我也应该指出我看到的问题。
executeSql是从异步循环调用的,它本身也调用异步函数。我认为连接错误是由connect()调用引起的,该调用是在每次executeSql调用时产生的,这意味着当某些先前调用的连接仍在进行时,它可能会尝试连接。您可以通过将connect()调用移到executeSql函数之外来解决问题(但它仍可以位于doSql.js的顶部)。因此,连接仅建立一次,然后可用于多个查询。