postgresql修改表结构报错

文章讲述了在SQL中遇到cannotaltertypeofcolumnusedbyvieworrule错误的原因,即视图或规则对表结构的依赖。提供了两种解决方案:一是删除依赖视图后修改,二是递归查找并删除/重建所有依赖。作者强调了理解依赖的重要性,并分享了查询和恢复依赖关系的SQL函数实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

error: cannot alter type of column used by a view or rule

分析原因是由于在该表之上有建了视图或规则。

场景模拟:

新建一张表

create table ptemp.online_job_info

(etl_system char(3) check (etl_system ~ '^[A-Z0-9_]*$')

,etl_job varchar(50) check (etl_job ~ '^[A-Z0-9_]*$')

,txdate date

,operator_type char(2) check (operator_type in ('重跑','下线','新增','变更'))

,request_person_name varchar(100) check (request_person_name not in ('')) not null

,remark varchar(200)

,last_modify_date date

,insert_time timestamp with time zone

,unique(etl_system,etl_job,txdate,last_modify_date)

)

distributed by (etl_system,etl_job);

在表基础上建视图

create view ptemp.v_online_job_info as
select * from ptemp.online_job_info;

更新字段,复现报错

alter table ptemp.v_online_job_info alter column remark type varchar(300);

error: cannot alter type of column used by a view or rule

解决方案一:

1.先将依赖ptemp.online_job_info的视图删除掉

drop view ptemp.online_job_info;

2.修改ptemp.online_job_info表结构

alter table ptemp.v_online_job_info alter column remark type varchar(300);

修改成功。

3.把视图建回来

create view ptemp.v_online_job_info as

select * from ptemp.online_job_info;

完成,表结构修改完毕。

作为一个拥有灵魂的SQL boy ,怎么可能就这样解决问题。动作一点都不酷!!!

分析原因:方案一解决这种问题的前提是,被修改表的所有依赖于被修改表的视图或其它都十分清楚,能够被你全部列举出来;只要有一条漏掉,你就修改不成功。除非使用绝招:把表级联删除掉,然后重新建表建视图建规则;当然这种操作危险性可想而知,反正我是不会在生产上这么操作的。

解决方案二:

思路:

1.先从数据库系统中把目标表的所有上游视图规则什么的全部找出来(而且不止一层,要递归查出所有),并找一张表保存起来;

2.按照递归出来的层级关系,从最后一层开始一个一个删除掉;

3.修改目标表结构;

4.按照第一步保存的层级关系,把所有依赖按照层级关系,从第一层一个一个把视图规则等建回来。

实践操作:

1.建表。该表的作用是为了把等下查依赖关系的视图相关信息及建视图删视图预计保存下来。

create table ptemp.drop_create_view_sql_tmp(

parent_oid oid

,parent_table varchar(200)

,childer_oid oid

,childer_table varchar(200)

,drop_view_sql text

,create_view_sql text

,"level"" interger

) distributed by (parend_oid);

2.创建第一个函数。从系统中获取表上游所有相关信息

create or replace function ptemp.alter_table1(schema_name varchar(20),table_name varchar(100)) returns void

as

$$

declare

  v_table_name varchar(150);

  drop_view_cursor  cursor for select drop_view_sql from ptemp.drop_create_view_sql_tmp order by "level" desc;

  v_drop_view text;

begin

 v_table_name := schema_name || '.' || table_name;

 delete from ptemp.drop_create_view_sql_tmp;

 insert into ptemp.drop_create_view_sql_tmp 

 wirh recursive rectbl (parent_oid,childer_oid,level) as (

select dep.parent_oid,rwr.ev_class childer_oid,1 from (select refobjid parent_oid,objid from pg_depend dep1

where dep1.refobjid = v_table_name::regclass

and dep1.deptype = 'n'

and dep1.classid = 'pg_rewrite'::regclass

group by refobjid,objid ) dep

 inner join pg_rewrite rwr

on dep.objid = rwr.oid

where dep.parent_oid <> rwr.ev_class

union all

 select b.refobjid,c.ev_class,level+1

 from rectbl a

 inner join pg_depend b

 on a.childer_oid = b.b.refobjid

inner join pg_rewrite c

 on b.objid = c.oid

 where a.childer_oid <> c.ev_class

)

select parent_oid

           ,parent_oid::regclass parent_table

           ,childer_oid

           ,childer_oid::regclass childer_table

           ,'DROP VIEW ' || childer_oid::regclass || ';'  drop_view_sql

          ,'CREATE VIEW ' || childer_oid::regclass || ' AS' || chr(13) || pg_get_viewdef(childer_oid,true) as view_def

         ,level

from rectbl group by parent_oid,childer_oid,level;

 

----drop_view_cursor

open drop_view_cursor;

loop

FETCH drop_view_cursor INTO v_drop_view;

EXIT WHEN NOT FOUND;

execute v_drop_view;

end loop;

close drop_view_cursor;

end

$$

LANGUAGE plpgsql;

3.创建第二个函数。用于修改表结构化恢复依赖关系

create or replace function ptemp.alter_table2()

returns void

as

$$

declare

 create_view_cursor cursor for select create_view_sql from ptemp.drop_create_view_sql_tmp order by "level" ;

 v_create_view text;

begin

----create_view_cursor

 open create_view_cursor;

loop

FETCH create_view_cursor INTO v_create_view;

EXIT WHEN NOT FOUND;

execute v_create_view;

end loop;

close create_view_cursor;

end

$$

LANGUAGE plpgsql;

测试:

 1.备份依赖关系

select * from ptemp.alter_table1('ptemp','online_job_info');

2.真正修改表结构

alter table ptemp.v_online_job_info alter column remark type varchar(300);

3.还原表视图依赖

select * from ptemp.alter_table2();

当然也可以查看上次修改表的相关依赖信息:

select * from ptemp.drop_create_view_sql_tmp;

到这就结束了。

如果特别自信修改表结构的语句没有问题,是可以把第一个函数和第二个函数合并成一个函数,增加一个传递修改语句的参数进去就可,这样就能过一句执行就行,而不是分三步。

本人自己是建了一步修改表结构函数的,但是平时用的最多的还是方案二的三步曲。

 

### PostgreSQL 安装错误解决方案 当遇到 `postgres:无法访问服务器配置文件 "C:/Program Files/PostgreSQL/10/data/postgresql.conf": No such file or directory` 的错误时,这通常意味着 PostgreSQL 数据目录未被正确初始化或路径设置不正确。 #### 1. 验证安装路径 确保 PostgreSQL 已经成功安装到指定的路径。如果选择了自定义安装路径,则需要确认该路径下的 `data` 文件夹是否存在并具有正确的权限[^1]。 #### 2. 初始化数据库集群 如果数据目录不存在,可能是因为在安装过程中跳过了初始化步骤。可以通过命令行工具手动创建一个新的数据库集群: ```bash "C:\Program Files\PostgreSQL\10\bin\initdb.exe" -D "C:\Program Files\PostgreSQL\10\data" ``` 此操作会生成必要的配置文件和结构化存储区域来保存用户表空间和其他持久状态信息。 #### 3. 修改环境变量和服务注册 有时服务未能正常启动也可能导致上述问题。检查 Windows 系统的服务列表 (`services.msc`) 中是否有名为 `postgresql-x64-10` 或类似的条目,并尝试重新启动该项服务。另外,还需验证 PATH 变量是否包含了 PostgreSQL 的二进制文件所在位置以便能够全局调用 psql 和其他实用程序。 #### 4. 使用 pg_ctl 控制工具 对于更复杂的场景下可以借助 `pg_ctl` 进行诊断与修复工作: ```bash "C:\Program Files\PostgreSQL\10\bin\pg_ctl.exe" status -D "C:\Program Files\PostgreSQL\10\data" ``` 这条指令用来查看当前实例的状态;如果是停止状态则继续执行下面的操作来进行重启: ```bash "C:\Program Files\PostgreSQL\10\bin\pg_ctl.exe" start -D "C:\Program Files\PostgreSQL\10\data" ``` 通过这种方式可以直接控制 PostgreSQL 实例而不依赖于操作系统层面的服务管理器。 #### 5. 日志审查 最后不要忘记查阅位于 `%PROGRAMDATA%\PostgreSQL\logs` 下的日志记录以获取更多关于失败原因的信息。这些日志可以帮助进一步定位具体是什么地方出了错以及如何针对性地解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值