如何编写SQL UPDATE查询使sqlc生成带可选参数的Go函数
解决sqlc生成可选更新Go函数的问题
正确SQL写法(用NULL标识不更新)
用命名参数+NULL判断的方式,既能让sqlc识别列名,又能实现真正的可选更新:
-- name: UpdateTable :one UPDATE "table" SET name = COALESCE(:name, name), default_content = COALESCE(:default_content, default_content) WHERE id = :id RETURNING *;
如果偏好CASE语法,也可以这么写:
-- name: UpdateTable :one UPDATE "table" SET name = CASE WHEN :name IS NOT NULL THEN :name ELSE name END, default_content = CASE WHEN :default_content IS NOT NULL THEN :default_content ELSE default_content END WHERE id = :id RETURNING *;
生成的Go代码效果
上述写法会让sqlc生成带明确列名的参数结构体,且字段用指针类型(支持传入nil表示不更新):
type UpdateTableParams struct { Name *string `json:"name"` DefaultContent *string `json:"default_content"` ID uuid.UUID `json:"id"` }
原写法的问题
- 用
$1 <> ''判断空字符串,sqlc无法将占位符关联到具体列名,只能生成Column1/Column2这类泛型命名;同时空字符串本身是合法业务值,没法区分“不更新”和“主动更新为空”的场景。 - 未使用命名参数时,sqlc无法识别字段语义,自然生成泛型参数结构。
使用说明
- 不想更新某个字段时,传递
nil即可;如果需要主动将字段更新为空字符串,传递&""。 - 表名如果是SQL关键字(比如示例中的
table),要用双引号包裹避免语法错误。
内容的提问来源于stack exchange,提问作者waa
相关产品推荐
相关产品推荐

