代码之家  ›  专栏  ›  技术社区  ›  Lamda

如何确定给定条目是否有指向它的外键?

  •  0
  • Lamda  · 技术社区  · 4 年前

    我目前正在为一个父表开发一个触发器函数,它应该对一个子表上的相关行执行检查,该子表对更新的父表行有一个外键。

    我做了一把小小提琴来布置我的处境:

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

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

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

    我如何知道某个东西依赖于这一行,并执行我想要的检查,反之亦然,没有东西依赖于这一行?

    0 回复  |  直到 4 年前
        1
  •  0
  •   Hannes Erven    4 年前

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

    您可以通过带有函数的约束子句来实现这一点,但是,当您使用触发器时,您可以更好地控制逻辑。e、 在一个trigger函数中,您总是可以使用新旧行或值,因此如果时间范围没有改变,您可以轻松跳过检查。

    要检查“另一面”,您必须在触发器函数中执行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 有一个关于触发器函数的综合示例和文档。

        2
  •  0
  •   mrvol    4 年前

    如果我答对了你的问题,也许这对你有帮助。

    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';