如何在 postgresql 中创建只读视图,类似于 oracle?

Posted

技术标签:

【中文标题】如何在 postgresql 中创建只读视图,类似于 oracle?【英文标题】:How to create a read only view in postgresql , similar to oracle? 【发布时间】:2020-01-21 09:17:17 【问题描述】:

我想在 PostgreSQL 中创建只读视图。我们可以在 Oracle 中创建,但在 PostgreSQL 中无法创建。

我尝试创建只读视图,但在 READ ONLY 处出现语法错误。

CREATE OR REPLACE VIEW VIEW NAME() 
from table names 
where filter condition1=filter 
  condition2 
with READ ONLY; 

但是READ ONLY 在 PostgreSQL 中不起作用。如何在 PostgreSQL 中创建只读视图?

【问题讨论】:

【参考方案1】:

我不认为 Postgres 提供了一种将视图显式定义为 read-onöy 的方法。

The documentation 状态:

简单的视图可以自动更新

但是:

不满足所有这些条件的更复杂的视图默认是只读的。

文档列出了只读视图的限制:

如果满足以下所有条件,则视图会自动更新:

视图的 FROM 列表中必须有一个条目,该条目必须是表或另一个可更新视图。

视图定义不得在顶层包含 WITH、DISTINCT、GROUP BY、HAVING、LIMIT 或 OFFSET 子句。

视图定义不得在顶层包含集合操作(​​UNION、INTERSECT 或 EXCEPT)。

视图的选择列表不得包含任何聚合、窗口函数或集合返回函数。

简单视图可以自动更新:系统将允许在视图上使用 INSERT、UPDATE 和 DELETE 语句,就像在常规表上一样。如果满足以下所有条件,则视图会自动更新:

视图的 FROM 列表中必须有一个条目,该条目必须是表或另一个可更新视图。

视图定义不得在顶层包含 WITH、DISTINCT、GROUP BY、HAVING、LIMIT 或 OFFSET 子句。

视图定义不得在顶层包含集合操作(​​UNION、INTERSECT 或 EXCEPT)。

视图的选择列表不能包含任何聚合、窗口函数或集合返回函数

因此,如果您的视图不满足所有这些条件,则它是只读的。如果您想将一个简单的视图设为只读,则(次优)选项是调整其定义,使其违反上述规则之一。

例如,您可以添加一个虚拟的WITH 子句:

CREATE VIEW myview AS 
WITH dummy AS (SELECT 1)
-- real view definition here

【讨论】:

【参考方案2】:

您应该使用 PostgreSQL 中的权限来处理这个问题。

只要确保没有人有权修改视图。

请注意,您还可以撤销视图所有者的权限。

【讨论】:

【参考方案3】:

另一种方法是创建假联接。任何连接都会立即取消它成为可更新视图的资格。例如:

CREATE VIEW public.west_country as select
city.id,
city_name,
country_id
from public.city
where city.country_id = 1 
WITH CHECK OPTION;

这将创建一个可更新的视图。但是,如果您将下面的代码片段与 join 语句一起使用,它将是只读的。

CREATE VIEW public.west_country_rw as select
city.id,
city_name,
country_id
from public.city
left join (select -1 as "id" ) as tmp on tmp.id = city.id
where city.country_id = 1;

【讨论】:

以上是关于如何在 postgresql 中创建只读视图,类似于 oracle?的主要内容,如果未能解决你的问题,请参考以下文章

sql 如何在PostgreSQL中创建只读用户

创建 PostgreSQL 只读用户错误:关系 _foo 的权限被拒绝

使用表中的列在 PostgreSQL 中创建视图

只读SAS视图(双击也是如此)

在 postgres 中创建一个范围

如何在实体框架中创建只读实体?