database - 数据库约束检查值(来自不同行)是否按连续顺序排列
问题描述
我正在设置一个 PostgreSQL 数据库,并且想要创建一个约束来检查值(来自单个表中的不同行)是否是连续的。
该表如下所示:
+-------------+---------+-------+
| waypoint_id | path_id | order |
+-------------+---------+-------+
| 89 | 1 | 1 |
| 16 | 1 | 2 |
| 17 | 1 | 3 |
| 19 | 1 | 4 |
| 4 | 1 | 5 |
| 75 | 2 | 1 |
| 28 | 2 | 2 |
| 2 | 2 | 3 |
+-------------+---------+-------+
它是一个表格,用于存储某条路径的航点顺序。
- waypoint_id是存储航点坐标的表的 ForeignKey 。
- path_id是存储有关路径信息(什么类型的路径等)的表的 ForeignKey 。
- order是一个整数,用于存储特定路径中的航点的顺序。
- PrimaryKey 是所有 3 列的组合。
约束必须检查 order 列中的值(具有相等的 path_id)是否是连续的。
这是一个无效的示例:(顺序不连续,因为缺少 3)
+-------------+---------+-------+
| waypoint_id | path_id | order |
+-------------+---------+-------+
| 21 | 1 | 1 |
| 29 | 1 | 2 |
| 104 | 1 | 4 |
+-------------+---------+-------+
我希望约束不允许插入该行:
| 104 | 1 | 4 |
请向我展示类似问题的解决方案示例,或向我指出如何解决问题的文档。
解决方案
给你:https ://dbfiddle.uk/?rdbms=postgres_11&fiddle=b67be9527e86fd444d158f9ab93bf600
对于不耐烦的人:
CREATE OR REPLACE FUNCTION consecutive_check()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
IF NEW."order" = 1 OR EXISTS (SELECT 1 FROM my_table WHERE path_id = NEW.path_id AND "order" = (NEW."order" - 1)) THEN
RETURN NEW;
END IF;
RAISE EXCEPTION 'Previous waypoint not available for path_id = %', NEW.path_id;
END;
$function$;
CREATE TRIGGER no_holes_path
BEFORE INSERT
ON my_table
FOR EACH ROW
EXECUTE PROCEDURE consecutive_check()
;
警告:这将导致查询表,因此您必须有一个索引path_id
,order
并且您必须意识到此解决方案无法很好地扩展这一事实。
推荐阅读
- html - 如何将img放在div旁边?
- reactjs - 如何使用 React js 中的 Hooks 在网页上上传/浏览和显示图像?
- php - 执行功能不起作用它在窗口数组问题中出错
- java - 从 URL 获取 Json 中的多个 UUID
- c - 我无法连接 ATtiny85 和 EM18(RFID 阅读器)
- spring - 想按类型查找用户
- java - 在 Manjaro Linux 上运行 Java 程序
- python - 使用python在Excel中搜索字符串
- html - MediaQuery 不工作。对于桌面(超过 992 像素)全部保留在一行中,对于平板电脑,前 2 个应为 50% 宽度,第 3 个应为 100%,对于移动设备全部为 100%
- perl - 为什么这个 Perl 的斐波那契单线行得通?