如何使用PostgreSQL中的EXECUTE语句删除物化视图

时间:2014-11-25 11:08:30

标签: sql postgresql dynamic-sql postgresql-9.3 materialized-views

我的数据库是PostgreSQL(9.3.5)。

我们有超过500个物化视图,并希望删除其中一些。
为此,我们从pg_class

中获取这些具体化视图
FOR MVNAME IN (SELECT relname
            FROM pg_class
            WHERE relkind='m')

LOOP
   EXECUTE 'DROP MATERIALIZED VIEW '||MVNAME||'';
END LOOP;

在执行时它给我们一个错误:

ERROR: "dimension" is not a materialized view
SQL state: 42809

Hint: Use DROP FOREIGN TABLE to remove a foreign table.
Context: SQL statement "DROP MATERIALIZED VIEW dimension"
PL/pgSQL function test_drop_dims() line 14 at EXECUTE statement

我们可以使用以下方式删除一个物化视图:

DROP MATERIALIZED VIEW MVNAME;

但我们无法使用EXECUTE语句删除多个物化视图。

1 个答案:

答案 0 :(得分:2)

错误消息表明您使用双引号创建了非标准名称,例如"Dimension"(大小写混合大小写)。您需要在动态SQL中正确引用和转义标识符。不仅因为它不能以任何其他方式工作,还要避免 SQL注入 此外,您可能必须架构限定名称。详细说明:

另外,您可以drop multiple MV's at once并且不需要这样循环:

EXECUTE (
   SELECT 'DROP MATERIALIZED VIEW ' || string_agg(oid::regclass::text, ', ')
   FROM   pg_class
   WHERE  relkind = 'm'
   );

注意这一点!它会删除当前数据库的所有模式中的所有实体化视图。您可能需要先仔细检查。

请注意我使用的是oid::regclass::text,而不是quote_ident(relname)。这也会自动覆盖模式名称。 Detailed explantaion in the provided link.