从匿名块返回游标结果
Posted
技术标签:
【中文标题】从匿名块返回游标结果【英文标题】:Return cursor results from anonymous block 【发布时间】:2013-05-08 13:30:39 【问题描述】:我有以下 SELECT ,我想将其更改为匿名块(需要像在 Java 中那样使用匿名块,并且无权访问创建的存储功能),以便将文字的使用删除到绑定变量:
SELECT IL.LAT_NUM, IL.LNGTD_NUM
FROM ITEM_LOCATION IL
WHERE IL.ITEM_ID = 294341;
我创建了两个匿名块,但无法找到如何返回两者中创建的值:
1)
DECLARE
itemID number;
latitude number;
longitude number;
BEGIN
itemID := 294341;
SELECT
IL.LAT_NUM,
IL.LNGTD_NUM,
INTO
latitude,
longitude,
FROM
ITEM_LOCATION IL
WHERE
IL.ITEM_ID = itemID ;
END;
2)
DECLARE
TYPE t_ref_cursor IS REF CURSOR;
c_cursor t_ref_cursor;
itemID number;
latitude ITEM_LOCATION.LAT_NUM%TYPE;
longitude ITEM_LOCATION.LNGTD_NUM%TYPE;
BEGIN
itemID := 294341;
OPEN c_cursor FOR
SELECT
IL.LAT_NUM,
IL.LNGTD_NUM,
FROM
ITEM_LOCATION IL
WHERE
IL.ITEM_ID = itemID ;
CLOSE c_cursor;
END;
有谁知道这两个块中的一个/两个如何像上面的 SELECT 一样返回?
【问题讨论】:
为什么不能将查询作为准备好的 statmenet 执行?在这些块中,您没有做任何不合时宜的事情。 你可以看看这个问题。 . . ***.com/questions/6455566/…. @haki - 我无权在应用程序的数据库上创建。公司的职责分离和 DBA 将无法很快实现。我想暂时修补它,直到 DBA 用准备好的语句回来。这是我认为不会花很长时间但已经成为一个真正的痛苦的事情。搜索的谷歌加载并且只能找到准备/存储功能的能力。许多文档谈论通过匿名块“返回”值,但与 DBMS_OUTPUT.put_line 相关。但这实际上并没有像 SELECT 那样返回值,它正在打印值。谢谢。 @Gordon Linoff - Pascal 试图调试块并且 DBMS_OUTPUT.put_line 工作,因为他只需要在控制台中查看数据,但我需要返回数据,就像执行了 SELECT 一样。谢谢。 @JamesGallagher:带有替换变量的 SQL Plus 脚本可以工作吗,例如SELECT IL.LAT_NUM, IL.LNGTD_NUM FROM ITEM_LOCATION IL WHERE IL.ITEM_ID = &ITEMID;
【参考方案1】:
我想变成一个匿名块...为了删除 在绑定变量中使用文字
为什么你认为你需要使用匿名块来使用绑定变量?无论如何,您的两个块仍然具有硬编码的值294341
;您的 select
在块中使用绑定变量,但每次都生成一个新块,这对您的改进有很大的改进吗?
正如@haki 几个小时前所说,您只需使用带有绑定变量的准备好的语句:
PreparedStatement pStmt = conn.prepareStatement(
"SELECT IL.LAT_NUM, IL.LNGTD_NUM :
+ "FROM ITEM_LOCATION IL "
+ "WHERE IL.ITEM_ID = ?");
pStmt.setInt(1, 294341);
... 然后执行查询并按照您可能已经处理的方式处理结果集。 (从您对 haki 评论的回复来看,您似乎将准备好的语句(这是一种 Java/JDBC 构造)与数据库中的存储过程混淆了)。
这是一个针对演示 HR
架构的 EMP
表的简单独立示例:
导入 java.sql.; 导入 java.text.; 导入 oracle.jdbc.*; 导入 oracle.jdbc.pool.OracleDataSource;
public class JamesGallagher
public static void main(String args[]) throws SQLException
Connection conn;
OracleDataSource ds = new OracleDataSource();
ds.setURL("jdbc:oracle:thin:scott/oracle@127.0.0.1:1521:orcl");
conn = ds.getConnection();
PreparedStatement pStmt = conn.prepareStatement(
"select ename, sal from emp where sal > ?");
pStmt.setInt(1, Integer.parseInt(args[0]));
ResultSet rs = pStmt.executeQuery();
while (rs.next())
System.out.println(rs.getString(1) + ": " + rs.getInt(2));
try rs.close(); catch ( Exception ex )
try pStmt.close(); catch ( Exception ex )
try conn.close(); catch ( Exception ex )
conn = null;
我可以用javac JamesGallagher.java
编译它并用java JamesGallagher 1500
执行它,它会根据绑定值打印结果:
ALLEN: 1600
JONES: 2975
BLAKE: 2850
CLARK: 2450
SCOTT: 3000
KING: 5000
FORD: 3000
【讨论】:
感谢您的帖子。我希望不要进入“为什么”,因为它是冗长的。我正在使用 Apache SOLR 并且不支持准备好的语句 (issues.apache.org/jira/browse/SOLR-1262)。匿名块也可能不起作用,但我想尝试一下......我认为它会很快检查:) 变量是为上述 S.O. 硬编码的。示例,它们不会出现在实际代码中。绑定变量的原因:普通 SELECT 中的版本计数非常高,并且使用了大量数据库的共享池(300MB)。谢谢你的评论,我确实选错了@haki :)以上是关于从匿名块返回游标结果的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Oracle 过程返回填充了 NESTED RECORD 类型的游标