为什么第一个程序有效,而第二个程序却无效?

时间:2018-08-01 18:23:23

标签: javascript mysql sql node.js database

var mysql = require('mysql')

var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'user',
  password : 'pass',
  database : 'mydb'
})

var values = [ ['Dave', 20],
                    ['Judd', 22],
                    ['Snek', 24],
                    ['Dale', 26] 
            ];

connection.connect(function(err) {
  if (err) {
    return console.error('error: ' + err.message);
  }

  let createTodos = `create table if not exists siblings(
                          id int primary key auto_increment,
                          name varchar(255)not null,
                          age tinyint(2) not null default 0
                      )`;

  connection.query(createTodos, function(err, results, fields) {
    if (err) {
      console.log(err.message);
    }
  });

  var sql = 'insert into siblings (name, age) values ?';
connection.query(sql, [values], function (err, result) {
    if (err) throw err;
    console.log("Number of records inserted: " + result.affectedRows);
  });
});

这工作得很好,并且达到了我的预期,如果该表尚不存在,则使用名称和年龄列创建该表,然后在值数组中相应地插入值。

这不起作用

var mysql = require('mysql')

var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'user',
  password : 'pass',
  database : 'mydb'
})

var values = [ ['Dave', 20],
                    ['Judd', 22],
                    ['Snek', 24],
                    ['Dale', 26] 
            ];

connection.connect(function(err) {
  if (err) {
    return console.error('error: ' + err.message);
  }

  let createTodos = `create table if not exists siblings(
                          id int primary key auto_increment,
                          name varchar(255)not null,
                          age tinyint(2) not null default 0
                      )`;

  connection.query(createTodos, function(err, results, fields) {
    if (err) {
      console.log(err.message);
    }
  });

});

var sql = 'insert into siblings (name, age) values ?';
    connection.query(sql, [values], function (err, result) {
        if (err) throw err;
        console.log("Number of records inserted: " + result.affectedRows);
      });

区别在于,插入values数组的查询不在connect函数调用之外。我知道这一定与传递给连接的回调函数以及它们可能是异步函数有关,但是有人可以纠正我或对此进行进一步阐述吗?节点的控制流程使我望而却步。

3 个答案:

答案 0 :(得分:1)

您需要先连接到数据库,然后才能对数据库执行查询。

connection.connect()是一个异步函数,这意味着当您调用它时,它开始连接到数据库并立即返回。您的代码继续进行,当您尝试执行查询时,数据库尚未连接到数据库。

这就是在连接回调中执行查询很重要的原因。连接数据库后,当数据库成功(或未成功)完成连接时,回调函数将允许您的代码继续。

我强烈建议您阅读异步编程,并研究promise / await语法。它们本质上是通过将所有内容整齐地链接而不是涉及许多回调层来阻止代码。

promise-mysql软件包使您的污垢变得简单:

const mysql = require('promise-mysql');

const connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'user',
  password : 'pass',
  database : 'mydb'
});

const values = [
  ['Dave', 20],
  ['Judd', 22],
  ['Snek', 24],
  ['Dale', 26] 
];

async main() {
  const dbErr = await connection.connect();
  if (dbErr) {
    return console.error('error: ' + dbErr.message);
  }

  {
    const createTodos = `create table if not exists siblings(
      id int primary key auto_increment,
      name varchar(255)not null,
      age tinyint(2) not null default 0
    )`;
    const [err, results, fields] = await connection.query(createTodos);
  }

  {
    const insertSiblings = 'insert into siblings (name, age) values ?';
    const [err, results, fields] = await connection.query(insertSiblings);

    console.log("Number of records inserted: " + result.affectedRows);
  }
}

// Call the async function
main();

答案 1 :(得分:0)

问题是大概连接操作需要一些时间才能完成。在第一个示例中,由于后续调用包含在回调中,因此仅在建立与数据库的连接之后才发生。

在第二种情况下,由于查询位于要连接的回调之外,因此在建立连接之前尝试进行查询,因此失败。

即使在第一个示例中,在创建表的调用与随后的查询表之间也存在相同的错误。但是创建表的调用发生得如此之快,以至于在大多数情况下它只是可以工作,但是您肯定会不时看到失败。

使用回调编写此序列的正确方法是像这样将它们链接起来:

var mysql = require('mysql')

var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'user',
  password : 'pass',
  database : 'mydb'
})

var values = [ ['Dave', 20],
                    ['Judd', 22],
                    ['Snek', 24],
                    ['Dale', 26] 
            ];

connection.connect(function(err) {
  if (err) {
    return console.error('error: ' + err.message);
  }

  // this happens only after the connect operation is complete
  let createTodos = `create table if not exists siblings(
                          id int primary key auto_increment,
                          name varchar(255)not null,
                          age tinyint(2) not null default 0
                      )`;

  connection.query(createTodos, function(err, results, fields) {
    if (err) {
      console.log(err.message);
    }

    // this happens only after the connect & create table are complete
    var sql = 'insert into siblings (name, age) values ?';
    connection.query(sql, [values], function (err, result) {
      if (err) throw err;
      // this happens only after connect, create & insert are complete
      console.log("Number of records inserted: " + result.affectedRows);
    });
  });
});

答案 2 :(得分:-1)

在第二个代码上,将查询置于connection.connect(function(err){

第一个在里面。