如何在Slonik编写的SQL查询中添加条件SET子句
错误根因
你的写法存在两个问题:
- 当
passwordHash为null时,拼接出的SQL里"email" = ${email}末尾多了多余的逗号,不符合PostgreSQL语法 - 三目运算符返回空字符串时,slonik的SQL模板解析会出现占位符错位,触发
$3相关的语法报错
正确实现方案
下面提供两种常用的实现方式:
方案1:动态拼接更新字段(推荐)
通过数组收集需要更新的字段,再用sql.join拼接,从根源避免语法错误,适合可选更新字段较多的场景:
import { createPool, sql } from 'slonik' const dbPool = createPool() const updateUser = await dbPool.connect(async (conn) => { // 先加入固定要更新的字段 const updateFields = [ sql`"name" = ${name}`, sql`"email" = ${email}` ] // 仅当passwordHash非空时加入更新列表 if (passwordHash) { updateFields.push(sql`"passwordHash" = ${passwordHash}`) } return conn.one(sql` UPDATE users SET ${sql.join(updateFields, sql`, `)} WHERE "id" = ${id} RETURNING * `) })
方案2:SQL层逻辑处理
直接在SQL中用COALESCE函数处理,无需动态拼接代码,适合可选更新字段较少的场景:
import { createPool, sql } from 'slonik' const dbPool = createPool() const updateUser = await dbPool.connect(async (conn) => { return conn.one(sql` UPDATE users SET "name" = ${name}, "email" = ${email}, -- 若传入的passwordHash为null,就保留原有字段值 "passwordHash" = COALESCE(${passwordHash}, "passwordHash") WHERE "id" = ${id} RETURNING * `) })
原理:COALESCE函数会返回参数列表中第一个非null的值,如果传入的passwordHash为null,就会取当前行passwordHash字段的原有值,等效于没有修改该字段。
内容的提问来源于stack exchange,提问作者Federico Bellucci
相关产品推荐
相关产品推荐

