【发布时间】:2021-08-09 12:44:47
【问题描述】:
(TL;DR 结尾)
我正在合并 2 个大小合适的 postgres 数据库。
由于存在 ID 冲突和许多外键,我会很高兴UPDATE foo SET bar_id = bar_id + 100000 CASCADE 是 SQL 中的一个东西,因此它会神奇地相应地更新所有内容。不幸的是,事实并非如此。
所以我想使用一个 LOOP 结构(见下文),它可以简单地编辑任何地方的引用。 我想要一个选择查询,返回引用我想要的列的所有 table_name、column_name。
DO
$$
DECLARE
rec record;
BEGIN
FOR rec IN
(SELECT table_name, column_name FROM /*??*/ WHERE /*??*/) -- <<< This line
LOOP
EXECUTE format('UPDATE %I SET %s = %s + 100000 ;',
rec.table_name,rec.column_name,rec.column_name);
END LOOP;
END;
$$
LANGUAGE plpgsql;
我已经知道如何获取具有特定 column_name 的所有表 (+column_name),当外键列与其引用的列共享名称时,我使用该特定列名。或者即使它是我知道的 column_name 列表:
SELECT col.table_name, col.column_name
FROM information_schema.columns col
right join
information_schema.tables tab
ON col.table_name = tab.table_name
WHERE column_name = 'foo_id'
-- IN ('FOO_ID','BAR_FOO_ID') | or : like '%foo_id' | both works well most of the time
and tab.table_type = 'BASE TABLE'
但是……
我现在有一个表 PLACES,其中至少有 60 个不同的约束(匹配 LIKE '%place_id')引用了 place_id 列。 还有一些列引用了以其他方式命名的地点 ID,例如“foo_currentplace”、“foo_storageroom”、“foo_lastrecomposition_place”、“operating_theatre”等。另一方面,有来自placetype表的列引用'placetype_id'是LIKE '%place%' ,我不想更改placetype_id,所以我们无法猜测哪一列将包括或不仅来自他们的名字。
我知道有information_schema.table_constraints 表,但它不会告诉引用的列。
如果我们可以从约束名称中获得定义,则可以匹配:ILIKE format('%%REFERENCES %s(%s)%%',table_name,column_name)
但该定义也不属于table_constraints 表。
(对于那些想知道的人,我正在研究与绝育服务相关的医院数据库。)
我想要什么/TL;DR
我需要一个 SELECT 查询(或函数定义)返回整个数据库的所有列 (schema_name,table_name,column_name) 或 (table_name,column_name) 具有引用指定列(参数)的外键约束。
【问题讨论】:
标签: sql postgresql foreign-keys plpgsql information-schema