我的PostgreSQL中有一个视图,根据某些情况,它可以是正常的或物化的。我正在尝试编写一个查询,这个查询肯定会丢弃视图,并且无论目前它是什么类型都没有错误。但是,这似乎并不容易。当我尝试使用以下代码时,出现错误:
DROP VIEW IF EXISTS {{ schema }}.{{ viewName }};
DROP MATERIALIZED VIEW IF EXISTS {{ schema }}.{{ viewName }};
SQLSTATE[42809]: Wrong object type: 7 ERROR: "{{ viewName }}" is not a view
HINT: Use DROP MATERIALIZED VIEW to remove a materialized view.
因此,当视图实现时,看起来'IF EXISTS'在第一行中的结果为true,DROP命令启动,但由于视图类型错误(它不正常)而失败。任何人都可以建议一个适用于物化和普通视图的通用解决方法吗?
答案 0 :(得分:1)
没有。或者不容易,无论如何......正如Postgres报道的那样,两者是不同的动物。
我认为,如果存在踢的原因是因为这一切都存在于pg_class中。如果您创建了一个测试表,并尝试运行drop view if exists test
,则会出现类似的错误。
在检查pg_catalog.pg_class中实体的类型后,您可以在DO块中生成动态SQL语句,以确定您正在处理的内容的精确类型(表,视图) ,垫视图等。)。
答案 1 :(得分:0)
以下是满足您需求的PLSQL函数:
CREATE OR REPLACE FUNCTION drop_any_type_of_view_if_exists(IN _viewname text)
RETURNS VOID AS
$$
BEGIN
RAISE LOG 'Looking for (materialized) view named %', _viewname;
IF EXISTS (SELECT matviewname from pg_matviews where schemaname = 'public' and matviewname = _viewname) THEN
RAISE NOTICE 'DROP MATERIALIZED VIEW %', _viewname;
EXECUTE 'DROP MATERIALIZED VIEW ' || quote_ident(_viewname);
ELSEIF EXISTS (SELECT viewname from pg_views where schemaname = 'public' and viewname = _viewname) THEN
RAISE NOTICE 'DROP VIEW %', _viewname;
EXECUTE 'DROP VIEW ' || quote_ident(_viewname);
ELSE
RAISE NOTICE 'NO VIEW % found', _viewname;
END IF;
END;
$$ LANGUAGE plpgsql;
您还可以使用以下语法调用创建的函数
SELECT drop_any_type_of_view_if_exists('v_my_view');