oracle视图(带参数).docx_第1页
oracle视图(带参数).docx_第2页
oracle视图(带参数).docx_第3页
oracle视图(带参数).docx_第4页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

具体的Oracle参数视图实践(1)2010-04-19 10:20 佚名 CSDN博客 我要评论(0) 字号:T | T一般情况下Oracle数据库是不带参数的视图。有时,我们想使用Oracle参数视图,可以给我们方便查询数据。下面就来简单介绍下。AD: 一般情况下Oracle数据库是不带参数的视图。有时,我们想使用Oracle参数视图,可以给我们方便查询数据。比如,眼下我面对这这样一个问题:要打印一张报表,报表的数据源是Oracle视图。现在,随着数据量的增大,打印报表的速度越来越慢了。所以首先想到了如何优化视图,视图的基表为3张表,表A几百条数据,表B大约3万条数据,表C大约60万条数据,其中表C每月大约增加3万条数据,视图的SCRIPTS大概是这个样子:1. CREATEORREPLACEVIEWM_VIEW 2. (COL1,COL2,COL3) 3. AS 4. SELECTCOL1,COL2,COL3FROMA,B,CWHEREA.NAME=GET_A_NAME(B.ID)ANDB.ID=C.ID;其中,GET_A_NAME()为已定义好的根据B表ID查询其对应的A表NAME的方法。各基表中都已建立了索引,考虑到打印报表时值需要指定月份的数据,所以,想到能不能在视图中限定C.TIME=指定的时间,这样数据量就会大大下降,只需要C表中大约3万条数据。但是,问题是,Oracle中视图是不能带参数的。有问题,就有办法,用变通的办法,看招:方案1:利用全局变量。用全局变量做什么?改一下Oracle参数视图:1. CREATEORREPLACEVIEWM_VIEW 2. (COL1,COL2,COL3) 3. AS 4. SELECTCOL1,COL2,COL3FROMA,B,CWHEREA.NAME=GET_A_NAME(B.ID)ANDB.ID=C.IDANDC.TIME=全局变量; 全局变量中保存查询的时间条件,在每次调用查询视图之前,先修改全局变量的值,然后查询视图时就会按照指定条件筛选数据。但是,问题又来了,Oracle参数中是不支持全局变量的,要实现全局变量,同样需要变通实现,方法就是用包(PACKAGE),针对眼前的应用,可以设计如下的包:1. CREATEORREPLACEPACKAGEPKG_REPORTAS 2. FUNCTIONGET_VALUERETURNVARCHAR2; 3. PROCEDURESET_VALUE(PS_TIMEINVARCHAR2); 4. ENDPKG_REPORT; 5. CREATEORREPLACEPACKAGEBODYPKG_REPORTIS 6. M_VVARCHAR2(6); 7. PROCEDURESET_VALUE(PS_TIMEINVARCHAR2)ISBEGINM_V:=PS_TIME;END; 8. FUNCTIONGET_VALUERETURNVARCHAR2ISBEGINRETURNM_V;END; 9. ENDPKG_REPORT; 首先修改上面的视图,把全局变量替换成PKG_REPORT.GET_VALUE(),在程序中打印报表时先调用PKG_REPORT.SET_VALUE()方法设定时间条件,然后查询视图生成报表,这样就变通的实现了带参数视图。 方案2:利用临时表。利用临时表的思路是这样的:首先将所需数据插入到临时表中,然后构造视图时以该临时表为基表。在Oracle参数中,临时表分为事务级别、会话级别两种。会话级别的临时表,顾名思义是基于SESSION的,在SESSION失效时表中的数据会自动TRUNCATE掉,而且临时表中的数据各SESSION只能访问自己的数据,不用考虑并发冲突的问题。可见,会话级别的临时表正适合我的应用。首先,建立临时表:1. CREATEGLOBALTEMPORARYTABLEM_TEMP_TABLE 2. ( 3. COL1VARCHAR2(10BYTE), 4. COL2VARCHAR2(80BYTE), 5. COL3VARCHAR2(16BYTE) 6. ) 7. ONCOMMITPRESERVEROWS-指定临时表是会话级别的 8. NOCACHE; 然后,重构视图:1. CREATEORREPLACEVIEWM_VIEW 2. (COL1,COL2,COL3) 3. AS 4. SELECT*FROMM_TEMP_TABLE;-以临时表为基表最后,在程序中打印报表前,先调用如下过程,往临时表中插入数据:1. CREATEORREPLACEPROCEDUREPR_DYNAMIC_DATA( 2. /* 3. 动态的往会话级别的临时表中插数据 4. */ 5. PS_TIMEINVARCHAR2,-指定的时间条件 6. RTNOUTNUMBER 7. ) 8. IS 9. BEGIN 10. RTN:=1; 11. BEGIN 12. INSERTINTOM_TEMP_TABLE 13. SELECTCOL1,COL2,COL3FROMA,B,CWHEREA.NAME=GET_A_NAME(B.ID)ANDB.ID=C.IDANDC.TIME=PS_TIME; 14. EXCEPTION 15. WHENOTHERSTHEN 16. RTN:=-1; 17. END; 18. IFRTN=1THEN 19. COMMIT; 20. ELSE 21. ROLLBACK; 22. ENDIF; 23. END; 实际测试,方案看总是看上去很美的,究竟能不能响,还不一定。测试了一下:优化前:打印报表需要1分45秒;方案1:打印报表需要1分45秒;方案2:打印报表需要1分35秒;可见,方案真的是看上去美,但并没带来实际的效果。分析其原因,应该是Oracle自动优化了原来的代码,也就是说,SELECT * FROM 视图 A WHERE A.TIME=200710 和SELECT * FROM 基表 A,基表 B WHERE A.ID=B.ID AND A.TIME=200710 在执行时应该是一样的。这只是我的猜想,因为我也没仔细研究过Oracle优化器怎么个工作法。另外,我查看了优化前的视图脚本、利用方案1优化后的视图脚本的EXPLAIN PLAN,调整前的COST=36703670,调整后的COST=17031703。应该说能快一些,但实际并不是这个样儿地,有些不明白了。希望得到指点总结:Oracle参数化视图可以实现。但想以此作为优化的手段,看来并不可取。oracle 视图如何传参数 博客分类: SQL语句 OracleJavaSQL目前,Oracle不支持带参数的视图,只能通过一些方法来变通一下。下面是方法之一: 创建包: create or replace package p_view_param is function set_param(num number) return number; function get_param return number; end p_view_param; create or replace package body p_view_param is paramValue number; function set_param(num number) return number is begin paramValue:=num; return num; end; function get_param return number is begin return paramValue; end; end p_view_param; 视图的建立: create or replace view p_view_user a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论