楼主: yulihua49

[PRO*C] 看我做的数据库包装器

[复制链接]
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
381#
 楼主| 发表于 2009-7-4 18:40 | 只看该作者
原帖由 newkid 于 2009-7-4 01:24 发表


我犯了一个错误。你的存储过程CPU消耗不能通过time测试出来,它测试的时间只是sqlplus的CPU消耗,oracle引擎消耗测不出来。
我程序的消耗可以测出来,也是测不出来引擎消耗部分。

我的观点摆出来了,如果没有新内容,我不争辩,通过一些必要的测试,搞清一些问题,还要再思考一下结果。
我想,我的方法,效率很高,也很可靠易用,这就够了。
我们二者性能是差不多的,说明大家都接近了系统性能的极限。
剩下的问题,就是,谁适合什么就用什么,没必要争论了。

[ 本帖最后由 yulihua49 于 2009-7-4 19:25 编辑 ]

使用道具 举报

回复
论坛徽章:
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
382#
发表于 2009-7-5 02:12 | 只看该作者
原帖由 yulihua49 于 2009-7-4 18:36 发表

好像是偏向OLAP的东西,用户数又不是很多,什么技术都差不多,看你的队伍适合什么。关键是发挥数据库的优势。

好像里边有人质疑开游标,开游标怎么了?我提高效率的主要办法就是开游标,保持游标,面向游标的操作完全摈弃了语法分析问题。

我用游标保持技术PK掉了LDAP。openldap号称具有极快的读取速度。结果使用DAU,ORACLE性能高于LDAP。


你说的是4楼那位吧?
批量处理忌讳的就是用游标逐行处理。你丢一个大SQL给服务器,比你自己用游标一行一行计算,那不知要好多少。
你的做法是全部单表查询,这就导致使用了不必要的游标。比如生成席位的程序,我一个INSERT SELECT只用一个游标,和数据库交互一次;你开了十来个小游标,和数据库有大量的交互。
当然,你现在这种“保持游标”的做法,比起你当初不肯用绑定变量,已经是进步很多了。
说到游标缓存,如果用PLSQL编程,那么就是全自动的,完全不用程序员操心。哪怕你关闭了游标,PLSQL引擎也是假关闭;下次你再打开时它自动会为你从缓存里找出来。
这就是TOM所说的“比软解析更软的解析”(SOFTER SOFT PARSE)

关于如何检测ORACLE自身的开销,你可以看看这个:
http://asktom.oracle.com/tkyte/runstats.html

你用到的资源在数据字典里都有,只要比较运行前后的两个快照,就可以得出你的程序消耗了多少。
希望你不要就此挂免战牌,咱们继续操练。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
383#
 楼主| 发表于 2009-7-5 18:42 | 只看该作者
原帖由 newkid 于 2009-7-5 02:12 发表


说到游标缓存,如果用PLSQL编程,那么就是全自动的,完全不用程序员操心。哪怕你关闭了游标,PLSQL引擎也是假关闭;下次你再打开时它自动会为你从缓存里找出来。
这就是TOM所说的“比软解析更软的解析”(SOFTER SOFT PARSE)


可是我测试,关闭或保持游标速度大约差3倍!
争论可以继续,但属于“友谊赛”。因为从速度上讲,双方都逼近极限,没有太大余地了。没必要像体育比赛似的,0.01秒决胜负。
任何一个业务逻辑,我相信,任何手段都可以实现,当然,我认为采用非过程方法还是高手所为。我等受了几十年编程教育,思想已经很定式了。而且现在的新人,能够熟练使用非过程技巧的,少之又少。
还有一些测试,明天做完就汇报。
关于可移植性,确实有两种。
一种是数据库确定,前端平台不确定,这的确是采用存储过程最好。
另一种是前端确定,数据库不确定,那么存储过程就不是最佳选择。

比如,一个公司开发了一个应用产品。客户A说,我们已经买断了XXX数据库,你要用这个。客户B说,你不能强加我一个数据库产品,要用free的。。。。。。
我们情况更特殊,由于种种关系,系统的某一部分必须采用XXX产品,而XXX产品技术上存在严重问题,万一(几乎是一定)失败,我们需要一个退路,可以回到ORACLE,所以一定要用过程的方法,一定要有可移植性,DAU应运而生,它可以毫不修改的在ORACLE和XXX之间自由切换。DAU技术实际上是我本人对ORACLE极端赞许和肯定的结果。
有了DAU,我可以与SYBASE,MYSQL,DB2,还有那个XXX,PK。我坚信ORACLE的能力,但我要别人看,让大家看到,一模一样的程序,谁更优秀。

[ 本帖最后由 yulihua49 于 2009-7-5 19:01 编辑 ]

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
384#
发表于 2009-7-5 21:01 | 只看该作者
  1. J2EE基础应用:J2EE中SQL语句自动构造方法  

  2. 发布时间:2009.07.03 04:35     来源:赛迪网    作者:fen

  3. 【赛迪网技术社区整理】INSERT、DELETE、UPDATE 三种SQL语句是数据库技术的三大基本语句. 在通常的web开发中对它的处理可以说是无处不在. 如果简单的都用手工来构造这些SQL语句的话, 一方面给我们的开发带来很大的工作量, 另一方面系统灵活性受到很大的限制. 那么能不能基于某种规则让系统自动从页面表单中取出元素构造出SQL语句呢? 首先让我们看看一般INSERT、DELETE、UPDATE 三种语句的基本形式:

  4. INSERT INTO table_name (col_1,col_2,col_3,) VALUES (value_1,value_2,value_3 …)

  5. DELETE FROM table_name WHERE col_n=value_n

  6. UPDATE table_name SET col_1=value_1,col_2=value_2,col_3=value_3 WHERE col_x=value_x


  7. 我们知道,借用j2ee中的request.getParameterNames()方法可以读到表单中的所有元素的名称,有了元素名称借用request.getParameter(elementName)方法可以获取该元素的值。假设在开发中我们让页面元素的名称和底层数据库表的字段名一致。那么在这三种语句中col_n 和 value_n 对我们来说就不是未知的,未知的数据就剩下了 table_name,col_x和value_x 。现在如果我们写一个方法,传入request对象,再把table_name,col_x,value_x作为参数传入方法,那么我们可以轻松的自动构造SQL语句了。但这样做还是有欠灵活,因为一方面每一次使用该方法我们都得人工的设置table_name,col_x和value_x;另一方面别忘了sql语句中对于字符串的字段需要加单引号和替换字符串中间的单引号,而整型、浮点型、系统函数(如now(),to_date()等数据库函数)等不需要做单引号的处理,这些如果没有好的解决的话,我们的方法将受到非常大的限制。要达到再进一步分离最好的办法就是在表单元素命名上面做文章,我们可以自己定义一套元素命名规则,对不同规则命名的元素做不同的处理--设我们定义元素命名规格如下:

  8. 1.table_name,col_x,value_x这类元素,为公共元素。我们规定这类元素名以c_k开头(c=common),我们限制table_name的元素名为c_table,col_x=value_x定义到一起,元素名定为c_where. 当然我们别忘了我们还需要一个元素表示构造什么样(INSERT、DELETE、UPDATE)的SQL语句。我们给这个元素命名c_genre,它的值被限制在INSERT、DELETE、UPDATE这三者之中 。

  9. 2. 对于表单中对应数据库字符串类型的元素,在SQL构造中需要做单引号的处理。这类元素我们暂且称他们为字符串型元素。字符串型元素我们规定其名为s_+数据库表字段名 (s=String)。

  10. 3. 对于不需要做但引号处理的元素(如integer型、float型、数据库系统函数--如now(),to_date()等等)。我们暂且简单的统称这类元素为整型元素。对于整型元素我们限制其命名规则为i_+数据库表字段名(i=Integer)。


  11. 基于上面的规格我们可以非常轻松写一个javabean。代码如下:

  12. /**

  13. * @version: 1.1

  14. * @Time: 2005.03.02

  15. */

  16. package com.river.page ;

  17. import java.util.*;

  18. import javax.servlet.http.HttpServletRequest;

  19. public class PageUtil {

  20. private HttpServletRequest request = null ;

  21. public PageUtil(){

  22. }

  23. public void init(HttpServletRequest _request){

  24. this.request = _request ;

  25. }

  26. public void clear(){

  27. if(this.request != null){

  28. this.request = null ;

  29. }

  30. }

  31. public String get(String elementName){

  32. if(request == null || request.getParameter(elementName) == null){

  33. return "";

  34. }else{

  35. return request.getParameter(elementName);

  36. }

  37. }

  38. public String get(HttpServletRequest _request,String elementName){

  39. init(_request);

  40. return get(elementName);

  41. }


  42. public String getSQL(HttpServletRequest _request){

  43. init(_request);

  44. return getSQL();

  45. }

  46. public String getSQL(){

  47. String sqlstr = "";

  48. String c_table = get("c_table");

  49. String c_genre = get("c_genre");

  50. String c_where = get("c_where");

  51. if(c_genre == null || c_genre.equals("")){

  52. return "the action is null/empty";

  53. }

  54. if(c_table == null || c_table.equals("")){

  55. return "unknow table/empty" ;

  56. }

  57. if(c_genre.equalsIgnoreCase("INSERT")){

  58. java.util.Enumeration arg_names = request.getParameterNames();

  59. String colstr = "",valstr = "";

  60. String arg_name,pre_name,end_name ;

  61. while(arg_names.hasMoreElements()){

  62. arg_name = String.valueOf(arg_names.nextElement());

  63. if(arg_name.length() < 2){

  64. continue;

  65. }

  66. pre_name = arg_name.substring(0,2);

  67. end_name = arg_name.substring(2);

  68. if(pre_name.equalsIgnoreCase("i_")){

  69. colstr = colstr+","+end_name;

  70. if(get(arg_name).equals("")){

  71. valstr = valstr+",NULL";

  72. }else{

  73. valstr = valstr + "," + String.valueOf(get(arg_name));

  74. }

  75. }else if(pre_name.equalsIgnoreCase("s_")){

  76. colstr = colstr+","+end_name;

  77. if(get(arg_name).equals("")){

  78. valstr = valstr+",NULL";

  79. }else{

  80. valstr = valstr+",'"+get(arg_name).replaceAll("'","''")+"'";

  81. }

  82. }

  83. }

  84. if(!colstr.equals("")){

  85. colstr = colstr.substring(1);

  86. valstr = valstr.substring(1);

  87. }

  88. sqlstr = "INSERT INTO "+c_table+" ("+colstr+") VALUES ("+valstr+")";

  89. return sqlstr;

  90. }else if(c_genre.equalsIgnoreCase("UPDATE")){

  91. java.util.Enumeration arg_names = request.getParameterNames();

  92. String colstr = "";

  93. String arg_name,pre_name,end_name ;

  94. while(arg_names.hasMoreElements()){

  95. arg_name = String.valueOf(arg_names.nextElement()).trim();

  96. if(arg_name.length() < 2){

  97. continue;

  98. }

  99. pre_name = arg_name.substring(0,2);

  100. end_name = arg_name.substring(2);

  101. if(pre_name.equalsIgnoreCase("i_")){

  102. if(get(arg_name).equals("")){

  103. colstr += ","+end_name+"=NULL";

  104. }else{

  105. colstr += ","+end_name+"="+get(arg_name);

  106. }

  107. }else if(pre_name.equalsIgnoreCase("s_")){

  108. if(get(arg_name).equals("")){

  109. colstr += ","+end_name+"="+get(arg_name);

  110. }else{

  111. colstr += ","+end_name+"='"+get(arg_name).replaceAll("'","''")+"'";

  112. }

  113. }

  114. }

  115. if(!colstr.equals("")){

  116. colstr = colstr.substring(1);

  117. }

  118. sqlstr = "UPDATE "+c_table+" SET "+colstr;

  119. if(!c_where.equals("")){

  120. sqlstr += " WHERE "+c_where;

  121. }

  122. return sqlstr;

  123. }else if(c_genre.equalsIgnoreCase("DELETE")){

  124. sqlstr = "DELETE FROM "+c_table;

  125. if(c_where != null && !c_where.equals("")){

  126. sqlstr += " WHERE "+c_where;

  127. }

  128. }else{

  129. com.river.debug.Debug.show("unknow action type : "+c_genre);

  130. return null;

  131. }

  132. return sqlstr;

  133. }

  134. public String toString(){

  135. return "version 1.0, date 2005.03.02, author river";

  136. }

  137. }


  138. 这样我们就可以根据页面元素的命名来指导SQL语句的生成。这样做有很多的明显的好处:

  139. 1.减少编码工作,对于元素很多表单,用不着我们去写一大堆的代码,不用去担心哪个元素落下了,元素名有没有些错,单引号有没有处理。

  140. 2.通用、稳定、易于维护,javabean固有的优点,就不用太多的说明了。

  141. 3.分离表层的表单内容与逻辑层SQL语句的构造。设想一下,如果我们数据库表结构有调整时,那么我们只要修改一下表单就好了,根本就不用理原来写好的逻辑处理。附带着再说一句,设想如果我们再写一个类自动执行SQL,那么对于一些基本的增、删、改操作都可以映射到同一个action里面来处理,且不是很爽?


  142. 当然,这样做的缺点也是有的。那就是有一定的性能损耗。特别是碰到表单元素非常多时。但是我想对于那些不是很"苛刻"的项目这点损耗是值得的。


复制代码

使用道具 举报

回复
论坛徽章:
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
385#
发表于 2009-7-5 22:03 | 只看该作者
原帖由 yulihua49 于 2009-7-5 18:42 发表

可是我测试,关闭或保持游标速度大约差3倍!


你哪里看到我反对游标缓存了?我的意思:
1. 游标缓存比反复关闭、打开更好;但是! 能用一个游标(一个SQL)解决,就比多个游标(多个SQL)更快,哪怕你这多个游标是缓存过的!
2. 游标缓存在PL/SQL中一点都不稀罕,而且对程序员是透明的,你即使关闭了游标也会被缓存。

关于支持多数据库的通用系统,我前面也表过态了:
1.以你的售票模块为例,你换个数据库就得再写一遍。到头来和用存储过程的代价是差不多的。所谓的通用并不存在。
2.你前面的代码竟然以ROWID作主键,这是个低级错误,但愿你改过来了。
3.假设真的做出了通用的系统,那么必定以牺牲性能为代价,你用不到数据库的高级特性。
4.在现实中,数据库是作为应用的一个部件来推的。你推你的售票系统,同时必定推了TUXEDO, 推了ORACLE; 如果客户坚持要把ORACLE换掉,他同样有理由要求你改用JAVA.

使用道具 举报

回复
论坛徽章:
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
386#
发表于 2009-7-5 22:05 | 只看该作者
原帖由 〇〇 于 2009-7-5 21:01 发表
J2EE基础应用:J2EE中SQL语句自动构造方法  

发布时间:2009.07.03 04:35     来源:赛迪网    作者:fen

【赛迪网技术社区整理】INSERT、DELETE、UPDATE 三种SQL语句是数据库技术的三大基本语句. 在通常的web开发中对它的处理可以说是无处不在. 如果简单的都用手工来构造这些SQL语句的话, 一方面给我们的开发带来很大的工作量, 另一方面系统灵活性受到很大的限制. 那么能不能基于某种规则让系统自动从页面表单中取出元素构造出SQL语句呢? 首先让我们看看一般INSERT、DELETE、UPDATE 三种语句的基本形式:



没用绑定变量的垃圾代码,没兴趣往下看了。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
387#
发表于 2009-7-6 09:42 | 只看该作者
原帖由 newkid 于 2009-7-5 22:05 发表


没用绑定变量的垃圾代码,没兴趣往下看了。

  1. 8月14日
  2. JAVA 程序中使用ORACLE 绑定变量( bind variable )
  3. 1、为什么要使用绑定变量

  4.       (1)SQL语句硬分析(Hard Parse)太多,严重消耗CPU资源,延长了SQL语句总的执行时间

  5.         SQL语句的执行过程分几个步骤:语法检查、分析、执行、返回结果。其中分析分为硬分析(Hard Parse)和软分析(Soft Parse)。一条SQL语句通过语法检查后,Oracle 会先去shared pool 中找是否有相同的sql,如果找着了,就叫软分析,然后执行SQL语句。硬分析主要是检查该sql所涉及到的所有对象是否有效以及权限等关系,然后根据RBO或CBO模式生成执行计划,然后才执行SQL语句。

  6.    可以看出,硬分析比软分析多了很多动作,而这里面的关键是“在shared pool 中是否有相同的sql”,而这就取决于是否使用绑定变量。

  7.       另:oracle9i引入了soft soft parse,先到pga中的session cursor cache list列表中去查找(session cursor cache list的长度是由session_cache_cursor参数决定的),如果没有找到这条sql,这时候才去检查shard_pool.   对于Oltp系统,很多时候硬分析的代价比执行还要高,这个我们可以通过10046事件跟踪得知。



  8.     (2)共享池中SQL语句数量太多,重用性极低,加速了SQL语句的老化,导致共享池碎片过多。

  9.       共享池中不同的SQL语句数量巨大,根据LRU原则,一些语句逐渐老化,最终被清理出共享池;这样就导致shared_pool_size 里面命中率下降,共享池碎片增多,可用内存空间不足。而为了维护共享池内部结构,需要使用latch,一种内部生命周期很短的lock,这将使用大量的cpu 资源,使得性能急剧下降。

  10.       不使用绑定变量违背了oracle 的shared pool 的设计的原则,违背了这个设计用来共享的思想。



  11. 2、怎么查看没有使用绑定变量

  12. select * from v$sql or v$sqlarea 查看是否有很多类似的语句,除了变量不一样,其他的都一样



  13. 3、如何使用绑定变量?

  14. 编写java 程序时,我们习惯都是定义JAVA 的程序变量,放入SQL 语句中,如

  15. String v_id = 'xxxxx';

  16. String v_sql = 'select name from table_a where id = ' + v_id ;



  17. 以上代码,看起来是使用了变量v_id ,但这却是java 的程序变量,而不是oracle 的绑定变量,语句传递到数据库后,此java 的程序变量

  18. 已经被替换成具体的常量值,变成:

  19. select * from table_a where name = 'xxxxx' ;



  20. 假定这个语句第一次执行,会进行硬分析。后来,同一段java 代码中v_id 值发现变化(v_id = 'yyyyyy'),数据库又接收到这样的语句:

  21. select * from table_a where name = 'yyyyyy' ;



  22. ORACLE 并不认为以上两条语句是相同的语句,因此对第二条语句会又做一次硬分析。这两条语句的执行计划可是一样的!

  23. 其实,只需将以上java 代码改成以下这样,就使用了oracle 的绑定变量:

  24. String v_id = 'xxxxx';

  25. String v_sql = 'select name from table_a where id = ? '; //嵌入绑定变量

  26. stmt = con.prepareStatement( v_sql );

  27. stmt.setString(1, v_id ); //为绑定变量赋值

  28. stmt.executeQuery();



  29. 在Java中,结合使用setXXX 系列方法,可以为不同数据类型的绑定变量进行赋值,从而大大优化了SQL 语句的性能。



  30. 4、java中应用绑定变量的例子

  31. PreparedStatement stmt = conn.prepareStatement('select a from b where c = ? ');

  32. stmt.setLong(1,123);

  33. stmt.executeQuery()

  34. ……



  35. Oracle 绑定变量(Bind Variable )
  36. 1.让Oracle自己绑定变量
  37. set serverout on;
  38. set timing on;
  39. declare
  40. l_sql varchar2(2000);
  41. l_count number;
  42. l_param1 varchar2(100);
  43. l_param2 varchar2(100);
  44. begin
  45. l_param1:=’a';
  46. l_param2:=’b';
  47. select count(*) into l_count from table1 where col_1=l_param1 and col_2=l_param2;
  48. dbms_output.put_line(l_count);
  49. end;
  50. /
  51. 在上面的情况,Oracle会自己绑定变量,即,如果参数保存在一个数组中,select语句放在一个循环中,
  52. select 语句只会编译一次。
  53. 像这样
  54. for i in 1..3
  55. loop
  56. select count(*) into l_count from table1 where col_1=l_param1 and col_2=l_param2 and col_3=i;
  57. dbms_output.put_line(l_count);
  58. end loop

  59. 2.不绑定变量
  60. set serverout on;
  61. set timing on;
  62. declare
  63. l_sql varchar2(2000);
  64. l_count number;
  65. l_param1 varchar2(100);
  66. l_param2 varchar2(100);
  67. begin
  68. l_param1:=’a';
  69. l_param2:=’b';
  70. l_sql:=’select count(*) into :x from table1 where col_1=’||l_param1||’ and col_2=’||l_param2;
  71. Execute Immediate l_sql into l_count;
  72. dbms_output.put_line(l_count);
  73. end;
  74. /
  75. 3.动态绑定变量
  76. set serverout on;
  77. set timing on;
  78. declare
  79. l_sql varchar2(2000);
  80. l_count number;
  81. l_param1 varchar2(100);
  82. l_param2 varchar2(100);
  83. begin
  84. l_param1:=’a';
  85. l_param2:=’b';
  86. l_sql:=’select count(*) into :x from table1 where col_1=:y and col_2=:z ’;
  87. Execute Immediate l_sql into l_count using l_param1,l_param2;
  88. dbms_output.put_line(l_count);
  89. end;
  90. /

  91. :x,:y,:z相当于占位符,即
  92. 1.用:p1,:p2,:p3是一样的。
  93. 2.用:x,:x,:x也是一样的
  94. 需要的绑定变量按顺序排在执行语句后面就可以了,into的除外。
  95. 不过还是用p1,p2好些,至少可以看出绑定了多少个变量。  

  96. 结论:
复制代码



    绑定变量主要适用在Oltp,运行时间很短的系统。如客服系统,时时地进行insert方面的系统。 数据仓库系统不适用,和数据库仓库系统的一条sql运行时间相比,硬分析的代价显然是微不足道的,通过硬分析去选择正确的执行计划才是关键。

  简单一句话,在Oltp系统中应用绑定变量,性能会有质的提高。



                                                                                                                ---引(http://www.apub.org/doc/2006/03/11/10/52/26/21883.html

[ 本帖最后由 〇〇 于 2009-7-6 09:45 编辑 ]

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
388#
发表于 2009-7-6 15:21 | 只看该作者
刚刚自己编一个pro*c demo
遇到一个定点小数的问题,int放不下,double精度不保证,请教 yulihua49 怎么解决

使用道具 举报

回复
论坛徽章:
0
389#
发表于 2009-7-6 15:51 | 只看该作者
原帖由 〇〇 于 2009-7-6 15:21 发表
刚刚自己编一个pro*c demo
遇到一个定点小数的问题,int放不下,double精度不保证,请教 yulihua49 怎么解决

1.可以采用decimal类型,利用ORACLE的函数库处理。
2.number类型用SQL语句处理。
3.最笨的,加权整数。比如,钱以分为单位,除法写一个带四舍五入的函数。
比如,重量以吨为单位,小数点后两位,你就可以以0.01吨为单位的整数。输入输出时进行一点小小的变换即可。

使用道具 举报

回复
论坛徽章:
0
390#
发表于 2009-7-6 15:59 | 只看该作者
原帖由 〇〇 于 2009-7-5 21:01 发表
J2EE基础应用:J2EE中SQL语句自动构造方法  

发布时间:2009.07.03 04:35     来源:赛迪网    作者:fen

【赛迪网技术社区整理】INSERT、DELETE、UPDATE 三种SQL语句是数据库技术的三大基本语句. 在通常的web开发中对它的处理可以说是无处不在. 如果简单的都用手工来构造这些SQL语句的话, 一方面给我们的开发带来很大的工作量, 另一方面系统灵活性受到很大的限制. 那么能不能基于某种规则让系统自动从页面表单中取出元素构造出SQL语句呢? 首先让我们看看一般INSERT、DELETE、UPDATE 三种语句的基本形式:

INSERT INTO table_name (col_1,col_2,col_3,) VALUES (value_1,value_2,value_3 …)

DELETE FROM table_name WHERE col_n=value_n

UPDATE table_name SET col_1=value_1,col_2=value_2,col_3=value_3 WHERE col_x=value_x



是啊,多年来,程序员们都在绞尽脑汁解决SQL语句的自动生成问题。各种方案都有局限性。
他这个方案受限制比较多,效率也比较低。
我这个方案受限制比较少,效率很高,封装比较严,几乎看不到SQL语句。

还有,JAVA bean 无法支持直接bind,因为它那个bean不允许别人直接访问变量,只能通过存取函数进行。间接bind变量效率至少下降50%。


你前边JAVA带bind的例子都是bind已知变量的。如何bind未知变量?未知对象的变量?

DAU自动生成带bind的SQL语句,包括select、insert,update,delete语句。

[ 本帖最后由 yulihua49_cu 于 2009-7-6 16:23 编辑 ]

使用道具 举报

回复

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

本版积分规则 发表回复

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