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

Sql 查找使用需要更改类型的列的所有主键和外键,sql,postgresql,Sql,Postgresql,我需要将一个列的数据类型从int4更改为varchar(30),这个列在其他几个表中是主键和外键。 因此,我试图列出所有使用此列的PK和FK,并在修改所有这些表和约束之后 所以我有两个问题: 1) 有没有更聪明的方法来改变这种类型 2) 如何将所有这些PK和FK分别列出一行? (使用下面的“选择”,约束中的每列都有一行) 使用postgres 10.10 select tco.constraint_name, tco.constraint_type, kcu.table

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

所以我有两个问题:

1) 有没有更聪明的方法来改变这种类型

2) 如何将所有这些PK和FK分别列出一行? (使用下面的“选择”,约束中的每列都有一行)

使用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;

不管你想要达到什么样的目标会产生什么样的误解,下面是(我认为)在你的“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;

哇!是否确实要将pkey转换为varchar类型?索引处理肯定会爆炸…我们知道从这个角度来看不是一个好的选择,谢谢你的警告。哇。。。是否确实要将pkey转换为varchar类型?索引处理肯定会爆炸…我们知道从这个角度来看这不是一个好的选择,谢谢你的警告。很好,谢谢你,
pg\u get\u constraintdef(con.oid)
真的很有用你需要更多的帮助吗?事实上,如果在第一个选择中有一个按collumn名称的过滤器,或者在第二个选择中有约束定义,那么这将非常好。不要忘记批准答案;)很好,谢谢你,
pg\u get\u constraintdef(con.oid)
真的很有用。你还需要其他帮助吗?事实上,如果在第一个选择中有一个按column名称的过滤器,或者在第二个选择中有约束定义,那就很好了。别忘了批准答案;)