sql - 查找所有使用需要类型更改的列的主键和外键

标签 sql postgresql

我需要将一个列的数据类型从 int4 更改为 varchar(30),并且该列在其他几个表中是主键和外键。 所以我试图列出所有使用此列的 pks 和 fks,并在更改所有这些表和约束之后。

所以我有两个问题:

1) 有更聪明的方法来进行这种类型更改吗?

2) 我如何列出所有这些 pks 和 fks,每行一行? (在下面的选择中,约束中的每一列都有一行)

使用 postgres 10.10

select 
    tco.constraint_name,
    tco.constraint_type,
    kcu.table_schema,
    kcu.table_name,
    ccu.table_schema,
    ccu.table_name,
    ccu.column_name
from information_schema.table_constraints tco
join information_schema.key_column_usage kcu 
     on kcu.constraint_name = tco.constraint_name
     and kcu.constraint_schema = tco.constraint_schema
     and kcu.constraint_name = tco.constraint_name
JOIN information_schema.constraint_column_usage ccu ON ccu.constraint_name = tco.constraint_name
where 
    ( tco.constraint_type = 'PRIMARY KEY' or  tco.constraint_type = 'FOREIGN KEY' )
    and 
    kcu.column_name='column_name'

最佳答案

不管您想要实现的目标可能造成的误解如何,这里的代码(我认为)在您的“2)”上执行您想要的操作。

测试结构:

drop table if exists test;
create table test (id int primary key);
create table test_2 (id int, id_1 int);
alter table test_2 add constraint pk_test_2 primary key (id, id_1);
alter table test_2 add constraint fk_test_2_test_1 foreign key (id_1) references test (id);
create table test_3 (id int primary key, id_2 int, id_1 int);
alter table test_3 add constraint fk_test_3_test_2 foreign key (id_2, id_1) references test_2 (id, id_1);

查询:

SELECT
    rel.relname as table_name
    , ccu.relname as ref_table_name
    , pg_get_constraintdef(con.oid) as con_def                      
    , con.conname
    , col.attname
FROM pg_catalog.pg_constraint con                                   
    INNER JOIN pg_catalog.pg_class rel                              
        ON rel.oid = con.conrelid
    INNER JOIN pg_catalog.pg_namespace nsp                          
        ON nsp.oid = connamespace                           
    left outer JOIN pg_class AS ccu 
        ON con.confrelid = ccu.oid
    JOIN LATERAL UNNEST(con.conkey) WITH ORDINALITY AS u(attnum, attposition) ON TRUE
    JOIN pg_attribute col ON (col.attrelid = rel.oid AND col.attnum = u.attnum)
WHERE nsp.nspname = 'public'
    and col.attname = 'id';

或者像这样:

select 
    tco.constraint_name,
    tco.constraint_type,
    kcu.table_schema,
    kcu.table_name,
    ccu.table_schema,
    ccu.table_name,
    string_agg(distinct ccu.column_name, '; ')
from information_schema.table_constraints tco
join information_schema.key_column_usage kcu 
     on kcu.constraint_name = tco.constraint_name
     and kcu.constraint_schema = tco.constraint_schema
     and kcu.constraint_name = tco.constraint_name
JOIN information_schema.constraint_column_usage ccu ON ccu.constraint_name = tco.constraint_name
where 
    ( tco.constraint_type = 'PRIMARY KEY' or  tco.constraint_type = 'FOREIGN KEY' )
    and tco.constraint_schema = 'public'
group by tco.constraint_name,
    tco.constraint_type,
    kcu.table_schema,
    kcu.table_name,
    ccu.table_schema,
    ccu.table_name;

关于sql - 查找所有使用需要类型更改的列的主键和外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57975553/

相关文章:

java - Hibernate异常: Unable to access lob stream

sql - SQL 2000 中的多个内连接

postgresql - PL/pgSQL 函数返回不正确的按位结果

SQL 按类型和位置唯一分组

c# - 无法从存储过程中获取值

sql - 从 Laravel 4 中的不同 PostgreSQL 模式中选择表

postgresql - 将 Postgres 表导出到 csv

mysql - 使用 codeigniter 的事件记录模式的 UNION 查询

sql - 按最新 LastModifiedDatetime 排序的前 30 条不同记录

mysql - 向现有查询添加连接和计数会膨胀求和和计数函数输出