per*_*000 5 sql postgresql unique-constraint sql-update
使用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
Run Code Online (Sandbox Code Playgroud)
但是,使用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
Run Code Online (Sandbox Code Playgroud)
错误:重复键值违反唯一约束"tbl_test_pkey"DETAIL:键(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
Run Code Online (Sandbox Code Playgroud)
该表包含如下数据:
category1 : (foo, bar), (foo2, bar2)
category2 : (foo4, bar4), (foo3, bar3)
Run Code Online (Sandbox Code Playgroud)
请注意,(foo4,bar4)在category2中位于(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;
Run Code Online (Sandbox Code Playgroud)
延迟约束确实有一些开销,因此通过定义它可以initially immediate
将此开销保持在最低限度.您可以在需要时通过使用来推迟约束评估set constraint
.
但真正的问题是:为什么你需要在主键值上执行此操作?PK值没有任何意义,因此似乎没有必要增加所有值(无论使用何种DBMS)
归档时间: |
|
查看次数: |
1605 次 |
最近记录: |