如何在Node.js中向MySQL查询回调函数传递参数

28

我正在尝试找出向查询调用传递自定义数据以在回调中使用的正确方法。 我在nodejs中使用MySQL库(所有最新版本)。

我有一个对connection.query(sql, function(err, result) {...});的调用。

我找不到以下操作的方法:1)传递自定义数据/参数到调用中,以便2)在回调被调用时可以使用它。 因此,应该如何正确做到这一点?

我有以下伪代码:

...
for (ix in SomeJSONArray) {
    sql = "SELECT (1) FROM someTable WHERE someColumn = " + SomeJSONArray[ix].id;
    connection.query(sql, function (err, result) {
      ...
      var y = SomeJSONArray[ix].id;
    };
}

从上面的代码中,我需要能够将查询中使用的"ix"当前值传递给回调函数本身。

我该如何做到这一点?

4个回答

53

如果你正在使用node-mysql,请按照文档中所说的方式进行:

connection.query(
    'SELECT * FROM table WHERE id=? LIMIT ?, 5',[ user_id, start ], 
    function (err, results) {

    }
);

文档中也提供了适当转义字符串的代码,但是在查询调用中使用数组会自动为您转义。

https://github.com/felixge/node-mysql


关于在回调函数中使用“ix”,可以将查询放入其自己的函数或自调用匿名函数中。(我还是太新了,无法编辑我的答案...) - Chris
2
谢谢Chris,但我的问题不在于SQL字符串本身内部数据的编码,而是关于传递额外数据以通过回调返回,这些数据不是结果集的一部分。正如您在我的示例中所看到的,ix值将是外部循环中当前值,而不是我在数组索引中使用的值。 - Julio
这就是为什么我添加了第一个注释。将整个查询包装在自调用的匿名函数中,这样当您到达回调时,“ix”不会改变。 - Chris
确实,如果我能在回调的范围内保持IX的值,那么是的,这将有所帮助,而不必想办法通过调用和回调传递数据。只是为了明确你的建议,你会如何在所有内容周围放置一个包装器匿名函数? - Julio

11
为了回答这个初始问题并举例说明,可以使用一个匿名函数包装回调函数,该函数会立即创建一个作用域,其中包含所传递数据的“快照”。
var ix=1;
connection.query('SELECT 1',
    (function(ix){
        return function(err, rows, fields) {
            console.log("ix="+ix);
            console.log(rows);
        };
    })(ix));

对于像我20分钟前一样不熟悉这个概念的人来说,最后的 })(ix)); 是传递给 (function(ix){ 的外部变量 ix=1 的值。如果您更改了 console.log("ix="+abc);,它可以重命名为 (function(abc){。

顺便说一句(感谢Chris提供的链接填补了空白,让我得以找到解决方案)。


这是对OP问题的解决方案。 - João Pimentel Ferreira

1

虽然使用之前描述的方法 -- 将回调函数包装在匿名函数中 -- 将变量或对象传递给 mysql 查询回调函数是可以的,但我认为这在很大程度上是不必要的,我将通过一个例子来解释原因:

// This actually works as expected!

function run_query (sql, y) {
    var y1 = 1;
    connection.query (sql, function (error, rows, fields) {

        if (! error)
        {
            var r = rows[0];

            console.log ("r = " + r[1]);
            console.log ("x = " + x);
            console.log ("y = " + y);
            console.log ("y1= " + y);
            console.log ("");
        }
        else
        {
            console.log ("error = " + error);
        }
    });
};

var x = 5;

console.log ("step 1: x = " + x);

run_query ("SELECT 1", x);

x = x + 1;

console.log ("step 2: x = " + x);

run_query ("SELECT 1", x);

x = x + 1;

console.log ("step 3: x = " + x);

产生以下输出:
step 1: x = 5
step 2: x = 6
step 3: x = 7
r = 1
x = 7
y = 5
y1= 5

r = 1
x = 7
y = 6
y1= 6

恐惧在于第二次调用run_query()会在第一次调用其回调函数之前覆盖变量y和/或y1。但是,每个调用run_query()函数的实例中的变量实际上是相互隔离的,从而挽救了局面。

你的查询中打印输出使用了 console.log("y1= " + y) 而不是 y1,我猜想它总是会打印出 1 作为 y1 的值? - Eric G

0

MySQL的con.query有重载函数。在回调函数内,您可以使用全局变量或传递到函数参数中的任何变量。例如:

示例1:它需要SQL字符串回调函数。

var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers;
con.query(sql, function (err, result) {
  if (err) throw err;
  console.log(adr);
});

示例2:它需要SQL字符串、参数回调函数

var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ?';
con.query(sql, [adr], function (err, result) {
  if (err) throw err;
  console.log(adr);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接