查询以获取给定 table 列的相关视图定义和详细信息
Query to get dependant view definition and details for given table column
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)
table 和列以及其他详细信息。
目前它给出以下错误:
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是:
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;
如何合并这两个查询以从单个查询中获取名称和视图定义?
我认为这就是你要找的:
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
架构限定视图名称。适应您的需求。
相关:
- How does the search_path influence identifier resolution and the "current schema"
- Get list of functions used in a view
- Table name as a PostgreSQL function parameter
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)
table 和列以及其他详细信息。
目前它给出以下错误:
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是:
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;
如何合并这两个查询以从单个查询中获取名称和视图定义?
我认为这就是你要找的:
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
架构限定视图名称。适应您的需求。
相关:
- How does the search_path influence identifier resolution and the "current schema"
- Get list of functions used in a view
- Table name as a PostgreSQL function parameter