一、问题:
昨天想要修改Oracle数据库中某张表的某个字段,发现怎么都修改不成功!!!并给出了如下提示:
ORA-54031:要删除或修改的列由某个虚拟列表达式使用
二、啥是“虚拟列” 【不可见的列】
虚拟列的创建一般是数据库自动创建的,当然也可以手动创建。
什么时候创建:表中的数据,大量或频繁的发生变化的时候,数据库一般会自动创建虚拟列!
我觉得截一个漂亮的图,比我的一个字一个字的敲的更容易理解!哈哈哈!
Oralce 的虚拟列解决了以前很多需要使用触发器或者需要通过代码进行计算统计才能产生的数据信息。以前每次对其他的列进行统计,产生新列的时候都是采用在select 语句中通过统计计算增加新列的方法,执行效率很低,而且由于使查询SQL语句变得冗长、复杂很容易出错。严重的降低了开发效率和程序的执行效率。Oralce虚拟列的引入解决了这个问题。
Oralce 的虚拟列也有一些问题。不能使用insert into talbe_name values ().语句,在向含有虚拟列的表中添加数据时,要求insert语句的必须把添加的表的列名写出来。insert into table_name (list1,list2,...listend)列名中不能出现虚拟列名,否则会提示错误。
下面罗列一下解决方案:
二、几种解决方案
(1)先备份数据,备份表结构,再delete该表,再创建表(修改列信息),再导入数据!
数据量少的时候,无所谓,可以这么做,但是如果数据量过多,那么弊端就很明显了!
(2)drop当前虚拟列。流程如下:
--:查询指定表的虚拟列信息:
--select column_name,data_default,hidden_column
--from user_tab_cols
--where table_name='CB_BATCH_FLOW' AND column_name='BFL_OPRNO' --说明:修改步骤:
--(1)先查询user_tab_cols表.列的虚拟列data_default字段的信息,取其中的HASH值
--(2)如果(1)查到了HASH值,才需要执行exec 删除该列的虚拟列操作,如果没有查找HASH值,则不需要删除虚拟列
--(3)删除虚拟列之后,此时可以alter
--格式:
-- exec dbms_stats.drop_extended_stats('ebank','CB_BATCH_FLOW','BFL_CSTNO,CCP_USERID)'); ---删除虚拟列
-- alter table CB_BATCH_FLOW modify BFL_CSTNO varchar2(10); ---修改列信息
-- select dbms_stats.create_extended_stats('ebank','CB_BATCH_FLOW','(CCP_CSTNO,CCP_USERID)') FROM DUAL; ---新增虚拟列
执行截图:
1、exec 执行方法参数传入错误
2、成功删除虚拟列
3、成功创建一个虚拟列
但是,成功创建的虚拟列的在:user_tab_cols表中的COLUMN_NAME字段存入的值是随机的,