You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLite语法错误排查:自定义Wrapper插入JSON字符串报错

问题原因分析

你的语法错误根源是直接拼接SQL字符串并手动用双引号包裹值,当JSON序列化后的字符串包含双引号时,会破坏SQL语句的结构:
比如你传入的JSON是{"name":"hii","tetst":"thisis a test"},手动用双引号包裹后变成"{"name":"hii","tetst":"thisis a test"}",SQL解析器会把第一个"之后的{当作合法内容,遇到name时就会触发语法错误——因为此时SQL认为这是一个未定义的标识符。

同时这种写法存在严重的SQL注入风险,任何包含特殊字符的字符串都可能破坏SQL结构,甚至被恶意利用。

解决方法:使用参数化查询

sqlite3原生支持参数化查询(占位符?),驱动会自动处理值的转义与类型转换,彻底避免语法错误和注入问题。修改你的insert方法如下:

export class sqlite3Wrapper {
  #connection;
  #run;
  #get;

  constructor(dbName: string) {
    this.#connection = new sqlite3.Database(dbName);
    this.#run = promisify(this.#connection.run.bind(this.#connection));
    this.#get = promisify(this.#connection.get.bind(this.#connection));
  }

  async insert(table: string, { fields, values, object, updateOnDuplicate = false }: { fields?: string | string[]; values?: any | any[]; object?: { [key: string]: any }; updateOnDuplicate?: boolean }): Promise<any> {
    let f = object ? Object.keys(object) : fields;
    let v = object ? Object.values(object) : values;

    if (!f || !v) throw new Error("Fields can't be empty");
    if (!Array.isArray(v)) {
      v = [values as any];
    }
    if (!Array.isArray(f)) {
      f = [fields as string];
    }

    if (f.length !== v.length) throw new Error("Fields and values must be the same length");

    // 构建占位符字符串,比如 [?, ?]
    const placeholders = f.map(() => '?').join(', ');
    let sql = `INSERT INTO ${table} (${f.join(', ')}) VALUES (${placeholders})`;
    const params = [...v];

    // 处理更新逻辑:SQLite不支持ON DUPLICATE KEY UPDATE,需用ON CONFLICT DO UPDATE
    if (updateOnDuplicate) {
      // 构建SET部分的占位符,比如 field1 = ?, field2 = ?
      const updateClauses = f.map(field => `${field} = ?`).join(', ');
      sql += ` ON CONFLICT DO UPDATE SET ${updateClauses}`;
      // 将更新值追加到参数数组
      params.push(...v);
    }

    return await this.#run(sql, params);
  }
}
关键修改点说明
  1. 参数化占位符:用?代替直接拼接值,所有值都作为参数数组传给#run方法,驱动会自动处理转义,包括JSON字符串里的双引号。
  2. SQLite冲突更新修正:SQLite不支持MySQL的ON DUPLICATE KEY UPDATE,需替换为ON CONFLICT DO UPDATE(注意:你需要确保表中有唯一约束,比如id字段是主键或唯一索引,否则该语句不会生效)。
  3. 避免手动字符串拼接:彻底移除了手动判断值类型并添加引号的逻辑,由驱动统一处理类型转换。
验证调用

你的原有调用代码无需修改,直接使用即可:

const obj = { name: "hii", tetst: "thisis a test" };
const theJsonFile = JSON.stringify(obj);
console.log(theJsonFile);
await db.insert("jsonTest", { fields: ["id", "value"], values: ["3", theJsonFile] });

内容的提问来源于stack exchange,提问作者Yoru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 02:37:01