You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用better-sqlite3更新数据库行值时遭遇SqliteError: unrecognized token: ":"

better-sqlite3更新数据库行值时遭遇SqliteError: unrecognized token: ":"

嘿,这个问题我之前踩过坑!核心原因是你直接把变量值硬拼进了SQL语句里,导致SQL解析器把值里的特殊字符(比如URL里的冒号)当成了SQL语法的一部分,直接触发了语法错误。而且这种写法还藏着SQL注入的风险,得赶紧换成参数化查询的方式。

先看你出问题的这段代码:

let login_api = db.prepare(`UPDATE app_schema SET _c_url = ${_c_url_json.login_api}`)

假设_c_url_json.login_api返回的是类似https://your-api.com/login这样的URL,那最终生成的SQL语句会变成:

UPDATE app_schema SET _c_url = https://your-api.com/login

这完全不符合SQL语法——字符串值没加引号包裹,而且冒号:会被SQLite当成未知的语法令牌,直接抛出unrecognized token错误。

正确解法:用参数化查询

better-sqlite3原生支持参数绑定,这是处理动态值的标准操作,既安全又能彻底避免这类语法问题。有两种常用的绑定方式:

  1. 位置占位符(?)
    这种方式简单直接,按参数顺序传入值就行:
// 先获取API返回的数据
let _c_url = await fetch('api')
let _c_url_json = await _c_url.json()

// 准备带位置占位符的更新语句
let updateStmt = db.prepare(`UPDATE app_schema SET _c_url = ?`);
// 执行语句并传入参数
updateStmt.run(_c_url_json.login_api);
  1. 命名占位符
    如果参数较多,用命名占位符可读性更强:
let _c_url = await fetch('api')
let _c_url_json = await _c_url.json()

let updateStmt = db.prepare(`UPDATE app_schema SET _c_url = :loginApi`);
// 执行时传入键值对对象
updateStmt.run({ loginApi: _c_url_json.login_api });

额外提醒:别漏了WHERE子句

你的原语句没有加WHERE条件,这会更新app_schema表的所有行!如果你的需求是只更新特定行(比如id为1的记录),一定要补上条件:

// 示例:更新id=1的行
let updateStmt = db.prepare(`UPDATE app_schema SET _c_url = ? WHERE id = ?`);
updateStmt.run(_c_url_json.login_api, 1);

参数化查询会自动帮你处理字符串的引号包裹、特殊字符转义,不仅解决了冒号导致的语法错误,还能彻底杜绝SQL注入攻击,一举两得~

火山引擎 最新活动