加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql – 使用UNIQUE约束Postgres在一个字段中增加一组值

发布时间:2020-12-12 06:58:09 所属栏目:MsSql教程 来源:网络整理
导读:我有一个表,其中我有一个数字字段A,设置为UNIQUE.该字段用于指示必须执行某些操作的顺序.我想对所有更大的值进行更新,例如,比3更高.例如, 我有 A 12345 现在,我想在A的所有值中加1,大于3.因此,结果将是 A 12356 问题是,是否可以只使用一个查询来完成?请记住,
我有一个表,其中我有一个数字字段A,设置为UNIQUE.该字段用于指示必须执行某些操作的顺序.我想对所有更大的值进行更新,例如,比3更高.例如,
我有
A     
1
2
3
4
5

现在,我想在A的所有值中加1,大于3.因此,结果将是

A     
1
2
3
5
6

问题是,是否可以只使用一个查询来完成?请记住,我对列A有一个UNIQUE约束.

显然,我试过了

UPDATE my_table SET A = A + 1 WHERE A > 3;

但它不起作用,因为我对这个领域有约束.

解决方法

PostgreSQL 9.0及更高版本

PostgreSQL 9.0增加了deferrable unique constraints,这正是您似乎需要的功能.这样,在提交时而不是更新时检查唯一性.

使用DEFERRABLE关键字创建UNIQUE约束:

ALTER TABLE foo ADD CONSTRAINT foo_uniq (foo_id) DEFERRABLE;

稍后,在运行UPDATE语句之前,您将在同一事务中运行:

SET CONSTRAINTS foo_uniq DEFERRED;

或者,您可以在唯一约束本身上使用INITIALLY DEFERRED关键字创建约束 – 因此您不必运行SET CONSTRAINTS – 但这可能会影响其他查询的性能,而这些查询不需要推迟约束.

PostgreSQL 8.4及更早版本

如果您只想使用唯一约束来保证唯一性 – 而不是作为外键的目标 – 那么这种解决方法可能会有所帮助:

首先,将一个布尔列(如is_temporary)添加到临时区分更新和未更新行的表中:

CREATE TABLE foo (value int not null,is_temporary bool not null default false);

接下来创建一个仅影响is_temporary = false的行的部分唯一索引:

CREATE UNIQUE INDEX ON foo (value) WHERE is_temporary=false;

现在,每次都进行您描述的更新,您可以分两步运行它们:

UPDATE foo SET is_temporary=true,value=value+1 WHERE value>3;
UPDATE foo SET is_temporary=false WHERE is_temporary=true;

只要这些语句出现在单个事务中,这将是完全安全的 – 其他会话永远不会看到临时行.缺点是你将两次写行.

请注意,这只是一个独特的索引,而不是约束,但在实践中它应该无关紧要.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读