微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

查询有效但无法检索数据

如何解决查询有效但无法检索数据

我是 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);
    }
});

我有两个问题:

  1. 我不知道如何将查询到的数据放入一个对象中
  2. 如果我运行脚本,它确实会将项目打印到控制台,但在完成后它不会关闭连接。如果我在底部添加一个 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();

enter image description here

此外,您还可以使用包 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;
});

enter image description here

,

这篇文章应该可以帮助您解决您面临的所有问题……这与我开始使用 Node 时遇到的问题相同 :)

https://devblogs.microsoft.com/azure-sql/promises-node-tedious-azure-sql-oh-my/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。