Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按照依赖项的顺序对表进行排序-Postgres_Sql_Postgresql - Fatal编程技术网

Sql 按照依赖项的顺序对表进行排序-Postgres

Sql 按照依赖项的顺序对表进行排序-Postgres,sql,postgresql,Sql,Postgresql,其目的是允许插入脚本向模式中的所有表添加数据,这样就不会在约束中产生任何冲突。我从information_schema.tables中获取表,并从information_schema.table_约束中获取约束,但不确定如何与按外键约束顺序排序的表进行比较。请帮忙 下表生成重复的表名: select a.table_name,b.ordinal_position from information_schema.tables a left outer join information_s

其目的是允许插入脚本向模式中的所有表添加数据,这样就不会在约束中产生任何冲突。我从information_schema.tables中获取表,并从information_schema.table_约束中获取约束,但不确定如何与按外键约束顺序排序的表进行比较。请帮忙

下表生成重复的表名:

select a.table_name,b.ordinal_position
from information_schema.tables a left outer join
     information_schema.key_column_usage b
     on a.table_name = b.table_name

您需要一个遍历外键关系的整个依赖关系树的递归查询

以下查询对简单依赖项执行此操作。它不处理循环外键

with recursive fk_tree as (
  -- All tables not referencing anything else
  select t.oid as reloid, 
         t.relname as table_name, 
         s.nspname as schema_name,
         null::text as referenced_table_name,
         null::text as referenced_schema_name,
         1 as level
  from pg_class t
    join pg_namespace s on s.oid = t.relnamespace
  where relkind = 'r'
    and not exists (select *
                    from pg_constraint
                    where contype = 'f'
                      and conrelid = t.oid)
    and s.nspname = 'public' -- limit to one schema 

  union all 

  select ref.oid, 
         ref.relname, 
         rs.nspname,
         p.table_name,
         p.schema_name,
         p.level + 1
  from pg_class ref
    join pg_namespace rs on rs.oid = ref.relnamespace
    join pg_constraint c on c.contype = 'f' and c.conrelid = ref.oid
    join fk_tree p on p.reloid = c.confrelid
  where ref.oid != p.reloid  -- do not enter to tables referencing theirselves.
), all_tables as (
  -- this picks the highest level for each table
  select schema_name, table_name,
         level, 
         row_number() over (partition by schema_name, table_name order by level desc) as last_table_row
  from fk_tree
)
select schema_name, table_name, level
from all_tables at
where last_table_row = 1
order by level;
对于下表结构:

create table customer (id integer primary key);
create table product (id integer primary key);
create table manufacturer (id integer primary key);
create table manufactured_by (product_id integer references product, manufacturer_id integer references manufacturer);
create table distributor (id integer primary key);
create table orders (id integer primary key, customer_id integer references customer);
create table order_line (id integer primary key, order_id integer references orders);
create table invoice (id integer, order_id integer references orders);
create table delivery (oder_line_id integer references order_line, distributor_id integer references distributor);
这将返回以下结果:

schema_name | table_name |级别
-------------+-----------------+------
公共|客户| 1
公共|分销商| 1
公共|制造商| 1
公共|产品| 1
公共|制造| 2
公共|命令| 2
公共|秩序|线| 3
公共|发票| 3
公共|交付| 4
这意味着您需要先插入
客户
,然后才能插入
订单
。具有相同级别的表的插入顺序并不重要

使用CTE
所有表格的中间步骤必须只列出一次每个表格。否则
制造的表将列出两次:

schema_name | table_name |级别
------------+-----------------+------
公共|客户| 1
公共|产品| 1
公共|制造商| 1
公共|分销商| 1
公共|制造| 2
公共|制造| 2
公共|命令| 2
公共|交付| 2
公共|秩序|线| 3
公共|发票| 3
公共|交付| 4

此查询可能需要更多调整(特别是防止依赖关系树中出现循环),但它应该给您一个开始。

使用
pg_dump
生成插入脚本-它将自动处理约束。我需要的是立即编写查询。.回答得很好!谢谢