如果满足条件,PostgreSQL 删除行,否则更新一些值

标签 postgresql clojure

我正在尝试根据一个简单的条件删除一行,如果满足条件,则删除该行,否则更新该行。基本上我用 is_deleted 标记我的数据,所以如果 is_deleted 等于 true,则执行删除,如果不是,则将 is_deleted 值设置为 true。

现在我正在做的是一个简单的查询,从查询的数据中检查 is_deleted 并根据它做一些事情。

用 clojure 编写的非常简单的伪代码($n 只是位置参数的占位符):

(defn find-by-username 
  [db username]
  "SELECT * FROM users WHERE username = $1") ;; to illustrate the query

(defn delete-by-username-impl
  [db username]
  "DELETE FROM users WHERE username = $1")

(defn set-is-deleted
  [db username]
  "UPDATE users SET is_deleted = true WHERE username = $1")

(defn delete-by-username 
  [db username]
  (let [user (find-by-username db username)]
    (if (:is-deleted user)
      (delete-by-username-impl db username)
      (set-is-deleted db username))))

我正在寻找的是只访问数据库一次。

最佳答案

只访问数据库一次是什么意思?运行一个查询?然后您可以将所有查询合并为一个:

IF (SELECT is_deleted FROM users WHERE username = $1) THEN
  DELETE FROM users WHERE username = $1
ELSE
  UPDATE users SET is_deleted = true WHERE username = $1
END IF;

如果你的意思是一起运行所有查询或者在一个独立的上下文中不运行它们(这样其他客户端不能在查询运行时改变状态,比如 is_deleted 标志),你可以包装单独的查询使用 database transaction 进入交易:

Database transactions are available to ensure that multiple operations are performed atomically (i.e., all or none). The clojure.java.jdbc/with-db-transaction macro creates a transaction-aware connection from the database specification. Use the transaction-aware connection for the duration of the transaction:

;; Insert two new fruits atomically
(jdbc/with-db-transaction [trans-conn db-spec]
  (jdbc/insert! trans-conn :fruit {:name "Fig" :cost 12})
  (jdbc/insert! trans-conn :fruit {:name "Date" :cost 14}))
;; -> ({:grade nil, :unit nil, :cost 14, :appearance nil, :name "Date"})

关于如果满足条件,PostgreSQL 删除行,否则更新一些值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56284000/

相关文章:

sql - postgres中具有多个值列的数据透视表

Clojure 嵌套 for 循环和索引

clojure - clojure的所有特殊形式是什么?

list - 从 clojure 中的函数返回列表

Clojure 字符串到符号的计算结果错误

postgresql - rds postgres 上的 redis_fdw

ruby-on-rails - Rails、ActiveRecord、PostgreSQL 使用正则表达式在字符串中搜索单词

php - PDO 相当于 pg-result-seek

postgresql - 如何在 PL/Python PostgreSQL 例程中返回二进制字符串 (bytea)?

list - 什么是惯用的 Clojure 到 "remove"列表中多个实例的单个实例?