(1)广泛使用绑定变量,特别是批量绑定,因为这可以有效的避免sql的硬解析和PL/SQL引擎和SQL引擎的上下文切换!
(2)广泛使用UROWID来处理DML语句(UROWID是ROWID扩展,ORACLE推荐使用UROWID来替代ROWID)
(3)在你的存储过程中谨慎使用DDL语句(create、alter、drop、truncate等),因为这可能会破坏你的transaction的连续性,更为严重的是可能会阻塞DML操作并可能会导致大量library cache latch争用并且有可能会导致某些sql执行计划的改变。
(4)不要在存储过程里不应该commit的地方commit,特别是当你的存储过程会被另外一个存储过程调用的时候,你考虑到了你这么做会破坏调用你的父存储过程的transaction的连续性了吗?
(5)注意你面对的数据量,小数据量的处理方法和海量数据的处理方法是不一样的!
(6)循环的时候要注意清空临时变量的值
(7)注意“select into 变量”的问题,使用子begin语句封装“select into 变量”以避免可能会出现的错误,这样就可以避免要在“select into 变量”之前先执行一下select count(*)
(8)不要让oracle执行你的PL/SQL代码时产生隐式转换
(9)在PL/SQL中定义varchar2变量的时候当你在不知道你所定义的变量的长度的时候可以将其定义为varchar2(4000),这一点都不浪费!
(10)如果你写的一组存储过程有逻辑上的关联,那我建议你要把这些存储过程封装到一个package里面
(11)改正你的PL/SQL代码里的所有编译时编译器提示出的warning
(12)循环的时候一定要注意exit,否则就太可怕了!
(13)处理显式cursor的时候一定要注意fetch和exit,否则就太可怕了!如下是我处理的一个真实的案例,这个案例中暴露出的问题就很好的说明了处理cursor的时候一定要注意fetch和exit:

今天下午1点多的时候接到同事的一封信,信里提到我们的一个10gR2的开发环境连不进去了,报这样的错“ORA-00257:archiver error.Connect internalonly,until freed.”。很明显是因为归档进行不下去而导致整个系统被hang住了。
      我上去一看,果然是存放归档日志的目录满了。上述开发环境的存放归档日志的目录大小为10个G,alert log显示从今天11点半开始到下午1点左右的这段时间系统整整产生了10个G的归档日志,而且还在源源不断的继续产生。在继续产生归档日志的时候因为空间满了,所以导致整个系统被hang住。原因知道了,处理过程就很清晰了。
      只保留一个归档日志,然后手工把所有其他的归档日志rm掉,注意这里不要一下子就把所有的归档日志给rm掉,否则可能导致文件系统的句柄无法释放,进而这些归档日志占用的空间也无法释放。然后run一个ADDM报告,看一下是什么导致了在这么短的时间内产生了这么多的归档日志。从ADDM报告中可以很清晰的看到产生这么多归档日志的根本原因是因为一个存储过程里的几条sql在短时间内执行了1400多万次的缘故。
     用alter system kill session配合kill -9杀掉这个存储过程所在的session,以阻止它源源不断的产生归档日志。
     接着我分析了一下上述存储过程,发现根本原因在于在这个存储过程里打开了一个cursor,fetch这个cursor中的一条记录到一个record里,然后开启一个循环,在循环里run上述的那几条sql语句。但致命的是在循环的末尾并没有再fetch这个cursor中的另外一条记录,这就导致了上述循环的条件永远为真,所以上述sql如果不被我中断的话就会永远执行下去。这也就解释了为什么会在短时间里产生了大量的归档日志,并且undo tablespace的空间也被消耗殆尽。后续处理过程这里省略……

(14)bulk collect into的时候不要一次collect太多的数据,建议一次collect的数据量在10000条以内,你可以用批量绑定自带的limit子句来限制或者使用rownum来限制
(15)如果你使用了批量绑定,那为什么要把时间浪费在写诸如insertinto tablename(column1,column2,……,column100) values(value1(i),value2(i),……,value100(i))这样的sql语句上面?如果有可能,就写一个你自己的存储过程代码生成器吧,让它来帮你生成这样的语句。你应该把精力集中在更有用的方面!
(16)你希望你的代码被并发执行吗?如果你不希望或者你的代码根本就不能够被并发执行,那就想一个办法控制并发吧!在应用层面控制就好,比如在update之前先尝试对该记录加for update nowait的锁,或者利用DML语句当前读的特性来避免并发都是不错的主意
(17)不要写诸如insert into tablename1 select* from tablename2这样的语句,你考虑到扩展性了吗?假如以后tablename1或者tablename2增加或减少字段了呢?
(18)谨慎使用hint,除非你很清楚你在做什么。比如说这里你强制oracle使用了某个索引,假如以后这个索引的名字被改了,由此带来的执行计划的变更你怎么办?你考虑到这种情况了吗?
(19)注意关联更新丢失数据的问题,update语句如果没有指定where条件那就是对所有的数据做update操作,这个就太恐怖了!
(20)用好临时表,有时候临时表很有用!特别是在根据一堆复杂条件去更新海量数据的时候
(21)尽量避免在存储过程里使用递规!不是说不能用递规(递规在某些特定的情况下很有用),而是说在用递规的时候一定要避免无限递规的情况!
(22)写好你的PL/SQL代码里的注释,这个很重要!不写注释并不代表你很厉害!

常用的PL/SQL开发原则的更多相关文章

  1. ORACLE PL/SQL开发--bulk collect的用法 .

    刚刚在inthirties老大的博客里看到这篇文章,写的不错,正好自己最近在学习PL/SQL,转过来学习学习. ============================================ ...

  2. PL/SQL开发中动态SQL的使用方法

    一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DDL语句及系统控制语句,可以通过使 ...

  3. Oracle PL/SQL开发基础(第三十三弹:EXCEPTION_INIT)

    如果有一些异常并没有异常名称,比如一些ORA-开头的异常并没有一个友好的预定义的异常定义,此时在WHEN子句中无法使用具体的异常名称,必须要使用OTHERS异常处理器进行捕捉.通过EXCEPTION_ ...

  4. PL/SQL开发五年工作经验精典实例

    1. minus(差集)与intersect(交集) minus指令是运用在两个SQL语句上.它先找出第一个SQL语句所产生的结果,然后看这些结果有没有在第二个SQL语句的结果中,如果有的话,那这一笔 ...

  5. Oracle PL/SQL开发基础(第三十四弹:RAISE_APPLICATION_ERROR)

    RAISE_APPLICATION_ERROR在子程序内部使用时,能从存储子程序中抛出自定义的错误消息.这样就能将错误报告给应用程序而避免范围未捕获异常. 语法如下: RAISE_APPLICATIO ...

  6. Oracle SQL Developer,Oracle 开发工具之toad、SQL Developer、PL/SQL Developer等比较

    参考: oracle 的几个开发工具比较 因Oracle几乎是中大型商业企业数据的首选,所以比较一下常用与Oracle的工具. Oracle SQL Developer 免费,一般开发使用足矣,常用. ...

  7. PL/SQL数据开发那点事

    PL/SQL开发那点事----->PL/SQL开发过程中异常处理 用户编写的PL/SQL块在执行过程中不可避免地要发生一些错误. 这里涉及的错误并不是由于程序的语法错误引起的,而是因为处理的数据 ...

  8. PL/SQL存储过程编程

    PL/SQL存储过程编程 /**author huangchaobiao *Email:huangchaobiao111@163.com */ PL/SQL存储过程编程(上) 1. Oracle应用编 ...

  9. 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

    本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...

随机推荐

  1. [nowCoder] 局部最小值位置

    定义局部最小的概念.arr长度为1时,arr[0]是局部最小.arr的长度为N(N>1)时,如果arr[0]<arr[1],那么arr[0]是局部最小:如果arr[N-1]<arr[ ...

  2. [设计模式] 7 桥接模式 bridge

    #include<iostream> using namespace std; class AbstractionImp { public: virtual ~AbstractionImp ...

  3. ubuntu下opencv2.4.9安装测试

    ubuntu下opencv2.4.9安装测试 whowhoha@outlook.com 一.依赖包安装 1.  build-essential 软件包 sudo apt-get install bui ...

  4. 《head first java 》读书笔记(三)

    Updated 2014/04/03 --P518 Thread需要任务,任务是实现过Runnable的实例.Runnalbe这个接口只有一个方法.run()会是新线程所执行的第一项方法.要把Runn ...

  5. **【ci框架】PHP的CI框架集成Smarty的最佳方式

    因为CI自带的模板功能不是很方便,所以大家普遍采用集成Smarty的方式来弥补CI这方面的不足. 本人在网上看了不少CI集成Smarty的教程,包括咱们CI论坛里面的一个精华帖子 http://cod ...

  6. REST_FRAMEWORK加深记忆-加了API_ROOT及超链接的CASE

    urls.py from django.conf.urls import url from rest_framework.urlpatterns import format_suffix_patter ...

  7. hdu 4447 Yuanfang, What Do You Think?

    思路: 这题有个结论也可以自己归纳: 对于给定的n,其约数用pi表示 T(n)=T(p1)T(p2)……T(pn)T(n') 其中T(n')是这个式子所独有的也就是 T(n')=(x^n-1)/T(p ...

  8. lintcode 中等题:Single number III 落单的数III

    题目 落单的数 III 给出2*n + 2个的数字,除其中两个数字之外其他每个数字均出现两次,找到这两个数字. 样例 给出 [1,2,2,3,4,4,5,3],返回 1和5 挑战 O(n)时间复杂度, ...

  9. iOS 开发中遇到的问题

    1. 关于纠结很久的KVO崩溃问题,其真正原因是,在删除roomItem的KVO之前,将这个对象已经赋值为nil,所以实际上并没有删除他的observer,因此而崩溃:长时间纠结的原因是受.cxx_d ...

  10. 含有特殊字符的JSON串解析方法

    工具方法:public static <T> T parseJsonString(String json,Class<T> classType){ ObjectMapper m ...