继this earlier question之后我在PostgreSQL 8.4上,我遇到了可更新视图的问题。
我有一个观点:
CREATE VIEW filedata_view
AS SELECT num, id, ST_TRANSFORM(the_geom,900913) AS the_geom
FROM filedata
并希望从我的应用程序抛出Geoserver更新它。但是得到一个错误:
<ServiceExceptionReport version="1.2.0" xmlns="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/ogc http://schemas.opengis.net/wfs/1.0.0/OGC-exception.xsd">
<ServiceException> {http://www.opengeospatial.net/cite}filedata_view is read-only </ServiceException>
</ServiceExceptionReport>
因此PostgresSql中的视图不可更新。我需要创建一个规则或触发器来更新视图。
我试过了:
CREATE OR REPLACE RULE ins_view_2 AS
ON UPDATE TO filedata_view DO INSTEAD UPDATE filedata SET the_geom=ST_TRANSFORM(NEW.the_geom,70066)
WHERE num=NEW.num
但它没有帮助,我仍然得到同样的错误。
我的错误在哪里?
答案 0 :(得分:2)
不要为此使用规则,而是使用trigger。您至少需要9.1版,旧版本不支持视图触发器。
触发器是数据库应该自动生成的规范 每当某种类型的操作时执行特定的功能 执行。触发器可以附加到表和视图。
在表格上,触发器可以定义为在之前或之后执行 任何INSERT,UPDATE或DELETE操作,每个修改行一次, 或每个SQL语句一次。此外,UPDATE触发器可以设置为触发 仅当UPDATE的SET子句中提到某些列时 声明。触发器也可以触发TRUNCATE语句。如果一个 触发事件发生时,触发器的函数被调用 适当的时间处理事件。
有传言说规则将在一段时间内成为EOL。
答案 1 :(得分:2)
首先,我对弗兰克表示赞同。使用9.1和表触发器。但是,无论是视图还是视图都无法解决您的问题。
尝试在psql的视图上执行手册UPDATE
。如果这样做,并且如果你使用与opengeospatial相同的用户ID连接,那么我会说这个问题可能是opengeospatial太聪明了,因为它自己的好处并“知道”视图无法更新。要么就是这样,要么正在尝试INSERT
,而您还没有在视图中添加匹配的INSERT
规则。
消息“filedata_view是只读的”不是PostgreSQL可能产生的消息。我想知道opengeospatial是否正在使用JDBC元数据(假设它是Java)或INFORMATION_SCHEMA或类似的查询模式,确定filedata_view
是一个视图,并且得出结论它因此无法更新它。
如果是来自PostgreSQL的消息,则会改为:
# UPDATE customer_v SET customer_number = 1234;
ERROR: cannot update view "the_view"
HINT: You need an unconditional ON UPDATE DO INSTEAD rule or an INSTEAD OF UPDATE trigger.
在log_statement = 'all'
中启用postgresql.conf
并重新加载postgresql可能会提供信息。重新测试,然后查看日志,看看opengeospatial正在做什么。
如果事实证明它正在检测视图,那么您可以通过将ON SELECT
规则添加到空表来解决此问题。该表将像视图一样工作,但GeoServer将无法告诉它是一个视图,并且可能同意写入它。
答案 2 :(得分:0)
如果您有Postgres&gt; = 9.3,您可以使用GeoServer更新来自View的功能,至少如果视图是另一个表的子集(我认为这不适用于连接或复合字段..)
以下是:http://osgeo-org.1560.x6.nabble.com/postgresql-postgis-views-and-primary-keys-td3796362.html
这真的对我有用!