如何返回游标以及添加到每一行的新变量?
Posted
技术标签:
【中文标题】如何返回游标以及添加到每一行的新变量?【英文标题】:how to return a cursor along with new variable added to each row? 【发布时间】:2016-08-18 16:44:23 【问题描述】:我想从 java 中调用一个过程。
Example:
CREATE OR REPLACE PROCEDURE helloworld
AS
cursor data_test is
with required_data as( select *
from EMPLOYEES) select * from required_data rd join DEPARTMENTS d on d.department_id=rd.DEPARTMENT_ID ;
emp_rec data_test%ROWTYPE;
more_detail varchar2(50);
BEGIN
open data_test;
LOOP
FETCH data_test INTO emp_rec;
exit when data_test%NOTFOUND;
more_detail =BLA.GET_MORE_DATA(data_test.empid);// Lets say the fuction return varchar2 I've total of 4 similar fields to be added in total
END LOOP;
END;
/
现在如何返回所有 游标(data_test)中的数据以及每行中的 more_detail?即我希望我在 java 中的 ResultSet 具有 select 语句中的所有值以及 more_detail 的值。我的 helloworld 也会有 SYS_REFCURSOR 或其他参数吗?当从 java 调用时,我要做的就是创建一个可调用语句并将 out 参数注册为 Cursor 以使用它?
【问题讨论】:
手册中有一些例子展示了如何通过 JDBC 返回结果集。此外,在您的存储过程结束后,结果集将位于最后一行之后,因此它实际上是无用的。您可能想要的是在光标的SELECT
列表中调用GET_MORE_DATA()
。
@mustaccio 你能指出我的参考例子吗?我还搜索了从光标调用函数,但该函数将 empId 作为输入参数以及来自部门的一些值,而且我将如何连续添加它?
@mustaccio 我在想的是,除了光标作为输出参数,我还可以发送一个关联数组,其中键作为我的 empid,值作为我从 GET_MORE_DATA 获得的任何值。现在如何使用 JDBC 在 java 中检索这些值?我应该对此提出一个新问题还是什么?
您是否必须为此使用PROCEDURE
?根据现在显示的内容,您可能可以在使用 Statement.executeQuery()
调用的单个 SELECT
中执行相同的操作,然后根据需要在 Java 中处理结果。
@MickMnemonic 是的。我必须。 :(
【参考方案1】:
好吧,当我今天看它时,我怎么会问这个问题。这太不对劲了。 那时我对PLSQL了解不多,没看多就问了这个问题。无论如何,有很多方法可以解决它,正如我在评论中提到的,可以发回一个关联数组,但如果你不知道预期结果的数量,那在 java 方面会很痛苦。或者可以使用具有定义对象的用户创建一个嵌套数组,如下所示:
CREATE OR REPLACE TYPE keyvalue AS object (col Number(10), col2 VARCHAR2(30));
CREATE OR replace TYPE map IS TABLE OF keyvalue ;
听我说是怎么做的。您不能向光标添加列,但可以创建自己的自定义数据类型。
CREATE OR REPLACE TYPE dbObject AS OBJECT
(
empId NUMBER (6),// here add as many fields you want to return or want your object to have
emailId VARCHAR2 (25),
hiredate DATE
);
CREATE OR REPLACE TYPE datalist IS TABLE OF DBOBJECT;
PROCEDURE get_emp_data (list OUT datalist)
AS
CURSOR emp_cursor
IS
SELECT employee_id AS empId,
EMPLOYEES.EMAIL AS emailId,
EMPLOYEES.HIRE_DATE AS hiring
FROM EMPLOYEES;
c_datatype emp_cursor%rowtype;
BEGIN
OPEN emp_cursor();
list := datalist();
LOOP
fetch emp_cursor into c_datatype;
EXIT WHEN emp_cursor%NOTFOUND;
list.extend;
list(emp_cursor%ROWCOUNT):=DBOBJECT(c_datatype.empId,c_datatype.emailId,c_datatype.hiring);
END LOOP;
END get_emp_data;
现在你想从 java 中调用它:这里是代码:
String dataTypeName = "DBOBJECT";
String dataTypeListName = "datalist";
StructDescriptor structDescriptor = StructDescriptor.createDescriptor(dataTypeName.toUpperCase(), connection);
ResultSetMetaData metaData = structDescriptor.getMetaData();
CallableStatement cs = connection.prepareCall("call TEST_PACKAGE.get_emp_data(?)");
cs.registerOutParameter(1, OracleTypes.ARRAY, dataTypeListName.toUpperCase());
cs.execute();
Object[] data = (Object[]) ((Array)cs.getObject(1)).getArray();
for(Object tmp : data)
Struct row = (Struct) tmp;
int index = 1;
for(Object attribute : row.getAttributes())
System.out.println(metaData.getColumnName(index) + " : " + attribute);
++index ;
cs.close();
【讨论】:
以上是关于如何返回游标以及添加到每一行的新变量?的主要内容,如果未能解决你的问题,请参考以下文章