Telegram机器人开发问题:数据库查询结果仅输出至控制台,如何推送至用户?
问题分析与解决
先拆解下你代码里的几个核心问题:
- 数据库查询成功后,你只在控制台打印了结果,完全没调用
ctx.reply()把结果推送给用户 catch块的逻辑完全错位:你引用了未定义的results变量,而且遍历结果的代码本该放在查询成功的分支里,catch是用来处理查询失败的场景- 还有个严重安全隐患:直接把用户输入的
text拼进SQL语句,会引发SQL注入攻击,必须用参数化查询修复
修正后的可运行代码
bot.on('message', async (ctx) => { const text = ctx.text; // 先判断用户是否发送了有效文本 if (!text) { ctx.reply('请输入要查询的关键词哦~'); return; } try { // 使用参数化查询避免SQL注入,同时明确查询类型 const [results] = await sequelize.query( "SELECT book FROM books t WHERE (t.*)::text LIKE :searchText", { replacements: { searchText: `%${text}%` }, type: sequelize.QueryTypes.SELECT } ); // 处理无匹配结果的情况 if (results.length === 0) { ctx.reply('没有找到匹配的书籍哦'); return; } // 遍历查询结果,逐条发送给用户 for (const result of results) { ctx.reply(result.book); } } catch (err) { // 错误处理:打印日志+给用户反馈 console.error('数据库查询出错:', err); ctx.reply('查询出错了,请稍后再试'); } });
关键修改说明
- 改用async/await:比Promise链式调用更简洁直观,代码可读性大幅提升
- 增加输入校验:避免用户发送空消息时触发无效查询
- 参数化查询:用
:searchText作为占位符,通过replacements传递参数,彻底杜绝SQL注入风险 - 结果逻辑归位:把遍历发送结果的代码移到查询成功的
try块内,同时处理无结果的边界场景 - 错误处理优化:
catch块只负责捕获异常,打印错误日志并给用户友好提示
这样修改后,查询到的结果就能正常推送给用户,同时解决了安全隐患和逻辑错误问题。
内容的提问来源于stack exchange,提问作者anonym
相关产品推荐
相关产品推荐

