我在下面创建了测试表和相关视图。
create table test_col_drp (col1 varchar(100), col2 varchar(100), col3 varchar(100));
create view test_col_drp_vw1 as select col1 col1_vw1, col2 col2_vw1, col3 col3_vw1 from test_col_drp;
create view test_col_drp_vw2 as select col1_vw1 col1_vw2, col2_vw1 col2_vw2, col3_vw1 col3_vw2 from test_col_drp_vw1;
我正在尝试从表格中删除一列但却低于错误:
alter table test_col_drp drop column col3;
ERROR: cannot drop table test_col_drp column col3 because other objects depend on it
DETAIL: view test_col_drp_vw1 depends on table test_col_drp column col3 view test_col_drp_vw2 depends on view test_col_drp_vw1
HINT: Use DROP ... CASCADE to drop the dependent objects too.
********** Error **********
删除列并重新创建所有相关视图的最佳方法是什么?
致力于: x86_64-pc-mingw64上的PostgreSQL 9.6.6,由gcc.exe编译(Rev5,由MSYS2项目构建)4.9.2,64位
Windows 10
答案 0 :(得分:0)
首先,您必须删除视图。然后,执行alter table,最后再次创建视图。参见:
-- This is what you have in your database
create table test_col_drp (col1 varchar(100), col2 varchar(100), col3 varchar(100));
create view test_col_drp_vw1 as select col1 col1_vw1, col2 col2_vw1, col3 col3_vw1 from test_col_drp;
create view test_col_drp_vw2 as select col1_vw1 col1_vw2, col2_vw1 col2_vw2, col3_vw1 col3_vw2 from test_col_drp_vw1;
-- drop views and alter table
drop view test_col_drp_vw2;
drop view test_col_drp_vw1;
alter table test_col_drp drop column col3;
-- creating the views again without col3
create view test_col_drp_vw1 as select col1 col1_vw1, col2 col2_vw1 from test_col_drp;
create view test_col_drp_vw2 as select col1_vw1 col1_vw2, col2_vw1 col2_vw2 from test_col_drp_vw1;
另一种方法是使用drop cascade。在这种情况下,您不需要单独删除每个视图,但仍需要重新创建它们:
alter table test_col_drp drop column col3 cascade;
-- creating the views again without col3
create view test_col_drp_vw1 as select col1 col1_vw1, col2 col2_vw1 from test_col_drp;
create view test_col_drp_vw2 as select col1_vw1 col1_vw2, col2_vw1 col2_vw2 from test_col_drp_vw1;
另一种选择是创建一个SQL命令,使用cascade和create view生成alter table:
with query_result as (
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
, row_number() over() as id
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 1=1
-- AND source_ns.nspname = 'public'
AND source_table.relname like 'test_col_drp%'
AND pg_attribute.attnum > 0
AND pg_attribute.attname = 'col3'
)
select concat('alter table ', source_table, ' drop column ' , column_name, ' cascade;' ) as sql_command from query_result where id = 1
union all
select concat('create or replace view ', dependent_view, ' as select * from ', source_table, ';') as sql_command from query_result
然后,输出将是:
alter table test_col_drp drop column col3 cascade;
create or replace view test_col_drp_vw1 as select * from test_col_drp;
create or replace view test_col_drp_vw2 as select * from test_col_drp_vw1;