3

如何使用查询从 PostgreSQL 中删除所有用户定义的视图?就像我们可以使用 query 删除所有函数一样:

SELECT 'DROP FUNCTION ' || ns.nspname || '.' || proname 
       || '(' || oidvectortypes(proargtypes) || ');'
FROM pg_proc INNER JOIN pg_namespace ns ON (pg_proc.pronamespace = ns.oid)
WHERE ns.nspname = 'my_messed_up_schema'  order by proname;
4

2 回答 2

6

删除特定模式中所有视图的脚本:

SELECT 'DROP VIEW ' || t.oid::regclass || ';' -- CASCADE?
FROM   pg_class t
JOIN   pg_namespace n ON n.oid = t.relnamespace
WHERE  t.relkind = 'v'
AND    n.nspname = 'my_messed_up_schema -- select by schema(s)
ORDER  BY 1;

强制转换为regclass( t.oid::regclass) 会阻止SQLi,因为否则会自动引用非法名称。你也可以使用quote_ident().

您的示例本质上是不安全的。

Do马上:

DO
$$
DECLARE
   sql text;
BEGIN
   SELECT INTO sql
          string_agg('DROP VIEW ' || t.oid::regclass || ';', ' ')  -- CASCADE?
   FROM   pg_class t
   JOIN   pg_namespace n ON n.oid = t.relnamespace
   WHERE  t.relkind = 'v'
   AND    n.nspname = 'my_messed_up_schema';

   IF sql IS NOT NULL THEN
      -- RAISE NOTICE '%', sql;  -- to debug
      EXECUTE sql;
   ELSE
      RAISE NOTICE 'No views found. Nothing dropped.';
   END IF;
END
$$

DO需要 PostgreSQL 9.0 或更高版本。

如果没有找到视图,该IF构造会避免异常。

如果您有引用其他视图的视图,则必须CASCADE按从上到下的层次顺序添加关键字或删除视图。

在你做之前总是检查你要放弃的东西,否则你可能会用核弹自己。如果您不确定,请启动事务,放下炸弹,检查一切是否正常,然后提交或回滚。

BEGIN;
DO$$
  ...
$$;

-- check ..

ROLLBACK; -- if something wrong
COMMIT; -- else

请注意,您不能COMMITROLLBACK plpgsql 块内。只在外面。

于 2012-11-30T21:48:50.587 回答
0

使用表pg_class

你需要relkind = 'v'

于 2012-11-30T11:46:43.533 回答