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

如何在GRDB中用INSTR批量更新多行?支持原生查询吗?

解决GRDB中实现指定UPDATE语句的问题

一、使用GRDB DSL正确实现

你当前的代码存在两处逻辑错误:

  1. 字符串包含判断写反:应该是数据库字段title包含给定字符串,而非给定字符串包含字段
  2. start的条件逻辑不符原SQL:原SQL是start - ? < 60,等价于start < ? + 60,你写的Column("start") > date - 60逻辑相反

修正后的DSL代码

方式1:用GRDB内置方法模拟instr行为

如果只需要判断子串存在,直接用contains方法即可,效果和instr非0判断一致:

_ = try dbQueue?.write { db in
    try MyTable
        // 对应原SQL的start - ? < 60 → start < date + 60
        .filter(Column("start") < date + 60)
        // 对应instr(title, ?):字段title包含给定的title字符串
        .filter(Column("title").contains(title))
        .updateAll(db, Column("path").set(to: path))
}

方式2:显式调用instr函数

如果需要严格匹配instr的语法(比如特殊匹配场景),可以直接构造SQL函数表达式:

_ = try dbQueue?.write { db in
    try MyTable
        .filter(Column("start") < date + 60)
        // 调用instr函数,返回值非0则条件成立
        .filter(SQL("instr(title, ?)", title) != 0)
        .updateAll(db, Column("path").set(to: path))
}

二、使用原生SQL查询实现

完全可以用原生SQL执行,GRDB支持直接执行原生语句,按SQL中占位符的顺序填充参数即可:

_ = try dbQueue?.write { db in
    let sql = "UPDATE MyTable SET path = ? WHERE instr(title, ?) AND start - ? < 60"
    // 参数顺序对应SQL中的三个占位符:path、title、date
    try db.execute(sql: sql, arguments: [path, title, date])
}

如果需要更严谨的类型控制,也可以用Statement构建执行:

_ = try dbQueue?.write { db in
    let statement = try db.makeStatement(sql: "UPDATE MyTable SET path = ? WHERE instr(title, ?) AND start - ? < 60")
    statement.arguments = [path, title, date]
    try statement.execute()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:15:32