PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Làm thế nào để tìm bảng kế thừa theo chương trình trong PostgreSQL?

Vì bạn đang sử dụng phiên bản PostgreSQL cũ như vậy, bạn có thể sẽ phải sử dụng hàm PL / PgSQL để xử lý độ sâu kế thừa> 1. Trên PostgreSQL hiện đại (hoặc thậm chí là 8.4), bạn sẽ sử dụng biểu thức bảng chung đệ quy (WITH RECURSIVE ).

pg_catalog.pg_inherits bảng là chìa khóa. Đã cho:

create table pp( );     -- The parent we'll search for
CREATE TABLE notpp(); -- Another root for multiple inheritance
create table cc( ) inherits (pp); -- a 1st level child of pp
create table dd( ) inherits (cc,notpp); -- a 2nd level child of pp that also inherits aa
create table notshown( ) inherits (notpp); -- Table that inherits only notpp
create table ccdd () inherits (cc,dd) -- Inheritance is a graph not a tree; join node

Kết quả chính xác sẽ tìm thấy cc , ddccdd , nhưng không tìm thấy notpp hoặc notshown .

Một truy vấn chuyên sâu là:

SELECT pg_namespace.nspname, pg_class.relname 
FROM pg_catalog.pg_inherits 
  INNER JOIN pg_catalog.pg_class ON (pg_inherits.inhrelid = pg_class.oid) 
  INNER JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid) 
WHERE inhparent = 'pp'::regclass;

... nhưng điều này sẽ chỉ tìm thấy cc .

Đối với kế thừa đa chiều (tức là tableC kế thừa tableB kế thừa tableA ) bạn phải mở rộng điều đó thông qua CTE đệ quy hoặc một vòng lặp trong PL / PgSQL, sử dụng các phần tử con của vòng lặp cuối cùng làm cha mẹ trong vòng tiếp theo.

Cập nhật :Đây là phiên bản tương thích 8.3 sẽ tìm một cách đệ quy tất cả các bảng kế thừa trực tiếp hoặc gián tiếp từ một bảng gốc nhất định. Nếu sử dụng đa kế thừa, nó sẽ tìm bất kỳ bảng nào có bảng đích là một trong các bảng cha của nó tại bất kỳ điểm nào dọc theo cây.

CREATE OR REPLACE FUNCTION find_children(oid) RETURNS SETOF oid as $$
SELECT i.inhrelid FROM pg_catalog.pg_inherits i WHERE i.inhparent = $1
UNION
SELECT find_children(i.inhrelid) FROM pg_catalog.pg_inherits i WHERE i.inhparent = $1;
$$ LANGUAGE 'sql' STABLE;

CREATE OR REPLACE FUNCTION find_children_of(parentoid IN regclass, schemaname OUT name, tablename OUT name) RETURNS SETOF record AS $$
SELECT pg_namespace.nspname, pg_class.relname 
        FROM find_children($1) inh(inhrelid) 
          INNER JOIN pg_catalog.pg_class ON (inh.inhrelid = pg_class.oid) 
          INNER JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid);
$$ LANGUAGE 'sql' STABLE;

Cách sử dụng:

regress=# SELECT * FROM find_children_of('pp'::regclass);
 schemaname | tablename 
------------+-----------
 public     | cc
 public     | dd
 public     | ccdd
(3 rows)

Đây là phiên bản CTE đệ quy, sẽ hoạt động nếu bạn cập nhật Pg, nhưng sẽ không hoạt động trên phiên bản hiện tại của bạn. IMO sạch hơn nhiều.

WITH RECURSIVE inh AS (
        SELECT i.inhrelid FROM pg_catalog.pg_inherits i WHERE inhparent = 'pp'::regclass
        UNION
        SELECT i.inhrelid FROM inh INNER JOIN pg_catalog.pg_inherits i ON (inh.inhrelid = i.inhparent)
)
SELECT pg_namespace.nspname, pg_class.relname 
    FROM inh 
      INNER JOIN pg_catalog.pg_class ON (inh.inhrelid = pg_class.oid) 
      INNER JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid);


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cốt lõi của Entity Framework - Chứa phân biệt chữ hoa chữ thường hay không phân biệt chữ hoa chữ thường?

  2. Dấu ngoặc kép không chính xác khi sử dụng crosstab () trong PostgreSQL

  3. Ánh xạ cột PostgreSQL JSON thành thuộc tính thực thể Hibernate

  4. Spring:Cách sử dụng KeyHolder với PostgreSQL

  5. Sử dụng sails.js với cơ sở dữ liệu postgres hiện có