http://luckysea.itpub.net/post/5481/457746
今天有时间研究一下oracle11g的新特性,发现虚拟列在实际开发中非常有用
在 Oracle 数据库 11g 中,您不需要编写任何触发器代码。您只需添加一个虚拟列。
虚拟列为您提供了灵活性,可以添加传达商业规则的列,而不增加任何复杂性或性能影响。
大大减轻了开发的工作量,但在建模方面需要增加工作量。
--创建一个测试表
其中包括员工编号(pno),姓名(pname),薪水(salary),级别(plevel)四列
其中级别(plevel)是虚拟列,是根据薪水的多少自动算出来的,分为三个等级 PG,SE,SSE
换算关系是这样的: salary <=2000 plevel = PG
salary >2000 and salary <=7000 plevel = SE
salary >7000 plevel = SSE
--测试过程
PENG11G(sys)>conn sys/sys@peng11g as sysdba
已连接。
PENG11G(sys)>select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
PL/SQL Release 11.1.0.6.0 - Production
CORE 11.1.0.6.0 Production
TNS for 32-bit Windows: Version 11.1.0.6.0 - Production
NLSRTL Version 11.1.0.6.0 - Production
/**********************************************************************************************/
create table vc_test(pno varchar2(6),
pname varchar2(10),
salary number(10,2),
plevel varchar2(3)
generated always as(
case
when salary <= 2000 then 'PG'
when salary > 2000 and salary <= 7000 then 'SE'
when salary > 7000 then 'SSE'
else null
end ) virtual
);
/**********************************************************************************************/
PENG11G(sys)>create table vc_test(pno varchar2(6),
2 pname varchar2(10),
3 salary number(10,2),
4 plevel varchar2(3)
5 generated always as(
6 case
7 when salary <= 2000 then 'PG'
8 when salary > 2000 and salary <= 7000 then 'SE'
9 when salary > 7000 then 'SSE'
10 else null
11 end ) virtual
12 );
表已创建。
PENG11G(sys)>desc vc_test;
名称 是否为空? 类型
----------------------------------------------------- -------- -----------------
PNO VARCHAR2(6)
PNAME VARCHAR2(10)
SALARY NUMBER(10,2)
PLEVEL VARCHAR2(3)
/**********************************************************************************************/
insert into vc_test (pno, pname, salary) values ('000001','张三',1500);
insert into vc_test (pno, pname, salary) values ('000002','李四',2500);
insert into vc_test (pno, pname, salary) values ('000003','王五',4500);
insert into vc_test (pno, pname, salary) values ('000004','周二',1500);
insert into vc_test (pno, pname, salary) values ('000005','刘六',8500);
insert into vc_test (pno, pname, salary) values ('000006','待定',null);
/**********************************************************************************************/
PENG11G(sys)>insert into vc_test (pno, pname, salary) values ('000001','张三',1500);
已创建 1 行。
PENG11G(sys)>insert into vc_test (pno, pname, salary) values ('000002','李四',2500);
已创建 1 行。
PENG11G(sys)>insert into vc_test (pno, pname, salary) values ('000003','王五',4500);
已创建 1 行。
PENG11G(sys)>insert into vc_test (pno, pname, salary) values ('000004','周二',1500);
已创建 1 行。
PENG11G(sys)> insert into vc_test (pno, pname, salary) values ('000005','刘六',8500);
已创建 1 行。
PENG11G(sys)>insert into vc_test (pno, pname, salary) values ('000006','待定',null);
已创建 1 行。
PENG11G(sys)>commit;
提交完成。
PENG11G(sys)>select * from vc_test;
PNO PNAME SALARY PLE
------ ---------- ---------- ---
000001 张三 1500 PG
000002 李四 2500 SE
000003 王五 4500 SE
000004 周二 1500 PG
000005 刘六 8500 SSE
000006 待定
已选择6行。
--不能为虚拟列赋值
PENG11G(sys)> insert into vc_test (pno, pname, salary,plevel) values ('000007','测试',8500,'SSE');
insert into vc_test (pno, pname, salary,plevel) values ('000007','测试',8500,'SSE')
*
第 1 行出现错误:
ORA-54013: 不允许对虚拟列执行 INSERT 操作
--可以为虚拟列建立索引,索引类型为函数索引
PENG11G(sys)>create index ind_plevel on vc_test(plevel);
索引已创建。
PENG11G(sys)> select index_type from user_indexes where index_name = 'IND_PLEVEL';
INDEX_TYPE
---------------------------
FUNCTION-BASED NORMAL