Partial updates with database/sql, is this possible?

xuanbao · · 428 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I&#39;m writing a REST API without an ORM and I&#39;m not entirely sure how to implement a partial update. The straightforward approach that I can think of is to grab the entity from the database, update the fields with the decoded JSON (ignoring the empty values), and then hit the database again with all the fields. </p> <p>I was wondering: can I do this all with SQL/Postgres in one trip?</p> <p>The SQL would look something like this:</p> <pre><code>UPDATE users SET city=&#39;New York&#39;, interests=&#39;&#39; WHERE id=1 </code></pre> <p>But would be modified to ignore the &#39;interest&#39; column for this specific case since the value is empty. </p> <p>My database function: </p> <pre><code>func UpdateUser(db *sql.DB, u models.User) error { _, err := db.Exec( `UPDATE users SET city=$1, interests=$2 WHERE id=$3`, u.City, u.Interests u.ID) return err } </code></pre> <p>But the problem is that <code>u</code> may or may not have city and interest fields (since the user is able to partially update the profile).</p> <p>EDIT: Fix sql and add context.</p> <hr/>**评论:**<br/><br/>kardianos: <pre><p>I would highly encurage you to read through the postgresql SQL docs: <a href="https://www.postgresql.org/docs/current/static/functions-conditional.html" rel="nofollow">https://www.postgresql.org/docs/current/static/functions-conditional.html</a></p> <p>The answer to your question is to use a CASE statement as follows:</p> <pre><code>update u set city = $1, interests = case when $2 = &#39;&#39; then u.interests else $2 end from users u where u.id = $3; </code></pre></pre>KeyYam: <pre><p>thanks! this looks promising. I&#39;ll try this and read up on the postgresql docs.</p></pre>pcj2bs: <pre><p>You can just do this:</p> <pre><code>UPDATE users SET city = &#39;New York&#39; WHERE id = 1 </code></pre></pre>KeyYam: <pre><p>This wouldn&#39;t work because the sql is a string (I updated my original post for clarity).</p></pre>dinkumator: <pre><p>You&#39;ll have to build up the query yourself. It&#39;s not the most efficient, but something like this would work:</p> <pre><code>func UpdateUser(db *sql.DB, u models.User) error { cols := []string{} args := []interface{}{} if u.City!=&#34;&#34; { args = append(args, u.City) cols = append(cols, fmt.Sprintf(&#34;city=$%d&#34;, len(args))) } if u.Interests!=&#34;&#34; { args = append(args, u.Interests) cols = append(cols, fmt.Sprintf(&#34;interests=$%d&#34;, len(args))) } args = append(args, u.ID) query := &#34;UPDATE users SET &#34; query = strings.Join(cols, &#34;, &#34;) query += fmt.Sprintf(&#34; WHERE id=$%d&#34;, len(args))) _, err := db.Exec(query, args...) return err } </code></pre></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

428 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传