我正在尝试在NodeJS Lambda函数中运行两个单独的查询。第一个插入单个记录,并将返回在后续查询中使用的订单号。第二个查询需要插入n
条记录(订单项),因此我一直在尝试使用async
节点库执行那些记录,如下所示。
我遇到了一个问题,要么根本不执行这些查询,要么仅插入一条记录与n
记录。我现在用API请求来提供它,因此引用的items
数组中应该有两个索引,导致两次迭代。
const sql = require('mssql');
const async = require('async');
(function() {
// ——- Database support ——- //
exports.handler = function(event, context, callback)
{
const config = {
user: 'my_user',
password: 'my_pass',
server: 'my_serv',
database: 'my_db',
options: {
encrypt: true
}
};
// Request Body
var body = event;
var items = body[1]["items"];
var addDateTimeRaw = body[1]["created_at"];
var splitDateTime = addDateTimeRaw.split(" ");
// SPROC params
var CustomerNumber = "1234";
var OrderDateString = splitDateTime[0];
var ShipVia = "UPS";
var FOB = "null";
var PaymentTerms = "CREDIT CARD";
var Discount = "0";
var OrderAmount = body[1]["total_price"].cents;
var PONumber = body[1]["_id"];
var Comment = "I am a comment";
var SalesPerson = "WA";
var IsShippingSameAsBilling = "X";
var TaxableAmount = body[1]["total_value"].cents;
var TaxState = "my_state";
var AddDate = splitDateTime[0];
var AddTime = splitDateTime[1];
var WebOrderNumber = body[1]["_id"];
sql.connect(config, (err) => {
if (err) {
console.log(err);
callback(err);
} else {
const req = new sql.Request();
req.query('EXEC InsertOrder @CustomerNumber = "' + CustomerNumber + '", @OrderDateString = "' + OrderDateString + '", @ShipVia = "' + ShipVia + '", @FOB = "' + FOB + '", @PaymentTerms = "' + PaymentTerms + '", @Discount = "' + Discount + '", @OrderAmount = "' + OrderAmount + '", @PONumber = "' + PONumber + '", @Comment = "' + Comment + '", @SalesPerson = "' + SalesPerson + '", @IsShippingSameAsBilling = "' + IsShippingSameAsBilling + '", @TaxableAmount = "' + TaxableAmount + '", @TaxState = "' +TaxState + '", @AddDate = "' + AddDate + '", @AddTime = "' + AddTime + '", @WebOrderNumber = "' + WebOrderNumber + '";', (error, result) => {
if (error) {
console.log(error);
callback(error);
} else {
var OrderNumber = result.recordset[0].sono;
insertOrderItems(OrderNumber);
sql.close();
context.succeed(result.recordset)
return JSON.stringify(items);
}
});
function insertOrderItems(OrderNumber) {
async.forEachOf(items, function (item, i, inner_callback){
//var itemNumber = item["sku"];
var ItemNumber = "5678";
var DiscountPercent = "0";
var TaxRate = "6";
var Quantity = item["quantity"];
var ItemSequence = i + 1;
var CustomerMemo = "I am a memo";
var UnitPrice = "6.00";
var ssql = 'EXEC InsertOrderItems @OrderNumber = "' + OrderNumber + '", @ItemNumber = "' + ItemNumber + '", @DiscountPercent = "' + DiscountPercent + '", @TaxRate = "' + TaxRate + '", @Quantity = "' + Quantity + '", @ItemSequence = "' + ItemSequence + '", @CustomerMemo = "' + CustomerMemo + '", @UnitPrice = "' + UnitPrice + '";';
req.query(ssql, function(err, members, fields){
if(!err){
console.log(members);
//context.succeed(members.recordset)
inner_callback(null);
} else {
console.log("Error while performing Query");
inner_callback(err);
};
});
}, function(err){
if(err){
//handle the error if the query throws an error
callback(err);
}else{
//whatever you wanna do after all the iterations are done
callback(null);
}
});
}
}
});
sql.on('error', (err) => {
console.log(err);
callback(err);
});
};
}());
为什么对异步SQL查询的函数调用未执行?我正在尝试为两个已执行的查询保持相同的SQL连接打开。
答案 0 :(得分:1)
async
不是主要问题。我修补了一些地方,但情况仍然更糟。
为什么不逐步学习?
const sql = require('mssql');
const async = require('async');
const config = { ... };
exports.handler = function(event, context, callback) {
// Use default object with props or check existing of every props
var body = (event && event[1]) instanceof Object ? event[1] : {items: [], created_at: ' ', _id: ...};
var items = body.items || []; // Always use default value
var [addDate, addTime] = (created_at || '').split(' '); // Use destructuring assignment
// SPROC params
var CustomerNumber = "1234";
var OrderDateString = splitDateTime[0];
var ShipVia = "UPS";
var FOB = "null";
var PaymentTerms = "CREDIT CARD";
var Discount = "0";
var OrderAmount = parseFloat((body.total_price || {}).cents) || 0; // total_price can be non-object and it'll fall your app
var PONumber = body[1]["_id"];
var Comment = "I am a comment";
var SalesPerson = "WA";
var IsShippingSameAsBilling = "X";
var TaxableAmount = body[1]["total_value"].cents;
var TaxState = "my_state";
var WebOrderNumber = body._id;
sql.connect(config, (err) => {
// Early quit to avoid {}-ladder
if (err)
return callback(err);
const req = new sql.Request();
// Never do like this. Read about sql-injection. Use placeholders.
req.query('EXEC ost_InsertOrder @CustomerNumber = "' + ..., (err, result) => {
if (err)
return callback(err);
var OrderNumber = result.recordset.length && result.recordset[0].sono; // You must be sure that result has rows
// You should read about async-code
insertOrderItems(OrderNumber); // Here you start to insert items
sql.close(); // But before it'll success you close connection.
context.succeed(result.recordset);
// I didn't see definition of items.
// Return? For what?
return JSON.stringify(items);
});
...
}
});
sql.on('error', callback);
};