Nodejs环境下遇到的MySQL奇怪问题

Nodejs环境下遇到的MySQL奇怪问题

var mMysql = require(‘mysql’);

function Select(aWhere,aCallback) { mConnection.query("select *from "+aWhere, function (err, results, fields) { return aCallback(results,fields); }); }

另外一个类里调用处

mMySql.Select(tTableName,function (a_results,a_fields )
{
     if(a_results.length!=0)
     {
        .....//省略若干
     }
});

现象:同样的参数调用,有的时候程序正常,有的时候会提示a_results.length错误,原因是results 为undefined 是在是不知道是怎么回事,希望路过的高手指点下


12 回复

Nodejs环境下遇到的MySQL奇怪问题

在Node.js环境下使用MySQL时,有时会遇到一些令人困惑的问题。以下是一个具体的例子,展示了如何通过一个简单的查询函数来获取数据,并且在某些情况下会遇到resultsundefined的问题。

示例代码

首先,我们定义一个用于查询的函数:

var mMysql = require('mysql');

// 创建数据库连接
var mConnection = mMysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'testdb'
});

mConnection.connect(function(err) {
    if (err) {
        console.error('Error connecting to MySQL:', err.stack);
        return;
    }
    console.log('Connected to MySQL as id ' + mConnection.threadId);
});

function Select(aWhere, aCallback) {
    mConnection.query("SELECT * FROM " + aWhere, function(err, results, fields) {
        if (err) {
            console.error('Query error:', err.message);
            return aCallback(null, null); // 返回null以避免错误
        }
        return aCallback(results, fields);
    });
}

在另一个类里调用该查询函数:

Select('users', function(a_results, a_fields) {
    if (!a_results) {
        console.log('No results found or an error occurred.');
        return;
    }

    if (a_results.length !== 0) {
        // 处理结果
        console.log('Found results:', a_results);
    } else {
        console.log('No rows found in the table.');
    }
});

问题描述

在上述代码中,有时候调用Select函数时,a_results会被赋值为undefined,导致后续的逻辑出错。这可能是由于以下几个原因:

  1. SQL注入风险:直接将用户输入拼接到SQL语句中可能导致SQL注入攻击。如果aWhere包含非法字符或恶意SQL代码,可能会导致查询失败。
  2. 数据库连接问题:如果数据库连接在执行查询之前就已经断开,或者连接超时,那么查询操作可能无法成功完成。
  3. 查询语法错误:如果aWhere中的表名不正确,或者查询条件有误,会导致查询返回空结果集,从而导致a_resultsundefined

解决方案

为了避免这些问题,建议采取以下措施:

  1. 使用预编译语句:使用预编译语句可以有效防止SQL注入,并提高查询的安全性。
  2. 检查数据库连接状态:确保在执行查询前数据库连接是有效的。
  3. 验证输入:对传入的aWhere进行验证,确保其符合预期格式。

改进后的代码示例如下:

function Select(aWhere, aCallback) {
    var query = "SELECT * FROM ??";
    mConnection.query(query, [aWhere], function(err, results, fields) {
        if (err) {
            console.error('Query error:', err.message);
            return aCallback(null, null);
        }
        return aCallback(results, fields);
    });
}

在这个改进版本中,使用了预编译语句(??)来避免SQL注入攻击,并且确保查询语句的正确性。这样可以大大减少出现undefined结果的情况。


SQL 不正确

"select *from "+aWhere

在Select 函数里面加一些有效性判断比较好: err 是否是 undefined, results是否是undefined results的长度判断 等等。

应该不是SQL不正确,参数是我写死的,每次穿进去的都一样

不好重现,恶心死了

求解答呢

用 node-inspector 加断点。出现错误的时候 debug。你的程序没贴全,别人也没法替你测试。 那个 "select *from " 是怎么回事?你的程序里不会这么用吧?

输出了一下error

{ [Error: connect ETIMEDOUT] code: ‘ETIMEDOUT’, errno: ‘ETIMEDOUT’, syscall: ‘connect’, fatal: true }

看错误貌似是连接重连了,但是不清楚是什么原因造成的,

function Select(aWhere,aCallback) {
  mConnection.query("select *from "+aWhere, function (err, results, fields) {
    if (err) throw new Error('记得检查这个err变量,如果err不为null,results和fields可能为空的');
    return aCallback(results,fields);
  });
}

在Node.js中,大家基本上接受这样的约定:

  • 回调函数的第一个参数用来表示是否出错(如果出错了则为出错信息,否则设置为null),第二个参数起才是返回值。
  • 在回调函数内部,应该首先判断第一个参数(出错信息)是否不为空,如果回调是带有出错信息,那么后面的参数是不确定的(可能有,也可能没有)
  • 如果不按照这种约定来做,你就为后面的程序挖了个很大的坑,不知道什么时候就一脚踩上去了
  • 仔细看看Node.js内置模块的API文档,看看人家都是怎么做的

学习了。我的callback凑巧符合这个约定:

function(error, docs, info)

受教了~

在Node.js环境下使用MySQL时,如果results有时为undefined,通常是因为查询出现了错误。你需要检查错误对象err是否包含错误信息。如果查询过程中出现错误,err将会不为nullundefined

以下是修改后的代码示例:

var mMysql = require('mysql');

function Select(aWhere, aCallback) {
    mConnection.query("SELECT * FROM " + aWhere, function (err, results, fields) {
        if (err) {
            return aCallback(err, null, fields); // 返回错误信息
        }
        aCallback(null, results, fields); // 正常返回结果
    });
}

在调用处:

mMySql.Select(tTableName, function (err, a_results, a_fields) {
    if (err) {
        console.error("Error during query: ", err);
        return;
    }

    if (a_results && a_results.length > 0) {
        // 处理结果
    } else {
        console.log("No results found");
    }
});

通过这种方式,你可以确保即使查询出错,也能正确处理错误信息。如果查询出错,err不会为nullundefined,因此你可以避免resultsundefined导致的错误。

此外,为了提高代码的安全性和可维护性,建议使用预编译语句或参数化查询,以防止SQL注入攻击。例如:

function Select(aWhere, aCallback) {
    var query = mConnection.query('SELECT * FROM ??', [aWhere], function (err, results, fields) {
        if (err) {
            return aCallback(err, null, fields);
        }
        aCallback(null, results, fields);
    });
}

这样可以更安全地处理表名和其他动态输入。

回到顶部