我在DB上有一个表格,其中包含以下字段:PK DOC_ID
,SECTION_ID
,SET_ID
,CELL_ID
。您可以推断,这是指一组Excel电子表格。
除了这些字段外,我还有一个CELL_ROW
字段和CELL_COL
字段。
使用SET_ID
(唯一),它们会形成替代密钥。
所以,至少在理论上,如果我想交换两个单元格的坐标,我需要释放该约束,或者使用第三个临时自由位置(例如 A100000 )。 / p>
假设我有以下单元格:
DOC_ID | SECTION_ID | SET_ID | CELL_ID | CELL_ROW | CELL_COL
--------|------------|--------|---------|----------|----------
5 | 456 | 8778 | 15045 | 5 | 4
5 | 456 | 8778 | 15048 | 5 | 5
假设我有以下临时表,我在其中对主表执行UPDATE
:
DOC_ID | SECTION_ID | SET_ID | CELL_ID | CELL_ROW | CELL_COL
--------|------------|--------|---------|----------|----------
5 | 456 | 8778 | 15045 | 5 | 5
5 | 456 | 8778 | 15048 | 5 | 4
理论上,UPDATE
应该引发例外......
但只是尝试过,它有效!
你能解释一下为什么吗? Oracle是否将其作为原子操作执行,因此仅在整个操作之后检查约束(而不是每条记录的记录)?MS SQL Server 2008 r2和Postgres在这种情况下的表现如何?
答案 0 :(得分:1)
我在Postgresql中尝试了它并且正如预期的那样引发了重复键错误:
create table t (
doc_id integer,
section_id integer,
set_id integer,
cell_id integer,
cell_row integer,
cell_col integer,
primary key (doc_id, section_id, set_id, cell_id),
unique (set_id, cell_row, cell_col)
);
insert into t (doc_id, section_id, set_id, cell_id, cell_row, cell_col)
values
(5, 456, 8778, 15045, 5, 4),
(5, 456, 8778, 15048, 5, 5);
create temporary table t_temp (
doc_id integer,
section_id integer,
set_id integer,
cell_id integer,
cell_row integer,
cell_col integer
);
insert into t_temp (doc_id, section_id, set_id, cell_id, cell_row, cell_col)
values
(5, 456, 8778, 15045, 5, 5),
(5, 456, 8778, 15048, 5, 4);
update t
set
cell_col = t_temp.cell_col
from t_temp
where
t.doc_id = t_temp.doc_id
and t.section_id = t_temp.section_id
and t.set_id = t_temp.set_id
and t.cell_id = t_temp.cell_id
;
ERROR: duplicate key value violates unique constraint "t_set_id_cell_row_cell_col_key"
DETAIL: Key (set_id, cell_row, cell_col)=(8778, 5, 5) already exists.
如果约束设置为deferrable
,我可以这样做。检查该关键字的create table语句。
答案 1 :(得分:1)
PostgreSQL将抛出错误,除非您推迟唯一约束(然后您不能将其用作外键)。我不确定SQL Server。
简而言之,你可能想把它称为Postgres或PostgreSQL。将其称为Postgre表明您与社区的联系太少而无法纠正。
有关PostgreSQL的更多信息
PostgreSQL在元组更新时检查元组约束。这意味着即使在以不违反唯一约束的原子方式更新集合的情况下,也会违反唯一约束。这导致了一些有趣的解决方法,例如将一个整数键乘以该集合的-1,然后在下一次更新中再次乘以-1并添加一个。