楼主: dingjun123

[精华] 【有奖讨论】PL/SQL编程要点和注意点

[复制链接]
论坛徽章:
3
2009新春纪念徽章
日期:2009-01-04 14:52:28ITPUB9周年纪念徽章
日期:2010-10-08 09:31:222012新春纪念徽章
日期:2012-01-04 11:50:44
21#
发表于 2011-12-28 23:57 | 只看该作者
5
Tom Keyt说过:
You should do it in a single SQL statement if at all possible.
If you cannot do it in a single SQL Statement, then do it in PL/SQL.
If you cannot do it in PL/SQL, try a Java Stored Procedure.
If you cannot do it in Java, do it in a C external procedure.
If you cannot do it in a C external routine, you might want to seriously think about why it is you need to do it…
当然,这世界上没有绝对正确的真理,我在工作经常遇到一个简单的SQL Statement可以做却最后使用了PLSQL。一个简单例子,一个有上10亿records的table中某一个column,如果是NULL,update到‘A’,这个update statement在我们公司的系统里必死(golden gate, rollback......)。
cursor本身没有问题,更不是洪水猛兽。每一个SQL都会用到cursor,cursor是无法避免的。我们所要避免的是用cursor一个一个的loop,我一般都用以下这个模式:
   open cursor;
   loop
       fetch c bulk collect into l_c1, l_c2, ....... LIMIT 1000;
       for i in 1 .. l_c1.count
       loop
            process....
       end loop;
       forall i in 1 .. l_c1.count
            insert into ..... values ( L_c1(i), .... );
       end loop;
       exit when c%notfound;
   end loop;
   close cursor
LIMIT的值可以自己调整,一般来说我都是用10000,有时候1000。当然要是不愿意”麻烦“的也不要太担心,Oracle Database automatically optimizes it in Oracle Database 10g and above,我记得11g是相当于limit 200(不确定),但是我还是更愿意自己写。

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
22#
发表于 2011-12-29 00:26 | 只看该作者
llover 发表于 2011-12-28 23:57
5
Tom Keyt说过:
You should do it in a single SQL statement if at all possible.

这个所谓的自动优化,应该说的是FOR 游标,和FORALL写入没有关系。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
23#
发表于 2011-12-29 00:44 | 只看该作者
7.减少代码耦合度和提高代码重用性一些讨论和案例,大家有类似经验都可以分享一下。比如包起到封装的效果,封装的好必然可以减少耦合度,提高代码重用性。

事实上,任何事情都要掌握一个度。耦合少了,连接必然增多——比如函数多层嵌套,这就和表该按范式设计还是反范式设计,如果按反范式,又反到多少比较合适?这些问题无法一概而论,只能就事论事

请注意:这里的“事”,可以是具体的事也可以是抽象的事

使用道具 举报

回复
论坛徽章:
3
2009新春纪念徽章
日期:2009-01-04 14:52:28ITPUB9周年纪念徽章
日期:2010-10-08 09:31:222012新春纪念徽章
日期:2012-01-04 11:50:44
24#
发表于 2011-12-29 00:46 | 只看该作者
newkid 发表于 2011-12-29 00:26
这个所谓的自动优化,应该说的是FOR 游标,和FORALL写入没有关系。

对,这个就不能用forall了,不过比一个从table里fetch强点儿

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
25#
发表于 2011-12-29 02:00 | 只看该作者
lastwinner 发表于 2011-12-29 00:44
7.减少代码耦合度和提高代码重用性一些讨论和案例,大家有类似经验都可以分享一下。比如包起到封装的效果, ...

不好说,跟着感觉走
SQL是很难重用的,一个SQL就是解决一个特定问题。

使用道具 举报

回复
求职 : 数据库开发
论坛徽章:
29
ITPUB学员
日期:2009-10-14 18:49:45至尊黑钻
日期:2015-12-31 11:11:56数据库板块每日发贴之星
日期:2009-10-22 01:01:02优秀写手
日期:2014-04-30 06:00:17ITPUB8周年纪念徽章
日期:2009-10-09 21:30:10秀才
日期:2017-05-17 11:39:09马上有车
日期:2014-10-09 10:14:53马上有钱
日期:2014-02-18 16:43:09路虎
日期:2013-10-15 15:38:59林肯
日期:2013-09-12 15:57:33
26#
发表于 2011-12-29 10:04 | 只看该作者
写PL/SQL的话。。要在最开始极力缩小数据范围。在开始用1到2个SQL从物理表中取出最小范围的数据,之后的代码都只是对临时表的操作

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
27#
发表于 2011-12-29 10:35 | 只看该作者
newkid 发表于 2011-12-29 02:00
不好说,跟着感觉走
SQL是很难重用的,一个SQL就是解决一个特定问题。

是,除非多个业务都会使用相同的SQL来获取一些基础数据

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
28#
发表于 2011-12-29 10:36 | 只看该作者
风铃中の鬼 发表于 2011-12-29 10:04
写PL/SQL的话。。要在最开始极力缩小数据范围。在开始用1到2个SQL从物理表中取出最小范围的数据,之后的代码 ...

提高效率很重要~

使用道具 举报

回复
招聘 : 多个岗位招聘
论坛徽章:
33
2010广州亚运会纪念徽章:跆拳道
日期:2010-11-22 15:42:39灰彻蛋
日期:2012-05-16 13:17:56参与WIN7挑战赛纪念
日期:2012-05-24 10:37:35茶鸡蛋
日期:2012-05-28 17:27:32灰彻蛋
日期:2012-06-13 18:48:14双黄蛋
日期:2012-06-14 14:32:02奥运会纪念徽章:帆船
日期:2012-07-10 09:43:29奥运会纪念徽章:足球
日期:2012-08-17 09:17:32奥运会纪念徽章:帆船
日期:2012-07-26 15:46:49奥运会纪念徽章:赛艇
日期:2012-08-20 16:23:58
29#
发表于 2011-12-29 11:00 | 只看该作者
1.    PL/SQL中的命名规范和编程规范:包,过程,函数,触发器,类型,变量等


我们统一是前缀
v_  变量
p_  参数
后面跟英文的短名 比如EMP SMPID

一把是全大写


2.PL/SQL中的异常处理规范:异常分类:编译期、运行期、可预测的、不可预测的,异常如何捕获与如何处理,在什么场合和位置处理异常。相关包比如DBMS_UTILITY.FORMAT_ERROR_STACK、DBMS_UTILITY.FORMAT_CALL_STACK、DBMS_UTILITY.FORMAT_ERROR_BACKTRACE以及10g的DML ERROR LOG,批处理异常特点和应用。比如when others部分到底该如何处理,when others null;完事了?是否该考虑定制一个高度封装的异常处理包来处理异常?


我们比较简单的 exception 里
when others 把 sqlcode 和sqlerrm 写到error表里。

我们还采用在程序块中加变量的方式来标示 程序块的用途和提示。

  1. declare

  2. ...
  3. v_errmsg  varchar2(2000);
  4. ...

  5. begin
  6. .....
  7. v_errmsg:='查找员工号';
  8. .....
  9. v_errmsg:='查找员工工资';
  10. .....
  11. v_errmsg:='更新员工薪资系数';
  12. .....
  13. v_errmsg:='处理完毕';
  14. .....

  15. exception
  16.   when others
  17.       pkg_error.p_logerror(sqlcode,sqlerrm,v_errmsg);

  18. end


复制代码


3.PL/SQL中的静态sql和动态sql规范以及何时使用绑定变量,何时避免使用绑定变量,


一般都是 把拼好的sql 放到一个 varchar变量里
然后 用参数 执行


4.sql与PL/SQL的关系,如何最佳使用PL/SQL特性而避免使用sql。

能用sql的不用plsql
毕竟plsql是对sql的包装。

不过plsql 更多的是一种开发语言。从开发的角度用plsql即可~



5.PL/SQL中的cursor使用规范,如何避免不必要的cursor使用 。

我们都是fetch  bullet into

然后close
然后 loop  数组

个人认为 还是要 规范化

  1. open cursor for select xxx  from  xxx;

  2. fetch into xxx;

  3. close;


  4. loop

  5. xxxx
  6. xxxx
  7. xxxx

  8. end loop



复制代码

6.如何使用好PL/SQL的一些优化机制:管道函数、bulk binding、nocopy,returning,cache,各种类型的合理使用.事务和并发控制:如commit的频率、场合、位置,for update (nowait),for update skip locked等。

这些俺们都木有用到,对plsql的使用还比较初级~

7.减少代码耦合度和提高代码重用性一些讨论和案例,大家有类似经验都可以分享一下。比如包起到封装的效果,封装的好必然可以减少耦合度,提高代码重用性。

这块更多的是涉及架构、框架性的东西。与语言无太大关系。
一般是把常用的函数抽象出来。比如f_findempname   f_cal啥的
就是把大部分重复性的东西 写成一个。
然后用函数的形式调用。



8.最后一点,PL/SQL内置包可能是PL/SQL编程中比较容易忽略的部分,oracle package众多,如果能使用恰当,会让我们的代码量减少,并且效率更好,那么能否讨论下你认为的常用包以及一般用途。


说实话,常用就一个 output包。
其它了解较少,不太知道需要用啥。









请lz 指导~

使用道具 举报

回复
论坛徽章:
2
ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-01-04 11:50:44
30#
发表于 2011-12-29 12:51 | 只看该作者
本帖最后由 mikeamy 于 2011-12-29 12:54 编辑

个人看法:
1、注意包与包耦合程度。
2、函数或过程功能简单化,尽量可以重用。
3、面向对象的编程思想实现所需要的功能。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表