当前位置: 首页 > 面试题库 >

在PostgreSQL中移动(更新)唯一列值

席兴平
2023-03-14
问题内容

使用MS SQL Server,以下工作正常:

CREATE TABLE #temptable(mykey int primary key)

INSERT INTO #temptable VALUES (1)
INSERT INTO #temptable VALUES (2)

UPDATE #temptable SET mykey=mykey+1

但是,使用PostgreSQL,以下操作将失败:

CREATE TABLE pg_temp.tbl_test(testkey integer primary key)

INSERT INTO pg_temp.tbl_test VALUES (1)
INSERT INTO pg_temp.tbl_test VALUES (2)

UPDATE pg_temp.tbl_test SET testkey=testkey+1

错误:重复的键值违反了唯一约束“ tbl_test_pkey”详细信息:键(testkey)=(2)已存在。

我需要在一个表中增加一列的每个值,这是复合唯一约束的一部分。如何在一份声明中做到这一点?

谢谢 !

编辑:如果您想知道为什么这样做(至少对我而言),那么这是一个更完整的方案。

我有一张按类别组织的项目表。每个项目在类别中都有特定的位置。

category_id (PK) | category_position (PK) | item_attribute_1 | item_attribute_2
1 | 1 | foo | bar
1 | 2 | foo2 | bar2
2 | 1 | foo4 | bar4
2 | 2 | foo3 | bar3

该表包含如下数据

category1 : (foo, bar), (foo2, bar2)
category2 : (foo4, bar4), (foo3, bar3)

请注意,类别2中的(foo4,bar4)在(foo3,bar3)之前。现在,如果要对一个类别中的项目重新排序,则需要更新category_position
…但是由于PK,我无法像使用SQL Server一样使用PostgreSQL来移动值。


问题答案:

这确实有点令人困惑,因为在DML操作期间,所有其他约束都是在语句级别上评估的,仅PK /唯一约束是在每行级别上评估的。

但是,您可以通过将主键约束声明为可延迟来解决此问题:

create table tbl_test 
(
  testkey   INTEGER,
  constraint pk_tbl_test primary key (testkey) deferrable initially immediate
);

insert into tbl_test values (1), (2);

set constraints all deferred;

update tbl_test
   set testkey = testkey +1;

延迟约束确实有一些开销,因此可以通过将其定义为initially immediate将开销最小化来进行定义。您可以使用在需要时推迟约束评估set constraint

但是,真正的问题是:为什么要对主键值执行此操作?PK值毫无意义,因此似乎没有必要增加所有值(无论使用的是DBMS如何)



 类似资料:
  • 我的应用程序中不断出现此错误 重复的键值违反唯一约束“product\u supplierinfo\u pkey”详细信息:键(id)=(409)已存在。 这在表product_supplierinfo中。 关键约束需要的实际下一个序列号是5461,而不是409。 有人能告诉我更新此密钥唯一约束的正确查询吗?

  • 我想在PostgreSQL中设置一个表,这样两列在一起必须是唯一的。任何一个值都可以有多个值,只要没有两个值同时共享。 例如: 因此,和可以重复,但不能同时重复。因此,这是允许的(不包括id) 但不是这个:

  • 我有一个表和几个线程(系统),它们从表中读取特定列并更新它。因此,我的问题如下: 我想确保在任何时候只有一个线程可以选择和更新该列。最好的解决方案是什么? PS:据我所知,在SQL Server中使用事务会锁定事务中的所有资源,但我对PostgreSQL一无所知。 非常感谢。

  • 问题内容: 我们有一个遗留数据库架构,该架构具有一些有趣的设计决策。直到最近,我们仅支持Oracle和SQL Server,但是我们试图添加对PostgreSQL的支持,这带来了一个有趣的问题。我已经搜索了Stack Overflow和Internet的其余部分,但我不认为这种特殊情况是重复的。 对于唯一约束中的可为空的列,Oracle和SQL Server的行为相同,这实际上是在执行唯一检查时忽

  • 问题内容: 假设我有一个代表位置的类。位置“属于”客户。位置由Unicode 10个字符代码标识。对于特定客户,“位置代码”在位置之间应该唯一。 因此,如果我有两个客户,客户“ 123”和客户“ 456”。它们都可以有一个称为“ main”的位置,但都不能有两个称为main的位置。 我可以在业务逻辑中处理此问题,但是我想确保没有办法轻松地在sqlalchemy中添加需求。unique = True

  • 问题内容: 我在Heroku上托管了一个项目,想更改表的自动增量起始值。我在本地使用SQLite3,而Heroku使用PostgreSQL这是我在迁移中所拥有的: 迁移在本地运行,但SQLite似乎只是忽略更改,尽管它在Heroku上有效。我究竟做错了什么? 问题答案: 老实说,听起来这并不属于迁移。但是,您可以将以下内容添加到初始化程序中,以使其成为方便的基类方法以作为任务的一部分进行调用: 然