0

我目前正在研究父表的触发函数,该函数应该对子表上的相关行执行检查,该子表具有已更新的父表行的外键。

我做了小 dbfiddle 设置我的情况:

https://www.db-fiddle.com/f/sV8f9F7Lg6R6HE89nXNhhV/4

我的数据模型包含给定实体注册的实例,其中包含给定条目的不同版本。所以我的情况是,我拥有国家、纳尼亚和机场纳尼亚机场。纳尼亚机场有一把通往国家的钥匙,表明它是纳尼亚的一部分。

每个机场都有一个检查功能,确保子表与其父表的生命周期一致,这意味着只要纳尼亚不存在,纳尼亚机场就不能存在......

第一个查询显示的是哪个,但是我如何以另一种方式进行有效的检查?目前,我可以将国家/地区更改为国外 og 其孩子的寿命使孩子成为孤儿?

我有一个想法,为每个父子关系创建一个触发器,但它似乎有点重,我只对受影响的孩子做这个检查感兴趣,而不是每个孩子?

我怎么知道某些东西依赖于这一行,并执行我想要的检查,反之亦然,什么都不依赖于这个给定的行?

4

2 回答 2

0

正如您所概述的,您需要在两个方向上进行约束检查:更新机场时,确保国家/地区有效;当一个国家更新时,您需要确保所有机场注册仍然具有与更新的国家范围相关的有效范围。

您可以通过带有函数的 CONSTRAINT 子句来实现这一点,但是当您使用 TRIGGER 时,您将可以更好地控制逻辑。例如,在触发器函数中,您将始终拥有新旧行或值供您使用,因此如果时间范围没有改变,您可以轻松跳过检查。

要检查“另一面”,您必须在触发器函数中执行 SQL 查询。如果您在机场有很多行,也许可以在外键列(例如在 airport.country)上添加一个索引以加快查询速度。

“country”上的触发器将可以访问修改后的国家/地区的 ID,因此您可以执行如下 SQL: IF EXISTS(SELECT 1 FROM airport a WHERE country=NEW.entity_id AND ... /* insert range checking condition here*/ ) THEN RAISE ERROR ''; END IF;并且您不必担心性能。

https://www.postgresql.org/docs/12/plpgsql-trigger.html有一个关于触发器函数的综合示例和文档。

于 2020-10-01T22:55:34.940 回答
0

如果我正确地回答了您的问题,也许这对您有帮助。

SELECT
    tc.table_schema, 
    tc.constraint_name, 
    tc.table_name, 
    kcu.column_name, 
    ccu.table_schema AS foreign_table_schema,
    ccu.table_name AS foreign_table_name,
    ccu.column_name AS foreign_column_name 
FROM 
    information_schema.table_constraints AS tc 
    JOIN information_schema.key_column_usage AS kcu
      ON tc.constraint_name = kcu.constraint_name
      AND tc.table_schema = kcu.table_schema
    JOIN information_schema.constraint_column_usage AS ccu
      ON ccu.constraint_name = tc.constraint_name
      AND ccu.table_schema = tc.table_schema
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='mytable';
于 2020-10-02T09:08:10.510 回答