0

我在 DB 上有一个表,其中包含以下字段作为 PK: DOC_ID, SECTION_ID, SET_ID, CELL_ID. 正如您可以推断的那样,这被称为一组 Excel 电子表格。

除了那些字段,我还有一个CELL_ROW字段和CELL_COL字段。使用SET_ID( unique ),它们形成了一个替代键。

因此,至少在理论上,如果我想交换两个单元格的坐标,我需要释放该约束,或者使用第三个临时空闲位置(例如A100000)。

假设我有以下单元格:

 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 在这种情况下的表现如何?

4

2 回答 2

1

PostgreSQL 会抛出一个错误,除非你推迟唯一约束(然后你不能将它用作外键)。我不确定 SQL Server。

顺便说一句,您可能希望将其称为 Postgres 或 PostgreSQL。将其称为 Postgre 表明您与社区的联系太少而无法纠正。

有关 PostgreSQL 的更多信息

PostgreSQL 在元组更新时检查元组约束。这意味着即使在以不违反唯一约束的原子方式更新集合的情况下,也会违反唯一约束。这导致了一些有趣的解决方法,例如将整数键乘以 -1 的集合,然后在下一次更新中再次乘以 -1 并加一。

于 2013-02-26T13:04:37.163 回答
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 语句。

于 2013-02-26T12:53:11.620 回答