我在Microsoft bot Framework中有一个机器人,我希望能够从azure SQL数据库中提取数据,以便回答向机器人提出的问题。我已经设置了数据库,里面有一些excel文件。
这是我现在的代码:
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var connection = new Connection(dataconfig);
connection.on('connect', function(err) {
console.log("Connected");
executeStatement();
});
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
function executeStatement() {
request = new Request("select \"Product Name\" from SPA_Data_Feeds where \"Strategic Priority\" = 'Accelerate to Value (LD)'",
function(err, rowCount, rows)
{
console.log(rowCount + ' row(s) returned');
}
);
var result = "";
var count = 0
request.on('row', function(columns) {
columns.forEach(function(column) {
console.log("%s\t", column.value);
result+= column.value + "\t\n";
count++;
if ( count == rowCount ) {
ATVData(result);
} ;
});
});
connection.execSql(request);
}
function ATVData(result) { //Puts "result" inside of an adaptive card }
我似乎无法弄清楚如何使if语句正确。 rowCount不起作用,因为它不会等到它首先被函数定义,并且我尝试使用诸如column(s)。length,result(s).length之类的东西但是没有工作。
我还能用其他东西来完成if语句吗?或者我是否需要以回调/承诺的方式重新格式化以使其等待定义rowCount?如果可以,我可以就此提出一些建议吗?
答案 0 :(得分:1)
我还能用其他东西来完成if语句吗?或者我是否需要以回调/承诺的方式重新格式化以使其等待定义rowCount?如果可以,我可以就此提出一些建议吗?
我们可以使用Q.js作为JavaScript Promise实现之一来解决此问题。例如:
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var q = require('q');
// Create connection to database
var config =
{
userName: '', // update me
password: '', // update me
server: '', // update me
options:
{
database: '' //update me
, encrypt: true
}
}
var connection = new Connection(config);
// Attempt to connect and execute queries if connection goes through
connection.on('connect', function(err)
{
if (err)
{
console.log(err)
}
else
{
queryDatabase().then(function(result){
ATVData(result);
}, function(err){
console.log(err);
});
}
}
);
function queryDatabase()
{
console.log('Reading rows from the Table...');
//create a promise
var deferred = q.defer();
// Read all rows from table
var result = [];
var request = new Request(
"SELECT * From ForumMessages",
function(err, rowCount)
{
deferred.resolve(result);
});
request.on('row', function(columns) {
columns.forEach(function(column) {
console.log("%s\t%s", column.metadata.colName, column.value);
result.push(columns);
});
});
connection.execSql(request);
//return the promise
return deferred.promise;
}
function ATVData(result){
//your bot code goes here
}
答案 1 :(得分:0)
我想扩展Grace的答案,对于每一行,你也可以为一些实用程序做这个:
request.on('row', function(columns) {
var singleResult = {};
columns.forEach(function(column) {
console.log("%s\t%s", column.metadata.colName, column.value);
// Add a property to the singleResult object.
singleResult[column.metadata.colName] = column.value;
// Push the singleResult object to the array.
result.push(singleResult);
});
});
然后,您可以在机器人的代码中使用点表示法通过属性名称调用每个对象,例如:result[x].colName
其中colName是列的名称(在这种情况下是对象属性)。
示例(假设数据库中至少有一个结果项,带有数据的“链接”列):
var adaptiveCardExample = {
'contentType': 'application/vnd.microsoft.card.adaptive',
'content': {
'$schema': 'http://adaptivecards.io/schemas/adaptive-card.json',
'type': 'AdaptiveCard',
'version': '1.0',
'body': [
{
"type": "TextBlock",
"text": "Code Example"
},
{
"type": "TextBlock",
"text": "We're going to " + result[0].link,
"wrap": true
}],
'actions': [
{
'type': 'Action.OpenUrl',
'title': 'Go to the example link',
'url': result[0].link
}
]
}
};
var adaptiveCardMsg = new builder.Message(session).addAttachment(adaptiveCardExample);
session.send(adaptiveCardMsg);
作为预防措施,如果属性是数据库中的可空字段,您可能需要为该属性添加null或undefined检查。