【问题标题】:How to pass cursor or list of records to java procedure in pl/sql?如何将游标或记录列表传递给 pl/sql 中的 java 过程?
【发布时间】:2020-02-22 17:51:34
【问题描述】:

我想知道如何实现以下逻辑:

CREATE TABLE STUDENT ( 
   STUDENT_ID       NUMBER (5)      NOT NULL, 
   NAME             VARCHAR2 (255)  NOT NULL, 
   SURENAME         VARCHAR2 (255)  NOT NULL,        
   BIRTH_DATE       DATE            NOT NULL, 
   PRIMARY KEY (STUDENT_ID) 
)

然后假设通过调用PL/SQL过程找到相似的学生:

CREATE OR REPLACE PROCEDURE findStudentByName(p_name IN STUDENT.NAME%TYPE, c_student OUT SYS_REFCURSOR)
           IS
  BEGIN
       OPEN c_student FOR
       SELECT * FROM STUDENT WHERE NAME LIKE p_name || '%';
  END;
  /

然后……

DECLARE 
    c_student SYS_REFCURSOR;
    temp_student STUDENT%ROWTYPE;
BEGIN
  -- records are assign to cursor 'c_student' after calling findStudentByName procedure
  findStudentByName('John',c_student);

    LOOP
       --fetch cursor 'c_student' into STUDENT table type 'temp_student'
       FETCH c_student INTO temp_student;

       -- exit if no more records
       EXIT WHEN c_student%NOTFOUND;

       -- call java procedure the matched name
       -- HOW CAN I PASS ARRAY OF STUDENT%ROWTYPE to java procedure?

    END LOOP;
    CLOSE c_student;
END;
/

我的问题是如何将 ARRAY of records 传递给 java 程序

【问题讨论】:

  • 签出this
  • Java 程序在哪里?它是使用LOADJAVA utility 加载到数据库中还是使用CREATE JAVA 编译到数据库中,还是在数据库外部?
  • @VBokšić 所以你建议使用create or replace type student_rows as table of STUDENT%ROWTYPE; 而不是光标,不是吗?
  • @MT0 当然可以!

标签: java oracle plsql oracle11g


【解决方案1】:

您需要以 Oracle 格式或标准 JDBC 可调用语句语法将存储过程作为查询字符串调用。

不需要最后一个以DECLARE ..开头的代码块,使用存储过程findStudentByname就足够了。

更喜欢使用REGEXP_LIKE

OPEN c_student FOR SELECT * FROM STUDENT WHERE REGEXP_LIKE(NAME,p_name,'i')

针对 SQL 语句的区分大小写问题。

Oracle 格式

private void findStudent(String name)
 throws SQLException {
    String qry = "begin ? := findStudentByName(?); end;";
    //presuming you already constructed an Oracle connection such as
    // Class.forName("oracle.jdbc.OracleDriver");
    //con = DriverManager.getConnection("jdbc:oracle:thin:@//"+dbname,uname,passwd); 
    CallableStatement stmt = con.prepareCall(qry);

    // the out parameter should be registered as Oracle specific type
    stmt.registerOutParameter(1, OracleTypes.CURSOR);

    stmt.setFloat(2, name); //pass your filtering parameter

    // execute and retrieve the result set
    stmt.execute();
    ResultSet rs = (ResultSet)stmt.getObject(1);

    // print out the results
    while (rs.next()) {
     System.out.println("STUDENT_ID : "+rs.getLong(1));
     System.out.println("NAME : "+rs.getString(2));
     System.out.println("SURNAME : "+rs.getString(3));
     System.out.println("BIRTH_DATE : "+rs.getDate(4));
   }

   rs.close();
   stmt.close();
}

通过JDBC语法

private void findStudent(String name)
 throws SQLException {
    String qry = "{ call ? := findStudentByName(?) }";
    CallableStatement stmt = con.prepareCall(qry);

    stmt.registerOutParameter("out_crs", OracleTypes.CURSOR);    
    stmt.setFloat("in_st_name", name); 

    stmt.execute();
    ResultSet rs = (ResultSet)stmt.getObject("out_crs");

    while (rs.next()) {
     System.out.println("STUDENT_ID : "+rs.getLong("student_id"));
     System.out.println("NAME : "+name);
     System.out.println("SURNAME : "+rs.getString("surname"));
     System.out.println("BIRTH_DATE : "+rs.getDate("birth_date"));
   }

   rs.close();
   stmt.close();
}

【讨论】:

    猜你喜欢
    • 2019-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多