谢谢ashzs((可以包含中文字符)) !我用到的表中有两个是100万条以上的表(a和b),另一个是小表(c),原来在java中用的sql语句是这样的:select a.taskno,b.site as net,a.nodename, a.priority as isvip, a.isck, a.routeno, b.recordid, a.userid, a.tasktime, b.busitypeid, b.handlereasonid, c.checkrate from tb1 a, tb2 b, tb3 c where a.nodename = 'ck' and a.taskno like String1 || '%' and a.taskno = b.taskno and b.site = c.site and b.busitypeid = c.busitypeid and c.checkrate = '0' and rownum < 50;谢谢!
public void test_proc(){ String driver_class = "oracle.jdbc.driver.OracleDriver"; String connect_string = "jdbc:oracle:thin:@111.111.111.111:1521:orcl"; String query = "call test(?)"; Connection conn; try{ Class.forName(driver_class); conn = DriverManager.getConnection(connect_string, "user", "password"); CallableStatement cstmt = conn.prepareCall(query); cstmt.registerOutParameter(1,OracleTypes.CURSOR); cstmt.execute(); ResultSet rset = (ResultSet)cstmt.getObject(1); while (rset.next ()) System.out.println(rset.getString(1)) ; cstmt.close(); }catch( Exception e ) { // problem loading driver, class not exist? e.printStackTrace(); return; } }我的测试代码!!一点问题都没有!
to ashzs((可以包含中文字符)) : 能不能看看你的存储过程,谢谢!ps:昨晚中了病毒,到现在还没干净,郁闷!
--define ref cursor CREATE OR REPLACE PACKAGE "EPT_USER"."PKG_PUBLIC" as TYPE REF_CURSOR IS REF CURSOR; end;--out table type CREATE OR REPLACE PROCEDURE "EPT_USER"."TEST" (b out pkg_public.REF_CURSOR) as begin open b for select a from abcd;end;--my test table SQL> desc abcd 名称 是否为空? 类型 ----------------------------------------- -------- -------------------- A VARCHAR2(10) B VARCHAR2(10) SQL> select a from abcd;A ---------- 1 1 1 1 1 1 1 1 1 1 1A ---------- 1已选择12行。
哪有什么不能的? 你可以设置多个out参数不就行? 例子: CREATE OR REPLACE PROCEDURE "EPT_USER"."TEST" (b out pkg_public.REF_CURSOR,c out pkg_public.REF_CURSOR,d out pkg_public.REF_CURSOR) as begin open b for select a from abcd; open c for select a from abcd where rownum<5; --也可以用不同表! open d for select a from abcd where rownum<15;--也可以用不同表!end;这几个游标返回的都是多条记录呀!
1、如果只是想将三个大表不做任何关联,取到客户端进行操作,你可以用以前那个
贴子的方法,设置三个表变量,在java中取用。
2、如果你想从三个大表中在服务器端取出你要的查询结果,得到
结果后设置一个表变量,在java中取用。
你说到了,要提速,那么第一种方法就不行,因为在java中进行循环筛选是很慢的,
只能用第二种方法。而第二种方法就要用到表关联或用plsql进行循环。这样比较起来
表关联还是更快的!所以归结到现在,你最好的解决办法就是对你的表关联条件建立
相应的索引,使之更快!
你现在提问的方法应该是:
告诉大家你的三个表数据量大约多少,三个表要用什么条件进行连接,或直接贴出你的
sql让大家帮你优化,这才能解决你的问题呀!你看呢?
a.priority as isvip, a.isck, a.routeno, b.recordid,
a.userid, a.tasktime, b.busitypeid, b.handlereasonid, c.checkrate
from tb1 a, tb2 b, tb3 c
where a.nodename = 'ck' and a.taskno like String1 || '%'
and a.taskno = b.taskno and b.site = c.site
and b.busitypeid = c.busitypeid and c.checkrate = '0'
and rownum < 50;谢谢!
给你个例子:
import java.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
class curvar
{
public static void main (String args [])
throws SQLException, ClassNotFoundException
{
String driver_class = "oracle.jdbc.driver.OracleDriver";
String connect_string = "jdbcracle:thin:@slackdog:1521racle8"; String query = "begin :1 := sp_listEmp; end;";
Connection conn; Class.forName(driver_class);
conn = DriverManager.getConnection(connect_string, "scott", "tiger"); CallableStatement cstmt = conn.prepareCall(query);
cstmt.registerOutParameter(1,OracleTypes.CURSOR);
cstmt.execute();
ResultSet rset = (ResultSet)cstmt.getObject(1); while (rset.next ())
System.out.println( rset.getString (1) ;
cstmt.close();
}
}
注:这个例子是摘录的,并非原创!
注意到
ResultSet rset = (ResultSet)cstmt.getObject(1); while (rset.next ())
System.out.println( rset.getString (1) ;
cstmt.close();
了吗?就这么用呀!
在where子句中,尽量把b的字段放在右边,建立相应的索引。主要看看你的sql执行计划,
避免全表扫描。速度允许即可!
PLS-00382: 表达式类型错误
ORA-06550: 第 1 行, 第 7 列:
PL/SQL: Statement ignored返回表变量不能用resultset取值吧?
CallableStatement proc1 = null; proc1 = oOracleConnection.prepareCall("{ ? = call pkg.func(?) }");
proc1.registerOutParameter(1, OracleTypes.CURSOR);
proc1.setString(2, str1);
proc1.execute();
rs = (ResultSet) proc1.getObject(1);
while (rs.next())
{
System.out.println(rs.getString(1));
}
if (rs != null){
rs.close();
rs = null;
}执行“proc1.execute()”时报错!
String driver_class = "oracle.jdbc.driver.OracleDriver";
String connect_string = "jdbc:oracle:thin:@111.111.111.111:1521:orcl"; String query = "call test(?)";
Connection conn;
try{
Class.forName(driver_class);
conn = DriverManager.getConnection(connect_string, "user", "password"); CallableStatement cstmt = conn.prepareCall(query);
cstmt.registerOutParameter(1,OracleTypes.CURSOR);
cstmt.execute();
ResultSet rset = (ResultSet)cstmt.getObject(1); while (rset.next ())
System.out.println(rset.getString(1)) ;
cstmt.close();
}catch( Exception e ) { // problem loading driver, class not exist?
e.printStackTrace();
return;
}
}我的测试代码!!一点问题都没有!
CREATE OR REPLACE PACKAGE "EPT_USER"."PKG_PUBLIC" as
TYPE REF_CURSOR IS REF CURSOR;
end;--out table type
CREATE OR REPLACE PROCEDURE "EPT_USER"."TEST" (b out
pkg_public.REF_CURSOR)
as
begin
open b for select a from abcd;end;--my test table
SQL> desc abcd
名称 是否为空? 类型
----------------------------------------- -------- --------------------
A VARCHAR2(10)
B VARCHAR2(10)
SQL> select a from abcd;A
----------
1
1
1
1
1
1
1
1
1
1
1A
----------
1已选择12行。
有区别的:游标只能返回一条sql的查询结果,我是要对三个表分别查询(不用联查),然后合在一起返回,并且是多条记录,这个游标实现不了吧?
你可以设置多个out参数不就行?
例子:
CREATE OR REPLACE PROCEDURE "EPT_USER"."TEST" (b out
pkg_public.REF_CURSOR,c out pkg_public.REF_CURSOR,d out pkg_public.REF_CURSOR)
as
begin
open b for select a from abcd;
open c for select a from abcd where rownum<5; --也可以用不同表!
open d for select a from abcd where rownum<15;--也可以用不同表!end;这几个游标返回的都是多条记录呀!
通过与客户的沟通,现在我们使用临时表解决。
在此多谢ashzs((可以包含中文字符))的热心帮助!给20分。