• 关于 oracle 存储游标 的搜索结果

问题

myBatis 调用oracle存储过程报错?报错

爱吃鱼的程序员 2020-06-22 13:28:56 0 浏览量 回答数 1

回答

目前看也很多,还在努力弥补。首先,数据库自身对MySQL绝大部分常用用法是兼容了,但是对Oracle还只是兼容了标准SQL和一些常用函数(包括窗口函数)。当然存储过程、游标、更多的分析函数内部也实现了,还需要一段时间检验。传统Oracle数据库上的那复杂的存储过程和package目前在OceanBase里运行还可能有性能问题。内部业务正在试用过程中。其次,OceanBase的外部用户很少,了解的人很少,相关资料仅限于OceanBase官网和OceanBase论坛,还有微信公众号和群。所以不大容易得到用户信任。这个会有个很长的过程。 第三就是对机器配置要求不低。如至少32C64G(更小也可以搭建集群,但使用不当容易有问题),生产环境建议256G等。生产环境这个配置不算什么,不过个人如果要安装搭一个测试环境,可能不大好搞到机器。OceanBase的资源瘦身我们也在做了,还需要点时间。

茶什i 2019-12-02 03:18:56 0 浏览量 回答数 0

回答

咋没人回复呢 不要用任何和ORM相关的封装 所有ORM相关的封装,都是根据mysql来封装的 mysql不是数据库 所以任何的ORM都不能完整的支持数据库的操作楼主提到的是你最钟爱的Oracle,你是不是反应过激了,呵呵 回复<aclass='referer'target='_blank'>@xmut: 正是因为用了oracle或者其他任何真正的数据库 都会被这些框架困扰。  这些数据库框架的设计者,基本上都被mysqlFK过了。 <divclass="ref"> 引用来自“宏哥”的答案<divclass=ref_body> 不要用任何和ORM相关的封装 所有ORM相关的封装,都是根据mysql来封装的 mysql不是数据库 所以任何的ORM都不能完整的支持数据库的操作 1.找到异常的存储过程。在数据库端执行。看会不会报异常。 2.如果1返回true.那么你再检查。你用来接收的类型是什么类型.<至少是一个集合类型> 原因不用我多少了吧..   自己检查下. 我在接收map里面给的类型是CURSOR,当存储过程中游标从来没开启过时,mybatis读取返回值是就出错了。

爱吃鱼的程序员 2020-06-22 13:29:15 0 浏览量 回答数 0

新手开公司,教你化繁为简

开公司到底有没有那么难,传统的手续繁琐,线下跑断腿,场地搞不定等问题,通过阿里云”云上公司注册“解决你的烦恼。

问题

【精品问答】数据库面试总结50问

茶什i 2019-12-01 21:57:36 221 浏览量 回答数 0

问题

大型企业CRM请求技术支持帮助

匆匆程序员 2019-12-01 21:37:24 5069 浏览量 回答数 3

回答

后台传入变量a update from table set columnB=a  where columnB==""  order by columnA 循环操作这条sql,a从0开始 ######问问题都不能描述清楚 就别指望有人回答了######回复 @布尔道长 : +1######“这样规律的数据怎样用sql更新 “更新成什么? ”为空的columnB列,其中A列可能会有N条数据是一样的,但B列必须是从0开始递增 ”这是在说什么?######那么清析的表结构都理解不了?###### 引用来自“谭书记”的答案 后台传入变量a update from table set columnB=a  where columnB==""  order by columnA 循环操作这条sql,a从0开始 后台如何传入变量a? ######回复 @kylerho : oracle中可以用序列来实现你的自动增长。你自己试下,我提供一份简码: CREATE SEQUENCE my_seq START WITH 1 INCREMENT BY 1 MAXVALUE 100 ; (表示创建序列,从0开始,每次+1,最大值100) 然后调用我上面的sql,把a换成my_seq.nextval######回复 @谭书记 : 存储过程不太熟,试过用游标,写的有点不太正确######回复 @kylerho : 那就写个简单的存储过程吧,呵呵。还是变量一说。######回复 @谭书记 : 呵呵~~ 如果是程序操作的,我就不用在这问了,那是要在oracle中操作的######哦,我这可能是mybatis的思想。。oracle不知道适用不,看你使用的是什么orm框架,呵呵。。那你把a用oracle中的特殊函数替代下,比如自动增长的函数(不知道有木有)######使用窗口函数就OK######select columna, row_number() over(partition by columna order by columna)  - 1 columnb from t######回复 @kylerho : 修改了######回复 @kylerho : 晕,外面再嵌套一层减一会不######这个能从0开始的吗?######或者直接######在别名前减一就可以了######已经解决了,就在别名前减一,谢了

kun坤 2020-06-15 11:08:10 0 浏览量 回答数 0

回答

我的做法是: 1、写一个过程调用类,实现ICallback接口,完整代码如下: import java.sql.CallableStatement; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import oracle.jdbc.OracleTypes; import com.jfinal.plugin.activerecord.ICallback; import com.jfinal.plugin.activerecord.Model; import com.jfinal.plugin.activerecord.ModelBuilder; /** * 统计分析数据 * @author Administrator * */ public class ProcedureTool implements ICallback { private Object[] paras; private String procedure; private List<?> result; @SuppressWarnings("rawtypes") private Class<? extends Model> mdClass; /** * @param proc 存储过程名称及参数:如 prcName(?,?,?,?) * @param paras 输入\输出 参数,默认最后一个为游标参数 */ @SuppressWarnings("rawtypes") public void setParas(Class<? extends Model> modelClass,String proc,Object...paras){ procedure=proc; this.paras=paras; mdClass=modelClass; } /** * 结果集 * @return */ public List<?> getResultList(){ return result; } @Override public Object run(Connection conn) throws SQLException { // TODO Auto-generated method stub CallableStatement proc = null; result=null; proc = conn.prepareCall("{ call "+procedure+" }"); for (int i=0; i<paras.length; i++) { proc.setObject(i + 1, paras[i]); } proc.registerOutParameter(paras.length+1, OracleTypes.CURSOR); proc.execute(); ResultSet rs = (ResultSet) proc.getObject(paras.length+1); try { result=ModelBuilder.build(rs, mdClass); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } 2、调用getResultList就可以得到结果集了。 以上就是大概思路 南客南客 9个月前引用来自“车开源”的评论我的做法是: 1、写一个过程调用类,实现ICallback接口,如下: public class ProcedureTool implements ICallback { private Object[] paras; private String procedure; private List<?> result; @SuppressWarnings("rawtypes") private Class<? extends Model> mdClass; /** * @param proc 存储过程名称及参数:如 prcName(?,?,?,?) * @param paras 输入\输出 参数,默认最后一个为游标参数 */ @SuppressWarnings("rawtypes") public void setParas(Class<? extends Model> modelClass,String proc,Object...paras){ procedure=proc; this.paras=paras; mdClass=modelClass; } /** * 结果集 * @return */ public List<?> getResultList(){ return result; } @Override public Object run(Connection conn) throws SQLException { // TODO Auto-generated method stub CallableStatement proc = null; result=null; proc = conn.prepareCall("{ call "+procedure+" }"); for (int i=0; i<paras.length; i++) { proc.setObject(i + 1, paras[i]); } proc.registerOutParameter(paras.length+1, OracleTypes.CURSOR); proc.execute(); ResultSet rs = (ResultSet) proc.getObject(paras.length+1); try { result=ModelBuilder.build(rs, mdClass); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } 2、调用getResultList就可以得到结果集了。

小旋风柴进 2019-12-02 02:05:36 0 浏览量 回答数 0

回答

当我可以在60秒内在类似硬件上执行相同操作时,您的查询要花2个小时才能执行,这是一件非常错误的事情。 以下某些内容可能会有所帮助... 为您的引擎调整MySQL 检查服务器配置并进行相应优化。以下某些资源应该是有用的。 http://www.mysqlperformanceblog.com/2006/09/29/what-to-tune-in-mysql-server-after-installation/ http://www.mysqlperformanceblog.com/ http://www.highperfmysql.com/ http://forge.mysql.com/wiki/ServerVariables http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html http://www.xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/ http://jpipes.com/presentations/perf_tuning_best_practices.pdf http://jpipes.com/presentations/index_coding_optimization.pdf http://www.jasny.net/?p=36 现在不那么明显了... 考虑使用存储过程来处理数据服务器端 为什么不处理MySQL内部的所有数据,从而不必将大量数据发送到应用程序层?以下示例使用游标在2分钟内循环和处理服务器端5000万行。我不是游标的忠实拥护者,尤其是在MySQL游标非常有限的地方,但是我猜想您会循环结果集并进行某种形式的数值分析,因此在这种情况下使用游标是合理的。 简化的myisam结果表-基于您的密钥。 drop table if exists results_1mregr_c_ew_f; create table results_1mregr_c_ew_f ( id int unsigned not null auto_increment primary key, rc tinyint unsigned not null, df int unsigned not null default 0, val double(10,4) not null default 0, ts timestamp not null default now(), key (rc, df) ) engine=myisam; 我生成了1亿行数据,其中关键字段的基数与您的示例大致相同: show indexes from results_1mregr_c_ew_f; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Index_type ===== ========== ======== ============ =========== ========= =========== ========== results_1mregr_c_ew_f 0 PRIMARY 1 id A 100000000 BTREE results_1mregr_c_ew_f 1 rc 1 rc A 2 BTREE results_1mregr_c_ew_f 1 rc 2 df A 223 BTREE 存储过程 我创建了一个简单的存储过程,该过程将获取所需的数据并对其进行处理(使用与示例相同的where条件) drop procedure if exists process_results_1mregr_c_ew_f; delimiter # create procedure process_results_1mregr_c_ew_f ( in p_rc tinyint unsigned, in p_df int unsigned ) begin declare v_count int unsigned default 0; declare v_done tinyint default 0; declare v_id int unsigned; declare v_result_cur cursor for select id from results_1mregr_c_ew_f where rc = p_rc and df > p_df; declare continue handler for not found set v_done = 1; open v_result_cur; repeat fetch v_result_cur into v_id; set v_count = v_count + 1; -- do work... until v_done end repeat; close v_result_cur; select v_count as counter; end # delimiter ; 观察到以下运行时: call process_results_1mregr_c_ew_f(0,60); runtime 1 = 03:24.999 Query OK (3 mins 25 secs) runtime 2 = 03:32.196 Query OK (3 mins 32 secs) call process_results_1mregr_c_ew_f(1,60); runtime 1 = 04:59.861 Query OK (4 mins 59 secs) runtime 2 = 04:41.814 Query OK (4 mins 41 secs) counter 23000002 (23 million rows processed in each case) 嗯,性能有些令人失望,因此进入下一个想法。 考虑使用innodb引擎(令人震惊的恐怖) 为什么是innodb?因为它具有聚簇索引!您会发现使用innodb的插入速度较慢,但​​希望读取速度会更快,因此这是值得的折衷选择。 通过聚集索引访问行的速度很快,因为行数据位于索引搜索所位于的同一页上。如果表很大,则与使用不同于索引记录的页面存储行数据的存储组织相比,聚集索引体系结构通常可以节省磁盘I / O操作。例如,MyISAM将一个文件用于数据行,将另一个文件用于索引记录。 更多信息在这里: http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html 简化的innodb结果表 drop table if exists results_innodb; create table results_innodb ( rc tinyint unsigned not null, df int unsigned not null default 0, id int unsigned not null, -- cant auto_inc this !! val double(10,4) not null default 0, ts timestamp not null default now(), primary key (rc, df, id) -- note clustered (innodb only !) composite PK ) engine=innodb; innodb的一个问题是它不支持构成复合键一部分的auto_increment字段,因此您必须自己使用序列生成器,触发器或其他方法(可能是在填充结果表本身的应用程序中)提供递增的键值?? 同样,我生成了1亿行数据,这些键字段的基数与您的示例大致相同。如果这些数字与myisam示例不匹配,请不要担心,因为innodb估计基数,因此它们不会完全相同。(但它们-使用相同的数据集) show indexes from results_innodb; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Index_type ===== ========== ======== ============ =========== ========= =========== ========== results_innodb 0 PRIMARY 1 rc A 18 BTREE results_innodb 0 PRIMARY 2 df A 18 BTREE results_innodb 0 PRIMARY 3 id A 100000294 BTREE 存储过程 存储过程与上面的myisam示例完全相同,但是从innodb表中选择数据。 declare v_result_cur cursor for select id from results_innodb where rc = p_rc and df > p_df; 结果如下: call process_results_innodb(0,60); runtime 1 = 01:53.407 Query OK (1 mins 53 secs) runtime 2 = 01:52.088 Query OK (1 mins 52 secs) call process_results_innodb(1,60); runtime 1 = 02:01.201 Query OK (2 mins 01 secs) runtime 2 = 01:49.737 Query OK (1 mins 50 secs) counter 23000002 (23 million rows processed in each case) 比myisam引擎实施快约2-3分钟!(innodb FTW) 分而治之 在使用游标的服务器端存储过程中处理结果可能不是最佳解决方案,尤其是因为MySQL不支持诸如数组和复杂数据结构之类的东西,而这些东西在3GL语言(如C#等)或什至在其他数据库(如作为Oracle PL / SQL。 因此,这里的想法是将成批的数据返回到应用程序层(C#等),然后可以将结果添加到基于集合的数据结构中,然后在内部处理数据。 存储过程 该存储过程需要3个参数rc,df_low和df_high,这使您可以选择以下数据范围: call list_results_innodb(0,1,1); -- df 1 call list_results_innodb(0,1,10); -- df between 1 and 10 call list_results_innodb(0,60,120); -- df between 60 and 120 etc... 显然,df范围越高,您将提取的数据越多。 drop procedure if exists list_results_innodb; delimiter # create procedure list_results_innodb ( in p_rc tinyint unsigned, in p_df_low int unsigned, in p_df_high int unsigned ) begin select rc, df, id from results_innodb where rc = p_rc and df between p_df_low and p_df_high; end # delimiter ; 我还敲出了一个myisam版本,除了所使用的表外,该版本完全相同。 call list_results_1mregr_c_ew_f(0,1,1); call list_results_1mregr_c_ew_f(0,1,10); call list_results_1mregr_c_ew_f(0,60,120); 基于上面的光标示例,我希望innodb版本的性能优于myisam版本。 我开发了一个快速且肮脏的多线程C#应用程序,该应用程序将调用存储过程并将结果添加到集合中以进行后查询处理。您不必使用线程,可以按顺序完成相同的批处理查询方法,而不会造成性能损失。 每个线程(QueryThread)选择一个df数据范围,循环结果集,并将每个结果(行)添加到结果集合中。 class Program { static void Main(string[] args) { const int MAX_THREADS = 12; const int MAX_RC = 120; List<AutoResetEvent> signals = new List<AutoResetEvent>(); ResultDictionary results = new ResultDictionary(); // thread safe collection DateTime startTime = DateTime.Now; int step = (int)Math.Ceiling((double)MAX_RC / MAX_THREADS) -1; int start = 1, end = 0; for (int i = 0; i < MAX_THREADS; i++){ end = (i == MAX_THREADS - 1) ? MAX_RC : end + step; signals.Add(new AutoResetEvent(false)); QueryThread st = new QueryThread(i,signals[i],results,0,start,end); start = end + 1; } WaitHandle.WaitAll(signals.ToArray()); TimeSpan runTime = DateTime.Now - startTime; Console.WriteLine("{0} results fetched and looped in {1} secs\nPress any key", results.Count, runTime.ToString()); Console.ReadKey(); } } 运行时观察如下: Thread 04 done - 31580517 Thread 06 done - 44313475 Thread 07 done - 45776055 Thread 03 done - 46292196 Thread 00 done - 47008566 Thread 10 done - 47910554 Thread 02 done - 48194632 Thread 09 done - 48201782 Thread 05 done - 48253744 Thread 08 done - 48332639 Thread 01 done - 48496235 Thread 11 done - 50000000 50000000 results fetched and looped in 00:00:55.5731786 secs Press any key 因此,在不到60秒的时间内获取了5000万行并将其添加到集合中。 我使用myisam存储过程尝试了同样的事情,该过程花了2分钟才能完成。 50000000 results fetched and looped in 00:01:59.2144880 secs 移至innodb 在我的简化系统中,myisam表的性能不会太差,因此可能不值得迁移到innodb。如果您确实决定将结果数据复制到innodb表中,请按照以下步骤进行操作: start transaction; insert into results_innodb select <fields...> from results_1mregr_c_ew_f order by ; commit; 在将整个事物插入并包装到事务中之前,通过innodb PK对结果进行排序将加快速度。 我希望其中一些证明是有帮助的。 祝好运

保持可爱mmm 2020-05-18 11:14:35 0 浏览量 回答数 0

回答

不同的数据库连接数据库的方式不同,但是大体分为几种:ODBC(Open Database Connectivity,开放数据库互连)是微软公司开放服务结构(WOSA,Windows Open Services Architecture)中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准API(应用程序编程接口)。这些API利用SQL来完成其大部分任务。DAO(Data Access Objects):数据访问对象是用来显露了Microsoft Jet数据库引擎(最早是给Microsoft Access 所使用,现在已经支持其它数据库),并允许开发者通过ODBC直接连接到其他数据库一样,直接连接到 Access 表。DAO 最适用于单系统应用程序或在小范围本地分布使用。其内部已经对Jet数据库的访问进行了加速优化,而且其使用起来也是很方便的。所以如果数据库是Access数据库且是本地使用的话,建议使用这种访问方式---应用的专一性RDO(Remote Data Objects)远程数据对象是一个到ODBC的、面向对象的数据访问接口,它同易于使用的DAO style组合在一起,提供了一个接口,形式上展示出所有ODBC的底层功能和灵活性。尽管RDO在很好地访问Jet或ISAM数据库方面受到限制,而且它只能通过现存的ODBC驱动程序来访问关系数据库。但是,RDO已被证明是许多SQL Server、Oracle 以及其他大型关系数据库开发者经常选用的最佳接口。RDO提供了用来访问存储过程和复杂结果集的更多和更复杂的对象、属性,以及方法。---无疑是在odbc基础上的OLE DB 是 Microsoft 的一个战略性系统级编程接口,用于管理整个组织内的数据。OLE DB 是建立在 ODBC 功能之上的一个开放规范。ODBC 是为访问关系型数据库而专门开发的,OLE DB 则用于访问关系型和非关系型信息源,例如主机 ISAM/VSAM 和层次数据库,电子邮件和文件系统存储,文本、图形和地理数据以及自定义业务对象。 OLE DB 定义了一组 COM 接口,对各种数据库管理系统服务进行封装,并允许创建软件组件,实现这些服务。OLE DB 组件包括数据提供程序(包含和表现数据)、数据使用者(使用数据)和服务组件(处理和传送数据,例如,查询处理器和游标引擎)。OLE DB 接口有助于平滑地集成组件,这样,OLE DB 组件厂商就可以快速地向市场提供高质量 OLE DB 组件。此外,OLE DB 包含了一个连接 ODBC 的“桥梁”,对现用的各种 ODBC 关系型数据库驱动程序提供一贯的支持。---号称取代odbc,但也兼容odbcADO(ActiveX Data Object)是DAO/RDO的后继产物。ADO 2.0在功能上与RDO更相似,而且一般来说,在这两种模型之间有一种相似的映射关系。ADO"扩展"了DAO和 RDO 所使用的对象模型,这意味着它包含较少的对象、更多的属性、方法(和参数),以及事件。 作为最新的数据库访问模式,ADO的使用也是简单易用,所以微软已经明确表示今后把重点放在ADO上,对DAO/RDO不再作升级,所以ADO已经成为了当前数据库开发的主流。 ADO涉及的数据存储有DSN(数据源名称)、ODBC(开放式数据连接)以及OLE DB三种方式。后面的例程将详细讲解这三种方式的具体访问实现。---可以说是对odbc,oledb这些系统级的编程接口的汇接,并对DAO,RDO这些应用级的编程接口的升级吧。

卓刀 2019-12-02 00:38:22 0 浏览量 回答数 0

问题

在Microsoft SQL Server 2000中模拟MySQL LIMIT子句

保持可爱mmm 2020-05-11 17:20:49 0 浏览量 回答数 1

问题

SSH面试题

琴瑟 2019-12-01 21:46:22 3489 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 云栖号物联网 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站 云栖号弹性计算 阿里云云栖号 云栖号案例 云栖号直播