ORA-54033 要修改的列由某个虚拟表达式使用

A colleague recently asked me a question:

"I'm modifying the data type of a column. When doing so I get the following error:

ORA-54033: column to be modified is used in a virtual column expression

But there's no virtual columns defined on the table! What on earth's going on?!"

This was exceptionally confusing. Looking at the table definition we couldn't see any virtual columns defined: 

create table tab (
  x integer, 
  y date, 
  z varchar2(30)
);

Sure enough, when we tried to change the data type of y we got the exception:

alter table tab modify (y timestamp);

ORA-54033: column to be modified is used in a virtual column expression

How could this be? 

Perhaps there was a column defined that we couldn't see. Querying user_tab_cols revealed something interesting:

select column_name, data_default, hidden_column 
from   user_tab_cols
where  table_name = 'TAB';

COLUMN_NAME 			DATA_DEFAULT 			HID
------------------------------ 	-----------------------------   ---
SYS_STUYPW88OE302TFVBNC6$MMQXE	SYS_OP_COMBINED_HASH("X","Y")	YES
Z		                                                NO
Y								NO
X								NO

The SYS_... column isn't in the table DDL! Where does it come from? And what's SYS_OP_COMBINED_HASH all about? Has someone been mucking around with the database?

The SYS_ prefix is a sign that the column is system generated. So something's happened that's caused Oracle to create this on our behalf.

SYS_OP_COMBINED_HASH is an undocumented feature. The name implies Oracle is merging the arguments together to form a hash.

Is there a feature where we want to capture information about a group of columns?

Indeed there is -extended statistics!This feature enables to Oracle calculate statistics on a group of columns. It uses this information to improve row estimates. This is useful when there's a correlation between the values of two (or more) columns in a table.

Someone had created extended stats on this table for (x, y).

Now we've identified the problem, how do we get around it?

Simple: drop and recreate the extended stats:

exec dbms_stats.drop_extended_stats(user, 'tab', '(x, y)');

alter table tab modify (y timestamp);

select dbms_stats.create_extended_stats(user, 'tab', '(x, y)')
from   dual;

DBMS_STATS.CREATE_EXTENDED_STATS(USER,'TAB','(X,Y)')                           
--------------------------------------------------------------------------------
SYS_STUYPW88OE302TFVBNC6$MMQXE  

Success!

Extended stats are a great way to improve the optimizer's row estimates. If you need to create these, I recommend you also do the following:

  • Apply the extended stats to all environments
  • Put a comment on the columns explaining what you've done, e.g. 
    • comment on column tab.x is 'part of extended stats. To modify data type drop and recreate stats';
These actions will help prevent future developers getting stuck tracking down the cause of "missing" virtual columns!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ORA-01439是Oracle数据库中的一个错误代码,当我们试图修改表的字段数据类型时,系统可能会提示此错误。 要更改的数据类型,我们可以使用ALTER TABLE语句的MODIFY子句。在这个操作中,我们需要指定要修改的名称和新的数据类型。 例如,如果我们要将一个的数据类型从VARCHAR2修改为NUMBER,可以使用以下语法: ALTER TABLE 表名 MODIFY 名 新的数据类型; 其中,表名是要修改的表的名称,名是要修改的名称,新的数据类型是我们希望将修改为的数据类型。 需要注意的是,修改的数据类型可能会导致数据的丢失或变形。因此,在执行此操作之前,务必备份数据表,并确保已妥善处理了可能的数据转换问题。 此外,还需要考虑以下几点: 1. 如果表中已经存在数据,该数据必须与新的数据类型兼容。否则,修改可能会失败或导致数据损坏。 2. 如果修改在任何索引中被使用,那么需要先删除或修改相关的索引,以便在修改的数据类型后重新创建索引。 3. 如果被其他表或程序引用,那么在修改之前,需要相应地修改相关的外键和依赖项。 总结起来,ORA-01439的错误意味着我们在修改表的字段数据类型时遇到了问题。通过使用ALTER TABLE语句的MODIFY子句,我们可以更改的数据类型。然而,在执行此操作之前,我们需要注意潜在的数据转换问题,并确保兼容性、索引和外键的正确处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值