我正在寻找的行为类似于您在将约束(例如,唯一)添加到现有表时会观察到的行为,根据现有数据对其进行验证,然后删除约束。我不希望约束在表上持续存在,我只想表达它,在现有数据上验证它,然后继续(或引发检查失败的异常);Postgresql (9.2) 是否支持直接做这种事情的方法?
问问题
306 次
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,您可以通过从查询结果构建一个字符串、循环结果并引发NOTICE
s 等来实现。很多选项。我将把它作为练习留给读者,与 PL/PgSQL 文档一起使用。
于 2013-06-08T02:42:46.287 回答