如何在pl / sql过程中使用游标返回多行多列?

时间:2018-08-14 13:53:32

标签: oracle plsql procedure

我正在尝试编写一个过程(在PL / SQL中),以返回在特定日期之间注册课程的用户。将有2个输入(date1,date2)和3个输出(enrollno,error_code和enroll_date)。我希望它显示在date1和date2之间注册的多行用户的信息。这是我第一次编写过程,我能够以一种可以返回一行的方式来编写它。但是由于这些日期之间可能有许多用户注册,因此我想显示很多行。我看到我可以使用sys_refcursor,但是我做不到。互联网上的示例大多是针对一种输出过程的,因此我无法将其改编为我的示例。

例如,我在https://oracle-base.com/articles/misc/using-ref-cursors-to-return-recordsets处查看了示例,但我对声明语句感到困惑。

编辑:我打算从Java代码中调用此过程,并将返回的结果分配给某些内容,并且不允许在数据库中添加新表。

这是我的程序:

create or replace procedure display_users(pi_date1       in date,
                                          pi_date2       in date,
                                          po_enrollno    out number,
                                          po_error_code  out varchar2,
                                          po_enroll_date out date) is
  cursor user_display is
    select u.enrollno, u.error_code, u.enroll_date,
      from user_table u
     where u.enroll_date between pi_date1 and pi_date2;

begin
  open user_display;
  loop
    fetch user_display
      into po_enrollno, po_error_code, po_enroll_date;
    EXIT WHEN user_display%notfound;

  end loop;
  close user_display;

end;

2 个答案:

答案 0 :(得分:1)

您可以使用单个result = [] # datetime object list resultS = [] # dates converted in strings list tipo = [] # verifying boolean list oid = [] # object ids list resultF = [] oidF = [] verifTCRA = False # Keep the most recent dates and the type of data (if is TCRA or not) with da.SearchCursor(fc, (campos), expressao) as sCursor2: for row in sCursor2: row0temp = row[num_campo1] row1temp = row[num_campo2] row2temp = row[num_campo3] if row0temp == None: row0temp = dataInicDt if row1temp == None: row1temp = dataInicDt if row2temp == None: row2temp = dataInicDt if ((row0temp > row1temp) and (row0temp > row2temp)): resultS.append(str(row[num_campo1])) result.append(row[num_campo1]) tipo.append(False) oid.append(row[num_campo4]) elif ((row1temp > row0temp) and (row1temp > row2temp)): resultS.append(str(row[num_campo2])) result.append(row[num_campo2]) tipo.append(False) oid.append(row[num_campo4]) elif ((row2temp > row0temp) and (row2temp > row1temp)): resultS.append(str(row[num_campo3])) result.append(row[num_campo3]) tipo.append(True) oid.append(row[num_campo4]) MaxDat1 = max(result) # Biggest date of an AIA/NIS without TCRA # If there is TCRA data, keeps in another list for i in range(cont1): if tipo[i]: resultF.append(result[i]) oidF.append(oid[i]) verifTCRA = True if verifTCRA: MaxData2 = max(resultF) # TCRA with biggest data in AIA/NIS contInt = 0 MaxDat1S = str(MaxDat1) # Keeps the object id of the data with the biggest date (tcra has priority) if verifTCRA: for row in resultF: if row[0] == MaxData2: regCorr = oidF[contInt] contInt += 1 else: for row in resultS: #row0dt = dt.datetime.strptime(row[0], "%Y-%m-%d %H:%M:%S") if (row[0] == MaxDat1S): regCorr = oid[contInt] contInt += 1 out参数,而不要使用多个out参数。

REFCURSOR

这可以在Java中轻松使用,以获取此链接中所示的记录:

Using oracle ref cursors in java

答案 1 :(得分:0)

如果只是尝试将其输出到屏幕,则可以在循环的每次迭代中使用dbms_output.put_line,并确保在运行代码时在环境中“将serveroutput设置为开”。如果需要,还可以将它们串联成一行,每行输出。

dbms_output.put_line('Enrolled No: ' || to_char(po_enrollno));
dbms_output.put_line('Error Code: ' || po_error_code);
dbms_output.put_line('Enrolled Date: ' || to_char(po_enroll_date));

如果您想收集数据以备后用,则需要将记录插入到您创建的新表中。我们将其称为临时表,并且您需要确保在开始之前从表中删除所有记录。

insert into my_temp_table values( po_enrollno, po_error_code, po_enroll_date);