为何JavaScript中SQLite3的UPDATE操作this.changes值不稳定?求解决
SQLite3 UPDATE操作中this.changes有时为0的原因及解决办法
问题原因分析
- 内存与数据库数据不同步:你的代码先从内存
data数组查找noteId,找到后才执行数据库UPDATE,但如果data数组存在该noteId,但数据库中对应的记录已删除或从未存在,UPDATE语句找不到匹配行,this.changes就会返回0。 - 点赞逻辑的状态不一致:你依赖内存里的
item.hasLiked判断是否执行点赞,但用户刷新页面后,内存data数组会重新加载,hasLiked状态重置,此时若用户再次点击,即使cookie存在,仍会触发UPDATE;但如果数据库中noteId对应的记录不存在,依然会出现this.changes=0的情况。 - noteId类型不匹配:你把
noteId转成了整数,但如果数据库中noteId字段是字符串类型,WHERE noteId = ?的匹配会失败,导致UPDATE无生效行。
解决办法
1. 先校验数据库记录是否存在
执行UPDATE前先查询数据库,确认noteId对应的记录存在,避免无意义的UPDATE操作:
app.post("/like/:noteId", (req, res) => { shuf = false; const noteId = parseInt(req.params.noteId.trim()); // 先检查cookie是否已点赞,直接拦截重复请求 const hasLiked = req.cookies[`liked_${noteId}`]; if (hasLiked === "true") { return res.redirect("/"); } // 先查询数据库确认记录存在 db.get("SELECT * FROM data WHERE noteId = ?", [noteId], (err, row) => { if (err) { console.log(err.message); return res.status(500).send("服务器错误"); } if (!row) { return res.status(404).send("目标笔记不存在"); } // 执行UPDATE操作 db.run("UPDATE data SET Like = Like + 1 WHERE noteId = ?", [noteId], function(err) { if (err) { console.log(err.message); return res.status(500).send("点赞失败"); } if (this.changes === 0) { return res.status(500).send("点赞未生效,请重试"); } console.log(`Row(s) updated: ${this.changes}`); // 更新内存数据 const itemIndex = data.findIndex(item => item.noteId === noteId); if (itemIndex !== -1) { const item = data[itemIndex]; item.like++; item.hasLiked = true; // 移到数组开头 data.splice(itemIndex, 1); data.unshift(item); } res.cookie(`liked_${noteId}`, "true"); res.redirect("/"); }); }); });
2. 统一状态判断逻辑
不要仅依赖内存data数组的状态,结合cookie和数据库查询结果双重校验,避免重复点赞或无效操作:
- 优先通过cookie判断用户是否已点赞,直接拦截重复请求
- 数据库查询作为兜底校验,确保操作的有效性
3. 确保noteId类型匹配
检查数据库中noteId字段的类型:
- 如果数据库中是整数类型,保持
parseInt转换 - 如果是字符串类型,去掉
parseInt,直接使用req.params.noteId.trim()作为参数传入
4. 调整内存数据更新时机
将内存数据的更新放在数据库操作成功之后,避免数据库操作失败但内存数据已修改的不一致情况。
内容的提问来源于stack exchange,提问作者Fathin
相关产品推荐
相关产品推荐

