获取postgresql中其他表中没有任何引用的行列表

时间:2015-12-18 11:33:30

标签: sql postgresql

我有一个表,在整个系统中保存翻译,其他表引用它,例如:

Table "translations"
id | title
----------------------------
 1 | First Translation
 2 | Second Translation

第二个表,外键指向translations

Table "article"
id | translation_id | ...
 1 | 1              | ...

我想获得一个未被任何其他表引用的行列表(在此示例中,id = 2的行)。

表的数量可能会改变,我希望有一个通用的解决方案,可以在psql中运行本机关系机制。

1 个答案:

答案 0 :(得分:0)

我已经完成了你需要的功能。 Bellow是我为测试它而创建的示例数据。在我的数据示例中,返回值应为表ID 4中的t1。对于您的情况,t1表将是translations表。

您必须将其更改为您的表格。这不应该是困难的。

create table t1 (
    id integer primary key not null,
    lang varchar(10)
);

create table t2 (
    id integer primary key not null,
    id_t1 integer,
     constraint fk_t2 foreign key (id_t1) references t1(id)
);

create table t3 (
    id integer primary key not null,
    id_t1 integer,
    constraint fk_t3 foreign key (id_t1) references t1(id)
);

insert into t1 values (1, 'pt'), (2, 'us'), (3,'cn'), (4,'uk');
insert into t2 values (1, 1), (2,2);
insert into t3 values (1, 1), (2,3);

CREATE OR REPLACE FUNCTION listAllReferences()
  RETURNS setof integer AS
$$
declare
   fullSQL text;
   rs RECORD;
begin
   fullSQL := '';
   for rs in 
        SELECT 'select t1.id from t1 inner join ' || tc.table_name || ' ON ('||tc.table_name||'.'||kcu.column_name||' = t1.id)' as sel
          FROM information_schema.table_constraints AS tc 
                 JOIN information_schema.key_column_usage AS kcu
                   ON tc.constraint_name = kcu.constraint_name
                 JOIN information_schema.constraint_column_usage AS ccu
                   ON ccu.constraint_name = tc.constraint_name
         WHERE constraint_type = 'FOREIGN KEY' 
           AND ccu.table_name='t1' loop
      if fullSQL != '' then
         fullSQL := fullSQL || ' union ';
      end if;
      fullSQL := fullSQL || rs.sel;
   end loop;
   return query
      execute 'select t1.id 
                 from t1 left join ('||fullSQL||') alltb on (t1.id = alltb.id)
                where alltb.id is null';
   return;

end;
$$
  LANGUAGE plpgsql;

使用它只需:

select * from listAllReferences();

它将返回:

listallreferences
       4

参考您的语言表的未来表也将被涵盖,因为我从PostgreSQL的INFORMATION_SCHEMA获取数据

此外,您可能必须在隐式游标AND tc.table_schema = 'yourSchemaName'

上向查询添加另一个filter()