如何返回游标以及添加到每一行的新变量?

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();

【讨论】:

以上是关于如何返回游标以及添加到每一行的新变量?的主要内容,如果未能解决你的问题,请参考以下文章

使用游标

使用游标

使用游标

TSQL:有没有办法限制返回的行并计算在没有限制的情况下返回的总数(不将其添加到每一行)?

SQL游标怎么用

将多年平均列添加到每一行