【问题标题】:In Node, how to execute sql from global database connection在 Node 中,如何从全局数据库连接执行 sql
【发布时间】:2019-01-27 12:50:12
【问题描述】:

在 node.js 中使用全局数据库连接时,我无法执行 sql。

我已按照 Azure 文档中的步骤操作:https://docs.microsoft.com/en-us/azure/mysql/connect-nodejs 并且能够在控制台上显示输出。但是,我想将所有 Azure SQL 数据库连接放在一个单独的文件中,但是选择查询不会在控制台上打印输出。

DatabaseManager.js

var Connection = require('tedious').Connection;
var Request = require('tedious').Request;


var sqlConnection = function sqlConnection() {
// Create connection to database
var config =
  {
    userName: 'uname',
    password: 'password',
    server: 'dbserver.database.windows.net',
    options:
        {
            database: 'mydatabase',
            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 
    {
        console.log('CONNECTED TO DATABASE');
   }

  }
 );
}
module.exports = sqlConnection;

app.js

var restify = require('restify');
var builder = require('botbuilder');
var botbuilder_azure = require("botbuilder-azure");
var azure = require('azure-storage');
var dbconnection = require('./DatabaseManager');

bot.dialog('profileDialog',
    (session) => {
      session.send('You reached the profile intent. You said \'%s\'.', session.message.text);

      console.log('Reading rows from the Table...');
        dbconnection("select FNAME from StudentProfile where ID=1"),
        function (err, result, fields) {
            if (err) throw err;
            console.log(result);
        }
          session.endDialog();   
    }

控制台输出:

正在从表中读取行...
连接到数据库

我期待 FNAME 的输出,但控制台上没有打印任何内容。有什么,我失踪了吗?

谢谢。

【问题讨论】:

  • 你为什么会这样想?在任何时候,您都不会实际执行该 SQL 语句。
  • @James,也许我这样做是错的。这是我的第一个 js 代码。我还尝试了类似 dbconnection.query() 的方法,但显示的方法无效。有什么建议可以纠正这个问题,以便执行查询?

标签: javascript node.js azure-sql-database node-modules


【解决方案1】:

这里有几个问题。首先,您应该只为每个文件导入一次模块。这只是性能方面的考虑,实际上不会破坏您的代码。

接下来,注意从 DatabaseManager 模块导出的内容。现在,您正在导出一个创建连接的函数,然后不对其进行任何操作。我们可以通过使用一种称为“回调”的模式来解决这个问题,它允许我们提供一个函数,然后将连接作为参数调用该函数。

我在解释事情的代码中添加了大量的 cmets。此代码不会按原样运行 - 有几个地方我有“做这个或这个”。你必须选择一个。

var Tedious = require('tedious'); // Only require a library once per file
var Connection = Tedious.Connection;
var Request = Tedious.Request;

// Or using the object spread operator
var { Connection, Request } = require('tedious');

// You called this `sqlConnection`. I'm going to use a verb since it's a
// function and not a variable containing the connection. I'm also going
// to change the declaration syntax to be clearer.

function connect(cb) { // cb is short for callback. It should be a function.
  var config = {
    userName: 'uname',
    password: 'password',
    server: 'dbserver.database.windows.net',
    options: {
      database: 'mydatabase',
      encrypt: true
    }
  }; // Put a semi-colon on your variable assignments

  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);
      return; // Stop executing the function if it failed
    }

    // We don't need an "else" because of the return statement above
    console.log('CONNECTED TO DATABASE');

    // We have a connection, now let's do something with it. Call the
    // callback and pass it the connection.
    cb(connection);
  });
}

module.exports = connect; // This exports a function that creates the connection

然后回到你的主文件,你可以像这样使用它。

var restify = require('restify');
var builder = require('botbuilder');
var botbuilder_azure = require('botbuilder-azure');
var azure = require('azure-storage');
var connect = require('./DatabaseManager'); // renamed to be a verb since it's a function.

bot.dialog('profileDialog', (session) => { // Hey, this is a callback too!
  session.send('You reached the profile intent. You said \'%s\'.', session.message.text);

  console.log('Creating a connection');

  connect((connection) => {
  // or with the traditional function notation
  connect(function(connection) {

    console.log('Reading rows from the Table...');

    // Execute your queries here using your connection. This code is
    // taken from 
    // https://github.com/tediousjs/tedious/blob/master/examples/minimal.js
    request = new Request("select FNAME from StudentProfile where ID=1", function(err, rowCount) { // Look another callback!
    if (err) {
      console.log(err);
    } else {
      console.log(rowCount + ' rows');
    }
    connection.close();
  });

  request.on('row', function(columns) {  // Iterate through the rows using a callback
    columns.forEach(function(column) {
      if (column.value === null) {
        console.log('NULL');
      } else {
        console.log(column.value);
      }
    });
  });

  connection.execSql(request);
});

【讨论】:

  • 你能举个例子,使用上面app.js中的连接来执行查询吗?
  • 感谢 3ocene,缺少执行 sql 的行。出于某种原因,我需要在 app.js 中再次包含繁琐的内容。否则,我得到,请求未定义。
  • 感谢您在我错过的行中进行编辑!是的,这是正确的。当您导入某些内容时,它仅在该文件中可用,而不是包含它的任何文件。如果 A 导入 B 导入 C,A 可以访问 B,B 可以访问 C,但 A 不能访问 C。
  • const/let over var,Promises over callbacks,并提供等效代码作为选项只是混淆了示例,箭头函数在适当的情况下优于 STD 函数。
  • @James,在不知道 Node OP 运行的版本的情况下,我不想做任何会导致示例中断的事情。但是,我确实想阻止任何人在不阅读代码的情况下复制粘贴代码。如果有我不知道的堆栈溢出样式指南,我很乐意遵守。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
  • 2019-09-06
  • 2021-04-23
相关资源
最近更新 更多