修改表结构提示有试图依赖的处理方法

Posted 瀚高PG实验室

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了修改表结构提示有试图依赖的处理方法相关的知识,希望对你有一定的参考价值。

目录
环境
症状
问题原因
解决方案

环境
系统平台:N/A
版本:4.3.2,4.7.5,4.7.6,4.7.7,4.7.8,6.0
症状
修改表结构时,提示该表有其它视图依赖,例如:

错误: 0A000: 不能使用视图或规则改变一个字段的类型

DETAIL: 规则 _RETURN 在 视图 hgtest_vw1,hgtest_vw2 倚赖于字段 “name”

问题原因
瀚高数据库中,直接修改视图依赖的表时会有规则冲突,需要删除依赖视图,修改完毕后再重建视图。

解决方案
1、创建测试表和视图

highgo=# create table hgtest (id int,name varchar(10),des text);

CREATE TABLE

highgo=# create view hgtest_vw1 as select name from hgtest where id >2;

CREATE VIEW

highgo=# create view hgtest_vw2 as select name from hgtest where id <3;

CREATE VIEW

2、 插入模拟数据

highgo=# insert into hgtest values (1,'highgo01','The first line'),(2,'highgo02','The second line'),(3,'highgo03','The third  line'),(4,'highgo04','The fourth line');

INSERT 0 4

highgo=# select * from hgtest ;

 id |   name   |       des       

----+----------+-----------------

  1 | highgo01 | The first line

  2 | highgo02 | The second line

  3 | highgo03 | The third  line

  4 | highgo04 | The fourth line

(4 rows)



highgo=# select * from hgtest_vw1 ;

   name   

----------

 highgo03

 highgo04

(2 rows)

3、修改表结构(模拟问题)

highgo=# alter table hgtest alter COLUMN name type varchar(50);

错误:  0A000: 不能使用视图或规则改变一个字段的类型

DETAIL:  规则 _RETURN 在 视图 hgtest_vw1,hgtest_vw2 倚赖于字段 "name"

4、 找出该表上的所有视图
方法一:

highgo=# select viewname,definition from pg_views where viewname ~ '^hgtest';

  viewname  |        definition        

------------+--------------------------

 hgtest_vw1 |  SELECT hgtest.name     +

            |    FROM hgtest          +

            |   WHERE (hgtest.id > 2);

 hgtest_vw2 |  SELECT hgtest.name     +

            |    FROM hgtest          +

            |   WHERE (hgtest.id < 3);

(2 rows)

方法二:

CREATE OR REPLACE FUNCTION  funvread(db varchar(30),sm varchar(30),textlist text,flag BOOLEAN DEFAULT true)

 RETURNS void

 LANGUAGE plpgsql

AS $function$ 

	declare cur refcursor;

	i int DEFAULT 1;

	v_sql varchar;

	v_sql1 varchar;

	v_name text;

 begin 

	--递归判断 第一次调用

	IF flag THEN

		--表不存在则创建

		CREATE TABLE IF NOT EXISTS  drop_view_sql(id serial,vname text,def text);

		--清空表

		DELETE FROM drop_view_sql;

	END IF;	

	--递归增view字段

	create temp TABLE IF NOT EXISTS tempTable(id serial,vname text);

	while i<=array_length(regexp_split_to_array(textlist,','),1)

	LOOP

		DELETE FROM tempTable;

		--根据表名,或者view 查出对应view名,view 建立语句

		v_sql='INSERT INTO drop_view_sql(vname,def) SELECT 	view_name,view_definition FROM 	information_schema.view_table_usage a inner JOIN information_schema.views b ON 	b.table_name=view_name WHERE b.table_catalog='''||db||''' AND b.table_schema= '''||sm||''' AND a.table_name= '''||(regexp_split_to_array(textlist,',')::text[])[i]||'''';

	 	execute(v_sql);

		--增虚拟表,循环调用

		v_sql1='INSERT INTO tempTable(vname) SELECT view_name FROM 	information_schema.view_table_usage a inner JOIN information_schema.views b ON 	b.table_name=view_name WHERE b.table_catalog='''||db||''' AND b.table_schema= '''||sm||''' AND a.table_name= '''||(regexp_split_to_array(textlist,',')::text[])[i]||'''';

	 	execute(v_sql1);

		SELECT string_agg(vname,',') INTO v_name FROM  tempTable;

		IF v_name!='' THEN

			PERFORM funvread(db,sm,v_name,FALSE);	

		END IF;	

		i=i+1;

	END LOOP;

	--raise notice '***%***', '已保存view到表drop_view_sql';

 end; 

 $function$

5、 删除视图
方法一:

drop view hgtest_vw1;

drop view hgtest_vw2;

方法二:

CREATE OR REPLACE FUNCTION  funvread(db varchar(30),sm varchar(30),textlist text,flag BOOLEAN DEFAULT true)

 RETURNS void

 LANGUAGE plpgsql

AS $function$ 

	declare cur refcursor;

	i int DEFAULT 1;

	v_sql varchar;

	v_sql1 varchar;

	v_name text;

 begin 

	--递归判断 第一次调用

	IF flag THEN

		--表不存在则创建

		CREATE TABLE IF NOT EXISTS  drop_view_sql(id serial,vname text,def text);

		--清空表

		DELETE FROM drop_view_sql;

	END IF;	

	--递归增view字段

	create temp TABLE IF NOT EXISTS tempTable(id serial,vname text);

	while i<=array_length(regexp_split_to_array(textlist,','),1)

	LOOP

		DELETE FROM tempTable;

		--根据表名,或者view 查出对应view名,view 建立语句

		v_sql='INSERT INTO drop_view_sql(vname,def) SELECT 	view_name,view_definition FROM 	information_schema.view_table_usage a inner JOIN information_schema.views b ON 	b.table_name=view_name WHERE b.table_catalog='''||db||''' AND b.table_schema= '''||sm||''' AND a.table_name= '''||(regexp_split_to_array(textlist,',')::text[])[i]||'''';

	 	execute(v_sql);

		--增虚拟表,循环调用

		v_sql1='INSERT INTO tempTable(vname) SELECT view_name FROM 	information_schema.view_table_usage a inner JOIN information_schema.views b ON 	b.table_name=view_name WHERE b.table_catalog='''||db||''' AND b.table_schema= '''||sm||''' AND a.table_name= '''||(regexp_split_to_array(textlist,',')::text[])[i]||'''';

	 	execute(v_sql1);

		SELECT string_agg(vname,',') INTO v_name FROM  tempTable;

		IF v_name!='' THEN

			PERFORM funvread(db,sm,v_name,FALSE);	

		END IF;	

		i=i+1;

	END LOOP;

	--raise notice '***%***', '已保存view到表drop_view_sql';

 end; 

 $function$

5、 删除视图
方法一:

drop view hgtest_vw1;

drop view hgtest_vw2;

方法二:

CREATE OR REPLACE FUNCTION  fun_vdrop()

 RETURNS void

 LANGUAGE plpgsql

AS $function$ 

	declare cur refcursor;	

	v_name text;

 begin 

	 open cur for SELECT vname FROM drop_view_sql ORDER BY id desc;			   

	--循环删除VIEW  

	fetch  cur into v_name;

	while (Found) 

		loop			

			execute('drop view '||v_name);				 

			fetch  cur into v_name;    

		end loop;     

	close cur;   

 end; 

 $function$

SELECT fun_vdrop(); --删除视图
6、 修改表结构


alter table hgtest alter COLUMN name type varchar(50);

7、 重建视图
方法一:

highgo=# create view hgtest_vw1 as select name from hgtest where id >2;

CREATE VIEW

highgo=# create view hgtest_vw2 as select name from hgtest where id <3;

CREATE VIEW

方法二:

创建视图函数

CREATE OR REPLACE FUNCTION fun_vrecreate() 

RETURNS void 

LANGUAGE plpgsql 

AS $FUNCTION$

DECLARE cur refcursor;

v_name TEXT;

v_def TEXT;

BEGIN

		OPEN cur FOR SELECT

		vname,

		def 

	FROM

		drop_view_sql 

	ORDER BY

		ID;

--循环删除VIEW

	FETCH cur INTO v_name,

	v_def;

	while

	( FOUND )

	loop

	EXECUTE ( 'create OR REPLACE view ' || v_name || ' as ' || v_def );

	FETCH cur INTO v_name,

	v_def;

	

END loop;

CLOSE cur;

END; 

$FUNCTION$

select fun_vrecreate(); --重建视图

至此,完成表结构修改。

以上是关于修改表结构提示有试图依赖的处理方法的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server阻止保存修改表结构的解决方法

Android 片段和依赖注入

Oracle 数据库 - 使用UEStudio修改dmp文件版本号,解决imp命令恢复的数据库与dmp本地文件版本号不匹配导致的导入失败问题,“ORACLE error 12547”问题处理(代码片段

Sqlserver修改表结构提示不允许保存更改。

sqlserver通过设计器修改表结构保存时提示:保存到文本问题

c#node struct自定义LinkedListNode结构中的循环依赖