create table t23
(id number
, col_a varchar2(10)
, vcol_a as (upper(substr(col_a, 1, 1)))
)
/
请注意,我们无法插入或更新虚拟列。因此,您需要指定插入语句的投影:
insert into t23 (id, col_a) values (1, 'this is a test');
然后您可以在虚拟列上构建常规索引:
create index t23_vc_i on t23(vcol_a)
/
不要忘记删除基于函数的索引!
函数索引无法在表扫描中通用使用。
我在问题中做出的假设,即“内部,函数索引似乎会生成一个隐藏的表列...”,是错误的:函数的结果并没有存储在表列中,而只存储在索引中。
因此,除非有一种方法可以在执行扫描时访问索引(我能想到的唯一方法是如果它是以关键列开头的组合索引),否则预计算的函数结果无法使用。
11g的“虚拟列”功能也没有帮助,因为该列未存储在表中,而是动态计算的,类似于在视图中使用函数。
总之:如果无法排除表扫描,并且您的函数调用很耗费资源(慢),请使用真实列与“插入或更新之前”触发器相结合。函数索引行不通。
(注:添加此答案是因为我不想让这个问题保持未回答状态。答案归thilo所有,他指出该列从未被实现)。