如何修复Discord.js机器人从MySQL数据库获取数据的问题
问题描述
我开发了一个Discord.js机器人的欢迎系统,会保存服务器(Guild)数据,成员加入时读取该数据,但从MySQL数据库获取数据时出现问题——成员加入服务器时,相关代码段直接跳过,未执行任何动作。
数据库表结构说明:表名为welcomes,包含guildId(存储服务器ID)和welcomeChannel(存储欢迎频道ID)两个字段。
相关代码如下:
run() async function run() { const db = await database.connect({ // 创建数据库连接 host: 'localhost', port: '3306', // 默认端口是3306 user: 'root', password: 'root123', database: 'database1', charset: 'utf8mb4' }); client.on(Events.GuildMemberAdd, async (member) => { console.log(`User ${member.user.username} (${member.id}) join guild and add to database`) db.query(`SELECT welcomeChannel FROM welcomes WHERE "guildId" = '${member.guild.id}';`, function(result){ console.log(`Result:${result}`) }) console.log("1") const embed = new EmbedBuilder() .setDescription(`Пользователь ${member} присоединился к серверу!`) //.setColor(embedcolor) //const channel = member.guild.channels.cache.get(Channelid) //channel.send({embeds: [embed]}) }) }; module.exports = {run}
修复方案
1. 修正SQL语句的字段名引号错误
MySQL中字段名需要用**反引号()**包裹,你当前用双引号包裹guildId`,会被识别为字符串常量,导致查询条件变成「字符串"guildId"等于服务器ID」,完全匹配不到数据。
修复后的SQL语句:
SELECT welcomeChannel FROM welcomes WHERE `guildId` = '${member.guild.id}';
2. 处理异步查询的逻辑顺序
db.query是异步操作,你当前的代码在查询还未返回结果时就执行了后续逻辑。如果要基于查询结果执行发送消息等操作,必须把相关逻辑放在查询的回调函数内部,确保数据就绪后再执行。
调整后的核心代码片段:
client.on(Events.GuildMemberAdd, async (member) => { console.log(`User ${member.user.username} (${member.id}) joined guild`); // 修复字段名引号+添加错误处理 db.query(`SELECT welcomeChannel FROM welcomes WHERE \`guildId\` = '${member.guild.id}';`, (error, results) => { // 先捕获数据库查询错误 if (error) { console.error('数据库查询出错:', error); return; } console.log(`查询结果:`, results); // 检查是否查询到对应服务器的配置 if (results.length === 0) { console.log(`未找到服务器 ${member.guild.id} 的欢迎配置`); return; } // 从结果中取出频道ID并发送消息 const channelId = results[0].welcomeChannel; const channel = member.guild.channels.cache.get(channelId); if (!channel) { console.log(`频道 ${channelId} 不存在或无法访问`); return; } const embed = new EmbedBuilder() .setDescription(`Пользователь ${member} присоединился к серверу!`); channel.send({ embeds: [embed] }); }); });
3. 修复SQL注入风险
直接将用户/服务器ID拼接进SQL语句存在注入风险,建议改用参数化查询:
// 参数化查询写法,用?作为占位符 db.query('SELECT welcomeChannel FROM welcomes WHERE `guildId` = ?;', [member.guild.id], (error, results) => { // 后续逻辑同上 });
4. 确认数据库连接状态
在数据库连接代码后添加日志,验证连接是否成功:
const db = await database.connect({ // 连接参数 }); console.log('数据库连接成功');
内容的提问来源于stack exchange,提问作者SLYTER POP
相关产品推荐
相关产品推荐

