数据的虚拟列-让数据库中的C字段等于a+b

直接用update aaaaa aa set aa.f = (aa.a+aa.b)就行了

=======================================

引出来的新知识--虚拟列

虚拟列的好处是:如果c=a+b那插入数据时;值只插入a=1,b=2;那么c会自动是3

oracle temporary table and virtual column

(2013-07-31 15:06:55)

表是数据库中保存用户数据最基本的结构。下面我简要的学习了临时表和虚拟列。

表按照永久性可以分临时表和永久表。

临时表使用create global temporary table关键字来创建,创建的临时表仅对当前的session可见,其他session是不可见的;临时表在创建时,有关表的数据是保存在数据字典中(临时表空间也永久存在的,但是里面的数据却是没有的,退出session后仅仅知识做truncate table的操作,所以临时表空间在不用的时候是要手动drop的),但是没有空间分配给临时表,直到有数据插入时才分配。对临时表的操作和对永久表(普通表)的dm和ddll操作是一样的,她们两者之间仅是生存周期不同。临时表分session临时表和事务临时表,session临时表在创建时会指定on commit preserve rows,session临时表在该session结束时会自动删除,仅该session可见。事务临时表在创建时必须指定on commit delete rows(如果没有指定则模式是事务临时表),事务临时表仅在创建的事务中存活,该事务结束则也会消失。

创建临时表的一些限制:

1)不能分区,不能聚簇,不能索引组织

2)不能在临时表中有外键约束

3)临时表不能包含嵌套表中的列

4)临时表不支持LOB_storage_clause: TABLESPACE, storage_clause, or logging_clause.

5)不支持并行的update,delete,merge

6)在创建临时表时唯一可以指定的段属性是表空间,且表空间只能是临时表空间,如果在其他表空间会报0ra-02195尝试创建的临时对象在会临时表空间中

7)分布式事务不支持临时表

如果使用as 子查询语句来创建表则可以不指定数据类型,设置外键的column也可以不指定数据类型

虚拟列:虚拟列是不保存在磁盘中的,仅在获取的时候根据存储在磁盘中的列计算,组合获取。虚拟列可以创建索引,可以收集统计信息。创建虚拟列的语法是:column datatype(generated always) as (exp) virtrual,在定义虚拟列时没有指定数据类型则默认使用虚拟列表达式里面返回的值的数据类型,虚拟列的值不能是哦那个update和insert操作来更新,其值会根据新加入或更新的对应的列值计算来获取。针对虚拟列创建的索引等价于创建一个函数索引

虚拟列的限制:

1)虚拟列只能在relation heap表中使用,在组织索引表,外部表,对象表(objct table),聚簇报,临时表中都不可用。

2)虚拟列的表达式不能指向另一个虚拟列(虚拟列是在查询时根据表达式来计算,所以会有存在计算的是按后),这样会存在不确定性;虚拟列表达式涉及到的列 只能在同一个表中;虚拟列表达式中可以使用用户自定义的函数,但是如果使用用户自定义的函数后,该虚拟列不能作为分区;虚拟列表达式返回的值必须是是一个 确定的值;

3)虚拟列的数据类型不能是 a user-defined type, or LOB or LONG RAW.

虚拟列相关测试脚本以及结果:

SQL> create or replace function test1
  2  as
  3  begin
  4  return 23;
  5  end;
  6  /

函数已创建。


SQL> create table testvirtual (age number,
  2  v_test generated always as (age+10),
  3  v_test1 generated always as test1);
v_test1 generated always as test1)
                            *
第 3 行出现错误:
ORA-02000: 缺失 ( 关键字

SQL> insert into testvirtual values(10,20);
insert into testvirtual values(10,20)
            *
第 1 行出现错误:
ORA-54013: 不允许对虚拟列执行 INSERT 操作

SQL> insert into testvirtual values(10);
insert into testvirtual values(10)
            *
第 1 行出现错误:
ORA-00947: 没有足够的值


SQL> insert into testvirtual (age) values(10);

已创建 1 行。
SQL> select * from testvirtual;

       AGE     V_TEST
---------- ----------
        10         20


SQL> alter table testvirtual add (v_test1 as (v_test+1) virtual);
alter table testvirtual add (v_test1 as (v_test+1) virtual)
*
第 1 行出现错误:
ORA-54012: 在列表达式中引用了虚拟列
SQL> alter table testvirtual add (v_test1 as (age+1) virtual);

表已更改。

SQL> create or replace function testxu (p_in number) return number deterministic
 as
  2  begin
  3  return p_in+20;
  4  end;
  5  /

函数已创建。


SQL> create table testpartition (age number,
  2  v_age as (testxu(age)) virtual)
  3  partition by range(v_age)(
  4  partition p1 values less than (30),
  5  partition p2 values less than (100),
  6  partition p3 values less than (200),
  7  partition pn  values less than (MAXVALUE)
  8  );
v_age as (testxu(age)) virtual)
          *
第 2 行出现错误:
ORA-54021: 不能在分区列或子分区列中使用 PL/SQL 表达式

SQL> create table testpartition (age number,
  2  v_age as (age+10) virtual)
  3  partition by range(v_age)(
  4  partition p1 values less than (30),
  5  partition p2 values less than (100),
  6  partition p3 values less than (200),
  7  partition pn  values less than (MAXVALUE)
  8  );

表已创建。

网络文献参考:

虚拟列http://yangtingkun.itpub.net/post/468/409211

原文地址:https://www.cnblogs.com/wushuishui/p/4301558.html