【问题标题】:Duplication constraint in postgreSQL using (using GIST and or EXCLUDE)postgreSQL 中的重复约束使用(使用 GIST 和/或 EXCLUDE)
【发布时间】:2021-11-15 06:48:00
【问题描述】:

如何使用以下规则编写约束(表级别唯一,使用 GIST 和/或 EXCLUDE )以执行重复记录验证:

  1. 输入的 from_date 和 to_date 值不应相等或在范围内,并且
  2. Employee_id 不应该相等,并且

验证后,应返回一条错误消息,说明“重复条目”。 这是在 postgreSQL 中。

注意:我是 postgreSQL 新手(曾在 MS SQL Server 和 MySQL 工作过)。

提前致谢。

【问题讨论】:

  • 不应相等或不在范围内” - 在哪个范围内?
  • 这类似于重复检查,输入的 from_date 和 to_date 值不应相等或在 from_date 和 to_date 列的现有值范围内。 employee_id 不应等于现有的 employee_id 值。
  • 那个描述不清楚。无论如何,我认为第三个条件(尽管它的含义尚不清楚)将无法通过约束来做到这一点。
  • 当输入的 from_date 和 to_date 值相等或在现有 from_date 和 to_date 列值的范围内且输入的employee_id 不应等于现有employee_id 时,条目或记录将被视为重复值 AND 为状态列输入的值不应等于值“待定”。
  • employee_id 的非重叠范围可以很容易地使用排除约束来完成,但正如 Laurenz 已经提到的那样,仅针对 pending 事件不能使用排除约束来完成 - 只有过滤的唯一索引。但这反过来又不支持排除约束。所以这三者的结合似乎不太可能。有可能防止具有相同状态的employee_id 的范围重叠(因此没有重叠的待处理,没有重叠的“最终”等)

标签: postgresql postgresql-11


【解决方案1】:

正如@Laurenz Albe 所说,使用约束听起来是不可能的。您可以改为实现trigger functionrule

触发功能:

CREATE OR REPLACE FUNCTION test_insert_table()
RETURNS trigger LANGUAGE plpgsql IMMUTABLE AS
$$
BEGIN
IF NEW.status = 'pending'
AND EXISTS
  ( SELECT 1
      FROM your_table
     WHERE Employee_id = NEW.Employee_id
       AND range @> daterange(NEW.from_date, NEW.to_date)
  )
THEN
  RAISE EXCEPTION 'Duplicate Entry' ;
  RETURN NULL ;
ELSE
  RETURN NEW ;
END IF ;
END ;
$$

CREATE OR REPLACE TRIGGER test_insert_table 
BEFORE INSERT ON your_table
FOR EACH ROW EXECUTE FUNCTION test_insert_table() ;

规则:

CREATE OR REPLACE RULE test_insert AS
    ON INSERT TO your_table
 WHERE NEW.status = 'pending'
   AND EXISTS
       ( SELECT 1
           FROM your_table
          WHERE Employee_id = NEW.Employee_id
            AND range @> daterange(NEW.from_date, NEW.to_date)
       )
    DO INSTEAD NOTHING ;

【讨论】:

  • 谢谢'Edouard',因为应用程序需要错误消息,我们决定将它放在触发器中。你的回答有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多