
sqlite 不支持 sql server 风格的 `output` 子句,但自 3.35.0 版本起原生支持标准 sql 的 `returning` 子句,可直接在 `insert` 后返回新插入行的指定字段(包括自增主键),完美替代 `output inserted.*`。
SQLite 是轻量级嵌入式数据库,其语法与 PostgreSQL/SQL Server 等有明显差异。你遇到的 SQLITE_ERROR: near "OUTPUT": syntax error 错误,根本原因是 OUTPUT 是 SQL Server 专有语法,SQLite 完全不识别。幸运的是,SQLite 从 3.35.0 版本(2021 年 3 月发布)开始正式支持 RETURNING 子句,它功能等效且更符合 SQL 标准。
✅ 正确写法(推荐):
INSERT INTO articles( creation_date, publish_date, last_modified_date, title, subtitle, article_text, likes, author_id, published ) VALUES ( CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, ?, ?, ?, ?, ?, ? ) RETURNING *;
⚠️ 注意事项:
- RETURNING 必须紧跟在 VALUES(或 SELECT)子句之后,不能加逗号或分号隔开;
- RETURNING * 返回整行(含自增 rowid 或显式定义的 INTEGER PRIMARY KEY 字段),也可指定列,如 RETURNING id, title, created_at;
- Node.js 中需确保使用的 SQLite 驱动(如 sqlite3)底层链接的是 ≥3.35.0 的 SQLite 库(可通过 sqlite3 --version 或 db.get('SELECT sqlite_version()') 验证);
- 若使用较旧版本 SQLite(
? 进阶优化:简化时间戳逻辑
与其每次 INSERT 都显式传入 CURRENT_TIMESTAMP,不如在建表时设置默认值,既提升可读性,又避免应用层出错:
CREATE TABLE articles ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, subtitle TEXT, article_text TEXT, likes INTEGER DEFAULT 0, author_id INTEGER, published BOOLEAN DEFAULT FALSE, creation_date TEXT DEFAULT CURRENT_TIMESTAMP, publish_date TEXT DEFAULT CURRENT_TIMESTAMP, last_modified_date TEXT DEFAULT CURRENT_TIMESTAMP );
随后插入语句可大幅精简,且 RETURNING 仍生效:
INSERT INTO articles(title, subtitle, article_text, likes, author_id, published) VALUES (?, ?, ?, ?, ?, ?) RETURNING id, title, creation_date;
? 总结:
- ✅ 永远用 RETURNING 替代 OUTPUT(后者在 SQLite 中非法);
- ✅ 优先通过 DEFAULT CURRENT_TIMESTAMP 减少冗余参数;
- ✅ 生产环境务必检查 SQLite 版本兼容性;
- ✅ RETURNING 是原子操作,线程安全,无需额外事务封装。
这样修改后,你的 global.db.all(...) 将成功返回插入后的完整行数据,rows[0].id 即为新生成的主键值。










