如何解决查询有效但无法检索数据
我是 Node.js 的新手(总共 3 天的经验)。我正在使用 Node.js 和乏味的包来查询数据库(azure sql)。我使用此处解释的示例:https://docs.microsoft.com/en-us/azure/azure-sql/database/connect-query-nodejs?tabs=macos
const connection = new Connection(config);
// Attempt to connect and execute queries if connection goes through
connection.on("connect",err => {
if (err) {
console.error(err.message);
} else {
console.log("Reading rows from the Table...");
// Read all rows from table
const request = new Request(
"SELECT * FROM clients",(err,rowCount,columns) => {
if (err) {
console.error(err.message);
} else {
console.log(`${rowCount} row(s) returned`);
}
}
);
request.on("row",columns => {
columns.forEach(column => {
console.log("%s\t%s",column.Metadata.colName,column.value);
});
});
connection.execsql(request);
}
});
我有两个问题:
- 我不知道如何将查询到的数据放入一个对象中
- 如果我运行脚本,它确实会将项目打印到控制台,但在完成后它不会关闭连接。如果我在底部添加一个
connection.close()
,它将在完成之前关闭连接。我感觉 node.js 会同时执行所有内容(我已经习惯了 Python ......)。
更新
我找到了一种关闭连接的方法,据我所知,请求对象有几个由库预定义的“事件”。似乎我需要通过 request.on('done',...)
添加事件“完成”以确保它甚至可以完成。我更新后的代码如下所示:
var connection = new Connection(config);
connection.connect(function(err) {
// If no error,then good to go...
executeStatement();
}
);
connection.on('debug',function(text) {
//remove commenting below to get full debugging.
//console.log(text);
}
);
function executeStatement() {
request = new Request("SELECT * FROM clients",function(err,rowCount) {
if (err) {
console.log(err);
} else {
console.log(rowCount + ' rows');
}
connection.close();
});
request.on('row',function(rows) {
_.forEach(rows,function(value,collection){
console.log(value)
console.log(value.value);
console.log(value.Metadata.colName)
console.log(collection)
})
});
request.on('done',function(rowCount,more) {
console.log(rowCount + ' rows returned');
});
// In sql Server 2000 you may need: connection.execsqlBatch(request);
connection.execsql(request);
}
无论如何,您的帮助将不胜感激!
问候 彼得
解决方法
可以先自定义一个类,然后声明一个Array来保存对象,例如:
let sales = new Array();
class SalesLT{
constructor(catagryName,productName){
this.catagryName = catagryName;
this.productName = productName;
}
这里我的 sql 语句返回 2 个属性,所以每次循环从 ColumnValue[]
中取出两个元素。
request.on("row",columns => {
for(let i=0; i<columns.length; i=i+2){
let sale = new SalesLT(columns[i].value,columns[i+1].value);
sales.push(sale);
}
sales.forEach( item => {
console.log("%s\t%s",item.catagryName,item.productName)
})
});
代码如下:
const { Connection,Request } = require("tedious");
let sales = new Array();
class SalesLT{
constructor(catagryName,productName){
this.catagryName = catagryName;
this.productName = productName;
}
}
// Create connection to database
const config = {
authentication: {
options: {
userName: "<***>",// update me
password: "<***>" // update me
},type: "default"
},server: "<****>.database.windows.net",// update me
options: {
database: "<***>",//update me
encrypt: true
}
};
const connection = new Connection(config);
// Attempt to connect and execute queries if connection goes through
connection.on ("connect",err => {
if (err) {
console.error(err.message);
} else {
queryDatabase();
}
});
function queryDatabase() {
console.log("Reading rows from the Table...");
// Read all rows from table
const request = new Request(
`SELECT TOP 2 pc.Name as CategoryName,p.name as ProductName
FROM [SalesLT].[ProductCategory] pc
JOIN [SalesLT].[Product] p ON pc.productcategoryid = p.productcategoryid`,(err,rowCount) => {
if (err) {
console.error(err.message);
} else {
console.log(`${rowCount} row(s) returned`);
}
connection.close();
}
);
request.on("row",columns[i+1].value);
sales.push(sale);
}
sales.forEach( item => {
console.log("%s\t%s",item.productName)
})
});
connection.execSql(request);
}
,
包tedious
是同步包,它使用回调返回结果。因此,当我们调用 connection.close()
时,它将禁用连接并停止回调函数。如果想关闭连接,建议使用async
包来实现。
例如
const { Connection,Request } = require("tedious");
const async = require("async");
const config = {
authentication: {
options: {
userName: "username",// update me
password: "password",// update me
},type: "default",},server: "your_server.database.windows.net",// update me
options: {
database: "your_database",//update me
encrypt: true,validateBulkLoadParameters: true,};
const connection = new Connection(config);
let results=[]
function queryDatabase(callback) {
console.log("Reading rows from the Table...");
// Read all rows from table
const request = new Request("SELECT * FROM Person",rowCount) => {
if (err) {
callback(err);
} else {
console.log(`${rowCount} row(s) returned`);
callback(null);
}
});
request.on("row",(columns) => {
let result={}
columns.forEach((column) => {
result[column.metadata.colName]=column.value
console.log("%s\t%s",column.metadata.colName,column.value);
});
// save result into an array
results.push(result)
});
connection.execSql(request);
}
function Complete(err,result) {
if (err) {
callback(err);
} else {
connection.close();
console.log("close connection");
}
}
connection.on("connect",function (err) {
if (err) {
console.log(err);
} else {
console.log("Connected");
// Execute all functions in the array serially
async.waterfall([queryDatabase],Complete);
}
});
connection.connect();
此外,您还可以使用包 mssql
。它支持异步方法并依赖于包 tedious
。查询后我们可以直接调用close
。
例如
const mssql = require("mssql");
const config = {
user: "username",password: "password",database: "your_database",options: {
encrypt: true,enableArithAbort: true,};
let pool = new mssql.ConnectionPool(config);
async function query() {
try {
await pool.connect();
const request = pool.request();
const result = await request.query("SELECT * FROM Person");
console.dir(result.recordset);
await pool.close();
console.log(pool.connected);
} catch (error) {
throw error;
}
}
query().catch((err) => {
throw err;
});
,
这篇文章应该可以帮助您解决您面临的所有问题……这与我开始使用 Node 时遇到的问题相同 :)
https://devblogs.microsoft.com/azure-sql/promises-node-tedious-azure-sql-oh-my/
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。