2016-03-18 48 views
1

是否有可能拥有一个虚拟列,其列表达式定义引用另一个虚拟列,该虚拟列之前已在表中定义过? The documentation for column expressions说:指向另一个虚拟列的虚拟列定义

the defining column_expression must refer only to columns of the subject table that have already been defined, in the current statement or in a prior statement

这是我想要做的,与第三虚拟列指的是其他虚拟列一个简单的例子已经定义:

create table numberManipulation 
(
    value1 VARCHAR2 (10), 
    Value2 VARCHAR2 (10), 
    Addition AS (DECODE (value1, 'late', 1, 0) + DECODE (value2, 'late', 1, 0)), 
    subtraction AS(DECODE (value1, 'present', 1, 0) + DECODE (value2, 'present', 1, 0)), 
    Compile AS (ADDITION + SUBTRACTION) 
); 

但这会得到错误:

ORA-54012: virtual column is referenced in a column expression 

是我想要做的可能吗?

回答

3

不,虽然the documentation for column expressions没有明确说你不能。这一限制在My Oracle Support的文档466916.1表示,虽然,在create table documentation

The column_expression in the AS clause has the following restrictions:

  • It cannot refer to another virtual column by name.
    ...

你将不得不从先前的每个虚拟列的重复计算在第三个:

create table numberManipulation 
(
    value1 VARCHAR2 (10), 
    Value2 VARCHAR2 (10), 
    Addition AS (DECODE (value1, 'late', 1, 0) + DECODE (value2, 'late', 1, 0)), 
    subtraction AS(DECODE (value1, 'present', 1, 0) + DECODE (value2, 'present', 1, 0)), 
    Compile AS (DECODE (value1, 'late', 1, 0) + DECODE (value2, 'late', 1, 0) 
    + DECODE (value1, 'present', 1, 0) + DECODE (value2, 'present', 1, 0)) 
); 

Table NUMBERMANIPULATION created. 

或者稍微更简单:

Compile AS (DECODE (value1, 'late', 1, 'present', 1, 0) 
    + DECODE (value2, 'late', 1, 'present', 1, 0)) 

...尽管你可能宁愿保持两个较长表达式匹配的一致性和米早期专栏aintenance。

有一个虚拟列引用另一个虚拟列将决定他们必须被评估的顺序,并可能导致循环依赖关系。

另一种方法是有计算基表从两个虚拟列最后列的视图:

create table numberManipulation 
(
    value1 VARCHAR2 (10), 
    Value2 VARCHAR2 (10), 
    Addition AS (DECODE (value1, 'late', 1, 0) + DECODE (value2, 'late', 1, 0)), 
    subtraction AS(DECODE (value1, 'present', 1, 0) + DECODE (value2, 'present', 1, 0)) 
); 

Table NUMBERMANIPULATION created. 

create view vNumberManipulation as 
select numberManipulation.*, addition + subtraction as compile 
from numberManipulation; 

View VNUMBERMANIPULATION created. 

insert into numberManipulation (value1, value2) values ('late', 'late'); 
insert into numberManipulation (value1, value2) values ('late', 'present'); 
insert into numberManipulation (value1, value2) values ('present', null); 
select * from vNumberManipulation; 

VALUE1  VALUE2  ADDITION SUBTRACTION  COMPILE 
---------- ---------- ----------- ------------ ------------ 
late  late     2   0   2 
late  present    1   1   2 
present       0   1   1 

的视图也不能引用自己的列,所以你还需要增加和在基表中减法。您也可以在视图上使用instead-of trigger,以便尝试修改视图实际上会更改基表,这会使其更友好。

+0

谢谢,但问题是,我给这里就像样本,通常有value1 ..... value28,有没有其他方法可以做到这一点,因为它会更复杂,键入太多 – Programmer

+0

你可以有一个该视图基于基表的虚拟列计算列值;如果需要的话可以使用替代触发器。或者你可以通过触发器设置一个物理列,但这也不是理想的。 –

+0

o ..是否有任何参考或关键点可以基于它进行搜索。 – Programmer