SELECT
返回结构
const [rows, fields] = await db.query('SELECT * FROM folders');
返回:
rows
: 是一个数组,包含所有查到的记录。fields
: 是字段的结构定义(列信息),一般不用。
rows
是一个数组,包含所有查到的记录:
[
{ id: 1, name: '一级选项1', parent_id: null },
{ id: 2, name: '子目录1', parent_id: 1 }
]
INSERT
返回结构
const [result] = await db.query('INSERT INTO folders (name, parent_id) VALUES (?, ?)', ['test', 1]);
result
是一个包含插入信息的对象:
{
fieldCount: 0, // 字段数(一般是 0,插入不返回字段)
affectedRows: 1, // 受影响的行数
insertId: 17, // 新插入的主键 ID
serverStatus: 2, // MySQL 服务器状态码
warningCount: 0, // 警告数量,0 表示无警告
message: '', // 服务器返回的信息,一般为空或插入成功消息
protocol41: true, // 与协议有关,true 表示使用 4.1 协议
changedRows: 0 // 插入时恒为 0,仅在 UPDATE 时有意义
}
所以判断成功的办法是通过 affectedRows
:
if (result.affectedRows === 1) {
return res.status(200).json({
message: '目录添加成功',
folderId: result.insertId
});
} else {
return res.status(500).json({ error: '添加目录失败' });
}
UPDATE
返回结构:
const [result] = await db.query('UPDATE folders SET name = ? WHERE id = ?', ['newName', 17]);
result
内容:
{
fieldCount: 0,
affectedRows: 1, // 匹配并执行更新的行数(包括实际没变内容的)
insertId: 0, // 无插入则为 0
serverStatus: 2,
warningCount: 0,
message: '(Rows matched: 1 Changed: 1 Warnings: 0)',
protocol41: true,
changedRows: 1 // 实际内容发生变化的行数
}
DELETE
返回结构:
const [result] = await db.query('DELETE FROM folders WHERE id = ?', [17]);
result
内容:
{
fieldCount: 0,
affectedRows: 1, // 删除成功的行数
insertId: 0,
serverStatus: 2,
warningCount: 0,
message: '', // 有时会包含删除说明
protocol41: true,
changedRows: 0 // 始终为 0,DELETE 不用这个字段
}
不能随便“模拟”结构解构,必须清楚它的真实结构是数组 [rows, fields]
,否则会出错。
❌ 错误示例:
const { affectedRows } = await db.query(...); // ❌ 报错,因为它不是对象,是数组
✅ 正确示例:
const [result] = await db.query(...); // result 是对象
console.log(result.affectedRows); // 访问插入/更新结果
总结
场景 | 返回值结构 | 解构方式 |
---|---|---|
SELECT | [rows, fields] | [rows] 或 [rows, fields] |
INSERT/UPDATE/DELETE | [result, undefined] | [result] |
由于
- 新增
result.affectedRows === 1
; - 编辑
result.affectedRows > 0
更新语句执行了,result.changedRows > 0
内容确实有变更; - 删除
result.affectedRows > 0
;
1.回调方式
标准写法!!
db.query(sql, params, (err, results) => {
if (err) {
// 处理错误
} else {
// results 中包含 SQL 执行结果
}
});
2.await + Promise 方式
新增
const [result] = await db.query('INSERT INTO folders (name) VALUES (?)', ['Test']);
if (result.affectedRows === 1) {
console.log('插入成功,ID:', result.insertId);
} else {
console.log('插入失败');
}
编辑
const [result] = await db.query('UPDATE folders SET name = ? WHERE id = ?', ['NewName', 5]);
if (result.affectedRows > 0) {
console.log('更新语句执行了');
if (result.changedRows > 0) {
console.log('内容确实有变更');
} else {
console.log('字段值没变(例如改成原来的值)');
}
} else {
console.log('没有任何记录被更新');
}
删除
const [result] = await db.query('DELETE FROM folders WHERE id = ?', [999]);
if (result.affectedRows > 0) {
console.log('删除成功');
} else {
console.log('未删除任何记录(可能 id 不存在)');
}
最实用的判断逻辑:
try {
const [result] = await db.query(sql, values);
if (result.affectedRows > 0) {
// ✅ SQL 生效
} else {
// ⚠️ SQL 没生效(可能条件不匹配)
}
} catch (err) {
// ❌ SQL 执行失败(语法、连接、权限等错误)
}