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;
如何合并这两个查询以从单个查询中获取名称和查看定义?
答案 0 :(得分:0)
我认为这就是您要寻找的东西
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
限定视图名称。适应您的需求。
相关: