资源描述:
《oracle 11g 虚拟列》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、如果你要做一些大型OLTP(淘宝京东火车票)的网站,对一些表进行DML操作的时候,容易发生“缺失更新”的情况。我们在做spacermanager做dml模拟的时候,瞬间对数据库多表造成每秒数万的dml操作,如果遇到oracle11g的库,可以采用这种思路,防止产生缺失更新的现象。这时Oracle11g增加了表的虚拟列,就能比较好的处理这个问题。这个虚拟列的数据并没有存储在数据文件中,而是Oracle通过列数据的生成放到了数据字典中。看一个简单的例子:SQL>CREATEORREPLACEFUNCTIONF_GETTYPE(
2、P_TYPEINVARCHAR2)RETURNNUMBER2DETERMINISTICAS3BEGIN4IFP_TYPEIN('TABLE','INDEX','LOB','TABLEPARTITION','INDEXPARTITION','LOBPARTITION',5'TABLESUBPARTITON','INDEXSUBPARTITION','LOBSUBPARTITION','CLUSTER')THEN6RETURN1;7ELSE8RETURN0;9ENDIF;10END;11/函数已创建。SQL>CREATETAB
3、LET_VIRTUAL_COLUMN2(3IDNUMBERPRIMARYKEY,4V_LENGTHAS(CEIL(LENGTH(TO_CHAR(ID))/2)+1+LENGTH(NAME)+LENGTH(TYPE)),5NAMEVARCHAR2(30),6V_NAMECHAR(50)GENERATEDALWAYSAS(LOWER(NAME))VIRTUAL,7TYPEVARCHAR2(30),8V_TYPEAS(F_GETTYPE(TYPE))9);表已创建。上面例子中,V_LENGTH、V_NAME和V_TYPE都是虚拟
4、列,虚拟列的数值是通过真实列中的数据计算而来的。虚拟列的位置可以放在它参考的列的前面,也可以包括多个实际列的值,但是不能引用其他的虚拟列:SQL>CREATETABLET_VIRTUAL_COLUMN_ERR2(IDNUMBER,3V_ID1AS(ID*5),4V_ID2AS(V_ID1+45)5);V_ID1AS(ID*5),*第3行出现错误:ORA-54012:在列表达式中引用了虚拟列虚拟列的完整写法如上面例子中V_NAME列,包括列名、数据类型、GENERATEDALWAYS关键字、AS加列表达式和VIRTUAL关键
5、字。其中GENERATEDALWAYS和VIRTUAL为可选关键字,主要用于描述虚拟列的特性,写与不写没有本质区别。而列的数据类型如果忽略,那么Oracle会根据AS后面的表达式最终结果的数据类型来确定虚拟列的数据类型。虚拟列可以使用Oracle自带的函数,也可以使用用户定义的函数,不过对于用户定义的函数要求必须声明函数的确定性:SQL>CREATEORREPLACEFUNCTIONF_TESTRETURNNUMBERAS2BEGIN3RETURN1;4END;5/函数已创建。SQL>CREATETABLET_VIRTUA
6、L_COLUMN_DETER2(IDNUMBER,VIDAS(F_TEST));(IDNUMBER,VIDAS(F_TEST))*第2行出现错误:ORA-54016:指定了无效的列表达式虚拟列必须是对实际列进行操作后的结果,不能像上面这样直接写一个返回常数的函数,换句话说,表不能只包括虚拟列:SQL>CREATEORREPLACEFUNCTIONF_TEST(P_ININNUMBER)RETURNNUMBERAS2BEGIN3RETURN1;4END;5/函数已创建。SQL>CREATETABLET_VIRTUAL_COL
7、UMN_DETER2(3IDNUMBER,4V_IDAS(F_TEST(ID))5);V_IDAS(F_TEST(ID))*第4行出现错误:ORA-30553:函数不能确定现在错误信息显示,函数没有声明确定性:SQL>CREATEORREPLACEFUNCTIONF_TEST(P_ININNUMBER)RETURNNUMBERDETERMINISTICAS2BEGIN3RETURN1;4END;5/函数已创建。SQL>CREATETABLET_VIRTUAL_COLUMN_DETER2(3IDNUMBER,4V_IDAS(
8、F_TEST(ID))5);表已创建。Oracle虽然在创建创建的时候会检查函数的确定性,在表建立之后,却可以将函数替换为非确定性函数:SQL>INSERTINTOT_VIRTUAL_COLUMN_DETER(ID)VALUES(1);已创建1行。SQL>SELECT*FROMT_VIRTUAL_COL