0

我正在寻找的行为类似于您在将约束(例如,唯一)添加到现有表时会观察到的行为,根据现有数据对其进行验证,然后删除约束。我不希望约束在表上持续存在,我只想表达它,在现有数据上验证它,然后继续(或引发检查失败的异常);Postgresql (9.2) 是否支持直接做这种事情的方法?

4

3 回答 3

2

创建约束:

alter table t
add constraint the_pk primary key (user_id);
NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "the_pk" for table "t"
ERROR:  could not create unique index "the_pk"
DETAIL:  Key (user_id)=(1) is duplicated.

如果没有错误丢弃它:

alter table t
drop constraint the_pk;

如果您不想将其保留一段时间,请在事务中执行:

begin;

alter table t
add constraint the_pk primary key (user_id);

满足后回滚事务:

rollback;
于 2013-06-07T16:10:45.597 回答
1

IF EXISTS为此目的,在 plpgsql 中通常更简单、更快:

DO
$$
BEGIN
    IF EXISTS (SELECT 1 FROM tbl GROUP BY tbl_id HAVING count(*) > 1) THEN
        RAISE EXCEPTION 'Duplicate "tbl_id" in table "tbl"!';
    END IF;
END
$$ LANGUAGE plpgsql;
于 2013-06-08T18:49:45.367 回答
1

设置:

CREATE TABLE testu ( id integer );
INSERT INTO testu SELECT generate_series(1,100);
INSERT INTO testu VALUES (1),(10),(20);

演示查询以查找可能的问题行:

regress=> select id, count(id) FROM testu GROUP BY id HAVING count(id) > 1;
 id | count 
----+-------
 20 |     2
  1 |     2
 10 |     2
(3 rows)

将其包装在DO块中:

DO
$$
BEGIN
    PERFORM id FROM testu GROUP BY id HAVING count(id) > 1 LIMIT 1;
    IF FOUND THEN
        RAISE EXCEPTION 'One or more duplicate IDs in table testu';
    END IF;
END;
$$ LANGUAGE plpgsql;

如果您想报告单个冲突 ID,您可以通过从查询结果构建一个字符串、循环结果并引发NOTICEs 等来实现。很多选项。我将把它作为练习留给读者,与 PL/PgSQL 文档一起使用。

于 2013-06-08T02:42:46.287 回答