在一个查询中删除Postgresql 9.3中的普通或物化视图

时间:2013-10-22 17:11:06

标签: postgresql materialized-views sql-drop

我的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命令启动,但由于视图类型错误(它不正常)而失败。任何人都可以建议一个适用于物化和普通视图的通用解决方法吗?

2 个答案:

答案 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');