PostgreSQL更新视图脚本的注意事项

项目最早是基于Oracle的,移植到PostgreSQL后,本着尽量少修改的原则,创建/更新视图的脚本也沿用了Oracle风格的CREATE OR REPLACE VIEW形式。但是每当要更新视图定义时,常常报"cannot change name of view column xxx to yyy"的错误,通常是在视图修改某字段名、中间增加字段、删除字段时发生。

究其原因,是PostgreSQL虽然支持CREATE OR REPLACE VIEW语义,却有着容易让人忽略的重要限制(Oracle没有该限制),其官方文档这样描述:

即:更新视图只能在最后增加字段,不能改字段名、不能删除字段、也不能在中间增加字段,这在项目开发阶段是不可忍受的。虽然PostgreSQL提供了ALTER VIEW的语句,但怎么也不如直接放在CREATE VIEW里那样直观。

因此,建议脚本放弃Oracle风格的CREATE OR REPLACE VIEW形式,而改用MySQL风格的先DROP VIEW再CREATE VIEW的形式。不过,如果VIEW间存在层次引用关系,如视图A建立在视图B之上,则CREATE时必须先建B后建A,DROP时必须先删A再删B。当层次引用较多或变化较频繁时,调整顺序又是件麻烦事。

为降低复杂性,脚本最终只考虑CREATE VIEW时的顺序,而在DROP VIEW时,综合使用IF EXISTS 和CASCADE选项,如下所示:

DROP VIEW IF EXISTS B CASCADE;

CREATE VIEW B AS
...;

DROP VIEW IF EXISTS A CASCADE;

CREATE VIEW A AS
...;
时间: 2024-10-08 05:27:48

PostgreSQL更新视图脚本的注意事项的相关文章

postgresql 重建视图脚本

环境: psql (9.3.6) 输入 "help" 来获取帮助信息. root=# \d change_me          资料表 "public.change_me"    栏位    |         型别          | 修饰词  -----------+-----------------------+--------  too_short | character varying(50) |  root=# ALTER TABLE change_

可更新视图及其规则

1 前言 多表视图的定义:当视图的数据源只有一张数据表,则该视图为单表视图:当视图的数据源是多张数据表,则该视图为多表视图. 可更新视图的定义:在绝大多数人的概念中,视图是只读的,不允许修改.ORACLE 8i以上版本,单表视图如果没有设定With Read Only,则该视图是可以更新的,对视图的操作将直接写入的数据表中. 那么,如果视图的数据源是多张数据表,而多表视图如果实现可更新视图,则可以大大提高编码的效率. 2 多表可更新视图的应用范围 在程序实现过程中,我们往往会将诸如产品编号.计量

onAttachedToWindow () 和 onDetachedFromWindow () ; 以及更新视图的函数ondraw() 和dispatchdraw()的区别

protected void onAttachedToWindow() This is called when the view is attached to a window. At this point it has a Surface and will    start drawing. Note that this function is guaranteed to be called  before onDraw(android.graphics.Canvas), however it

Unity3D热更新全书-脚本(一) 初识脚本

开篇之前还是要先说明,这是一份给经验并不丰富的程序员阅读的文字. 有需求.有疑惑,往下看. 第一个问题什么是脚本?程序和脚本如何区分?我们给Unity编写的组件是程序还是脚本? 这些问题本文无意去解答,因为其中混合着太多有立场的东西,站在不同的立场会有不同的看法,这其中的矛盾不是简单可以调和的. 只要提出一个观点,就很容易陷入语言大战的泥潭. 我们不妨从另一个角度来思考,为什么要分程序和脚本,是为了找一条分界线. 这条分界线叫做灵活. 我们这个专题的出发点是探讨Unity3D客户端资源更新,已这

sas中的sql(7)创建视图,更新视图,删除视图

什么是视图? 视图是一系列的查询语句,在使用时被执行,用来从其他的数据集或视图中获取想要的子集(subset)或者超集(superset). The view contains only the logic for accessing the data, not the data itself 视图能用在哪些地方? 几乎在sas程序中任何真实表用的地方(不能用的地方暂未列出). 使用视图的好处? 1:节约空间,视图往往比真实表要小很多. 2:防止用户经常进行表查询而忽略默写列,视图写好后每次调用

Unity3D热更新全书-脚本(三) C#LightEvil语法与调试

调试,这是一个无法规避的问题 C#Light 由于有 词法解释.语法解释.运行时三种情况 所以和C#也是有类似的问题 出错大致可以分为编译错误和运行时错误 拼写出莫名的东西或者语法不正确,会在编译阶段报错,这种错误很好检查,因为 C#Light语法是C#的严格子集,所有的C#Light脚本都可以用C#的标准做语法检查 这也是C#Light基本上是用VisualStudio做编辑器的原因所在,直接作为C#代码编译,可以排除大部分的语法问题. 然后剩下的一些作为C#代码可以编译过,但是C#Light

Unity3D热更新全书-脚本(五) NGUI

让我们实际的研究一下如何将NGUI和C#LightEvil结合起来. 这里使用NGUI2.7,因为他是一个开源的版本,NGUI最新的版本未经作者的许可,是不可以带入我们的开源项目使用的. 这个例子完成的功能是从NGUI例子里找出了三个界面,按最下方的按钮依次进行切换 这是在之前的框架演示Mode1的基础上做的 由一个状态机去进行驱动,这也是我推荐各位使用脚本的方式. <=这是脚本,也是程序 Mode1的模式是定义一个接口类,然后由脚本继承此类型实现,因为随时考虑AOT的缘故(要兼容IOS),我们

使用SVN钩子运行PHP更新服务器代码的注意事项

想通过本地提交代码到SVN服务器,同时同步测试服务器的代码 使用SVN钩子,运行服务器的php文件 代码如下: <?php header("Content-Type: text/html; charset=utf-8"); header("Cache-Control:no-cache,must-revalidate"); $username = '用户名'; $password = '密码'; $target_dir = '路径'; exec("su

sql server 更新视图的sp

create procedure RefreshAllViewas begin declare @ViewName varchar(250) declare #views cursor for select name from sysobjects where objectproperty(id,N'IsView')=1 and uid=1 order by name open #views fetch next from #views into @viewname while @@fetch_