54SA.COM|专注于系统运维管理,为中国SA提供动力!
Getting online shouldn't be tough. $7.99 .COMs
系统管理员之家Banner
当前位置: 主页 > 信息化 > 数据库 >

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 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]


------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
用户名:
最新评论 进入详细评论页>>