是否可以拥有一个虚拟列,其列表达式定义引用另一个先前在表上定义的虚拟列? The documentation for column expressions说:
定义 column_expression 必须仅引用主题表中已定义的列,在当前语句或先前的语句中
这是我尝试做的一个简单示例,第三个虚拟列引用了已经定义的其他虚拟列:
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
我正在尝试做什么?
答案 0 :(得分:3)
不,虽然the documentation for column expressions没有明确表示你做不到。此限制显示在My Oracle Support文档466916.1中,并显示在create table
documentation:
AS子句中的column_expression具有以下限制:
- 它不能通过名称引用另一个虚拟列 ...
您必须从第三个虚拟列中的每个虚拟列重复计算:
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))
...虽然您可能希望保留两个较长的表达式与早期的列匹配,以保持一致性和维护。
让一个虚拟列引用另一个虚拟列将决定它们必须被评估的顺序,并且可能导致循环依赖。
另一种方法是使用一个视图来计算基表中两个虚拟列的最终列:
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,以便尝试修改视图实际上会更改基表,这会使其更加用户友好。