【问题标题】:Query to get dependant view definition and details for given table column查询以获取给定表列的依赖视图定义和详细信息
【发布时间】:2018-08-31 04:37:21
【问题描述】:
select 'CREATE VIEW ' || views || E' AS \n'
       || pg_get_viewdef(views, true) as view_definition
  from (
    select distinct(r.ev_class::regclass) as "views",
           pg_class.relname as table_name,
           pg_attribute.attname as column_name,
           pg_class.dependent_view as rel_obj_name 
      from pg_depend d join pg_rewrite r on r.oid = d.objid 
     where refclassid = 'pg_class'::regclass
       and refobjid = 'DBNAME.TABLENAME'::regclass
       and classid = 'pg_rewrite'::regclass
       and pg_get_viewdef(r.ev_class, true) ~ 'COLUMNNAME') as x;

我想运行此查询并在表和列上提取viewdefinition(Dependant) 以及其他详细信息。

目前它给出以下错误:

ERROR:  missing FROM-clause entry for table "pg_class"
LINE 3: ...(select distinct(r.ev_class::regclass) as "views",pg_class.r...
SQL state: 42P01
Character: 162

上述查询中使用的元数据表是:

                   Table "pg_catalog.pg_class"
       Column        |   Type    | Collation | Nullable | Default
---------------------+-----------+-----------+----------+---------
 relname             | name      |           | not null |
 relnamespace        | oid       |           | not null |
 reltype             | oid       |           | not null |
 reloftype           | oid       |           | not null |
 relowner            | oid       |           | not null |
 relam               | oid       |           | not null |
 relfilenode         | oid       |           | not null |
 reltablespace       | oid       |           | not null |
 relpages            | integer   |           | not null |
 reltuples           | real      |           | not null |
 relallvisible       | integer   |           | not null |
 reltoastrelid       | oid       |           | not null |
 relhasindex         | boolean   |           | not null |
 relisshared         | boolean   |           | not null |
 relpersistence      | "char"    |           | not null |
 relkind             | "char"    |           | not null |
 relnatts            | smallint  |           | not null |
 relchecks           | smallint  |           | not null |
 relhasoids          | boolean   |           | not null |
 relhaspkey          | boolean   |           | not null |
 relhasrules         | boolean   |           | not null |
 relhastriggers      | boolean   |           | not null |
 relhassubclass      | boolean   |           | not null |
 relrowsecurity      | boolean   |           | not null |
 relforcerowsecurity | boolean   |           | not null |
 relispopulated      | boolean   |           | not null |
 relreplident        | "char"    |           | not null |
 relfrozenxid        | xid       |           | not null |
 relminmxid          | xid       |           | not null |
 relacl              | aclitem[] |           |          |
 reloptions          | text[]    |           |          |


             Table "pg_catalog.pg_depend"
  Column    |  Type   | Collation | Nullable | Default
------------+---------+-----------+----------+---------
classid     | oid     |           | not null |
objid       | oid     |           | not null |
objsubid    | integer |           | not null |
refclassid  | oid     |           | not null |
refobjid    | oid     |           | not null |
refobjsubid | integer |           | not null |
deptype     | "char"  |           | not null |

               Table "pg_catalog.pg_rewrite"
   Column   |     Type     | Collation | Nullable | Default
------------+--------------+-----------+----------+---------
 rulename   | name         |           | not null |
 ev_class   | oid          |           | not null |
 ev_type    | "char"       |           | not null |
 ev_enabled | "char"       |           | not null |
 is_instead | boolean      |           | not null |
 ev_qual    | pg_node_tree |           |          |
 ev_action  | pg_node_tree |           |          

查询 1:

SELECT dependent_ns.nspname as dependent_schema
, dependent_view.relname as dependent_view 
, source_ns.nspname as source_schema
, source_table.relname as source_table
, pg_attribute.attname as column_name
FROM pg_depend 
JOIN pg_rewrite ON pg_depend.objid = pg_rewrite.oid 
JOIN pg_class as dependent_view ON pg_rewrite.ev_class = dependent_view.oid 
JOIN pg_class as source_table ON pg_depend.refobjid = source_table.oid 
JOIN pg_attribute ON pg_depend.refobjid = pg_attribute.attrelid 
    AND pg_depend.refobjsubid = pg_attribute.attnum 
JOIN pg_namespace dependent_ns ON dependent_ns.oid = dependent_view.relnamespace
JOIN pg_namespace source_ns ON source_ns.oid = source_table.relnamespace
WHERE 
source_ns.nspname = 'SCHEMANAME'
AND source_table.relname = 'TABLENAME'
AND pg_attribute.attnum > 0 
AND pg_attribute.attname = 'COLUMNNAME'
ORDER BY 1,2;

查询 2:

select 'CREATE VIEW ' || views || E' AS \n'
       || pg_get_viewdef(views, true) as view_definition
     from (select distinct(r.ev_class::regclass) as "views" 
          from pg_depend d join pg_rewrite r on r.oid = d.objid 
         where refclassid = 'pg_class'::regclass
           and refobjid = 'SCHEMANAME.TABLENAME'::regclass
           and classid = 'pg_rewrite'::regclass
           and pg_get_viewdef(r.ev_class, true) ~ 'columnname') as x;

如何合并这两个查询以从单个查询中获取名称和视图定义?

【问题讨论】:

  • 要从表中选择列,您需要在FROM 子句中指定表。你能解释一下你想要达到的目标吗?另外,我认为pg_class 中没有dependent_view 列。
  • 我需要一个查询,它会返回一个表和它的列的依赖视图..(当表名和列名被传递时)......它应该给出视图定义、表名、视图名、列名等。 .我还在上面的主查询中编辑和添加了元数据表
  • 请参见此处:mwenus.blogspot.de/2014/04/…,但我认为列级别的信息不可用
  • @a_horse_with_no_name...我也检查了该链接,但没有帮助..不幸的是,我现在可以获得 2 个查询(一个用于视图相关定义),即第一个和第二个用于其余信息,例如(列名,表名,视图名)...否则我如何合并这两个查询?这也可以解决我的问题

标签: sql postgresql sql-view database-metadata


【解决方案1】:

认为这就是你要找的东西:

SELECT v.relnamespace::regnamespace AS dependent_schema
     , v.relname                    AS dependent_table
     , t.relnamespace::regnamespace AS source_schema
     , t.relname                    AS source_table
     , a.attname                    AS column_name
     , format(E'CREATE VIEW %s AS\n%s'
            , v.oid::regclass, pg_get_viewdef(r.ev_class, true)) AS view_definition
FROM   pg_class     t
JOIN   pg_attribute a ON a.attrelid = t.oid
JOIN   pg_depend    d ON d.refobjid = a.attrelid
                     AND d.refobjsubid = a.attnum
JOIN   pg_rewrite   r ON r.oid = d.objid
JOIN   pg_class     v ON v.oid = r.ev_class
WHERE  t.oid = 'SCHEMANAME.TABLENAME'::regclass -- table name HERE
AND    a.attname = 'COLUMNAME'                  -- column name HERE
AND    NOT attisdropped                         -- no dropped cols
AND    attnum > 0                               -- no system cols
AND    d.classid = 'pg_rewrite'::regclass       -- it's a view
AND    r.ev_type = '1'                          -- only SELECT
AND    r.is_instead;                            -- INSTEAD rule

比您的任何一个查询都更简单、更快、更安全。但这仍然建立在可能会在下一个主要版本中更改的实现细节的基础上。所以不要依赖它。

输入 ('SCHEMANAME.TABLENAME') 可选地包括架构名称。 Postgres 默认使用 search_path 来表示不合格的名称。

视图定义使用v.oid::regclass,它根据当前的search_path 对视图名称进行模式限定。适应您的需求。

相关:

【讨论】:

  • ..感谢您的查询,但它并不能完全解决我的问题,因为我的输出中也需要视图定义..
  • @rock_techie:我添加了定义。
  • 感谢 Erwin 的询问和帮助...感谢
猜你喜欢
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 1970-01-01
  • 1970-01-01
  • 2021-10-18
  • 1970-01-01
相关资源
最近更新 更多