54SA.COM|专注于系统亚博体育官方网址管理,为中国SA提供动力!
当前位置: 主页 > 信息化 > 数据库 >

Oracle 11g 新特性 —虚拟列、只读表

时间:2012-07-26 10:05来源:OSCHINA 编辑:admin

?Oracle 11g 数据库的新特性 —— 虚拟列

介绍

在老的 Oracle 版本,当我们需要使用表达式或者一些计算公式时,我们会创建数据库视图,如果我们需要在这个视图上使用索引,我们会创建基于函数的索引。

现在 Oracle 11g 允许我们直接在表上使用虚拟列来存储表达式。

来看一个简单的例子:

1 CREATE?TABLE?EMP
2 (
3 ??EMPNO???? NUMBER(6),
4 ??SAL?????? NUMBER(8,2),
5 ??COMM????? NUMBER(8,2),
6 ??SAL_PACK? GENERATED ALWAYS?AS?( SAL + NVL(COMM,0) ) VIRTUAL
7 );

上述建的虚拟列 SAL_PACK 是由一个简单的表达式创建的,使用的关键字有 VIRTUAL(不过这个关键字是可选的),该字段的值是由 COMM 这个字段通过表达式计算而来的。

虚拟列的值是不存储在磁盘的,它们是在查询时根据定义的表达式临时计算的。

我们不能往虚拟列中插入数据:

1 SQL>?INSERT?INTO?emp?VALUES?(10, 1500, 500,2000);
2 ?
3 ERROR?at?line 1:
4 ORA-54013:?INSERT?operation disallowed?on?virtual columns

我们也不能隐式的添加数据到虚拟列:?

1 SQL>?INSERT?INTO?t?VALUES?(10, 1500, 500);
2 ????????????*
3 ERROR?at?line 1:
4 ORA-00947:?not?enough?values

我们只能使用物理列来插入数据。

1 SQL>?INSERT?INTO?t (empno, sal,comm)?VALUES?(10, 1500 , 500);
2 1 row created.

然后可以查询虚拟列的值:

1 SQL>?select?*?from?emp;
2 EMPNO??? SAL??????? COMM?????? SAl_PACK
3 -----?? ------????? -----????? --------
4 10????? 1500??????? 500??????? 2000
5 ?
6 1 row selected.

表达式是在查询的时候即时计算的,然后输出上述的结果。

虚拟列的索引和约束

索引和约束同样可以应用在虚拟列上。我们可使用如下SQL语句来创建索引:?

1 SQL>?create?index?sal_pack_idx?on?emp(sal_pack);
2 ???????????Index?Created.

我们也可以为虚拟列创建外键。

使用 PLSQL 函数来处理虚拟列

虚拟列的定义可使用 PLSQL 函数,但要求该函数必须是确定的:

1 CREATE?OR?REPLACE?FUNCTION?sum_num (in_num1 NUMBER, in_num2 NUMBER)
2 ???RETURN?NUMBER DETERMINISTIC
3 AS
4 BEGIN
5 ???RETURN?in_num1 + in_num2;
6 END;

然后可以在虚拟列中使用上述函数:?

1 SQL>ALTER?TABLE?emp?ADD?sal_pack_temp GENERATED ALWAYS?AS?( sum_num(SAL,COMM) ):
2 Table?Altered

虚拟列的注释?

为虚拟列创建注释的方法:

1 SQL> COMMENT?ON?COLUMN?emp.sal_pack?IS?'Virtual column [sal+ comm]';
2 Comment created.

上述例子看来虚拟列的功能比视图本身要简单很多。

希望这对你也有用。

?Oracle 11g 数据库的新特性 ——??只读表

只读表跟普通的表没有区别,但不允许任何事务对其执行任何?DML(Insert, Update, Delete)?操作。

在 Oracle 11g 之前,“只读”只对数据库和表空间有效,而到了 11g,你可以设置某个表为只读表。

?

在 11g 之前,如果我们要实现一个只读表,必须通过触发器和约束限制来实现。

1- 表触发器

下面我们简单创建一个表和触发器来演示这种方法:

01 CREATE?TABLE?READ_ONLY_TABLE (COL1 NUMBER);?
02 ????
03 ?CREATE?OR?REPLACE?TRIGGER?READ_ONLY_TABLE_TRG?
04 ???BEFORE?DELETE?OR?INSERT?OR?UPDATE?
05 ???ON?READ_ONLY_TABLE?
06 ???REFERENCING NEW?AS?NEW OLD?AS?OLD?
07 ???FOR?EACH ROW?
08 ?DECLARE?
09 ?BEGIN?
10 ???RAISE_APPLICATION_ERROR (-20001,?'Table is read only table.');?
11 ?END;?
12 ????
13 ?INSERT?INTO?READ_ONLY_TABLE?
14 ????VALUES?(1);

运行这个脚本你将会得到错误信息:

ORA -20001, Table is read only table.

2- 检查约束

使用下面的 SQL 语句:

1 CREATE?TABLE?READ_ONLY_TABLE2 (COL1 NUMBER);?
2 ???
3 ALTER?TABLE?READ_ONLY_TABLE2?ADD?CONSTRAINT?READ_ONLY_CONST?CHECK(0=0) DISABLE VALIDATE;?
4 ???
5 INSERT?INTO?READ_ONLY_TABLE2?
6 ???VALUES?(1);

执行的报错信息:

ORA-25128: No insert/update/delete on table with constraint SCOTT.READ_ONLY_CONST) disabled and validated

很麻烦对不对?

而 Oracle 11g 可通过语法 ALTER TABLE table_name RAED ONLY;? 来实现只读表,看看下面 SQL 语句:

1 CREATE?TABLE?READ_ONLY_TABLE3 (COL1 NUMBER);?
2 ALTER?TABLE?READ_ONLY_TABLE3?READ?ONLY;?
3 INSERT?INTO?READ_ONLY_TABLE3?VALUES?(1);

执行后的报错信息是:

ORA-12081: update operation not allowed on table "SCOTT"."READ_ONLY_TABLE3"

可是我怎么知道一个表是否只读表呢?

你可以通过数据字典视图 (ALL_TABLES,DBA_TABLES,USER_TABLES,TABS)中的 READ_ONLY 列得知,如:

1 SELECT?table_name, READ_ONLY?FROM?tabs;

运行结果:

?

[责任编辑:admin]

------分隔线----------------------------