【问题标题】:In Postgresql, can you express and check a constraint without adding it to an entity?在 Postgresql 中,您可以在不将约束添加到实体的情况下表达和检查约束吗?
【发布时间】:2013-06-07 15:41:36
【问题描述】:

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

【问题讨论】:

  • 您可以使用select 语句计算违反“条件”的行。例如对于涉及 group byhaving count(*) > 1 的唯一约束
  • @a_horse_with_no_name,感谢您的建议。如果违反了约束(顶级分支,即 CASE ...,在语法上无效),我该如何做某事,例如抛出异常?这需要使用程序语言吗?

标签: sql postgresql constraints unique-constraint


【解决方案1】:

创建约束:

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;

【讨论】:

    【解决方案2】:

    设置:

    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 文档一起使用。

    【讨论】:

      【解决方案3】:

      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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-25
        相关资源
        最近更新 更多