oracle 如何使用LOOP处理PLSQL过程?

gev0vcfq  于 2023-08-04  发布在  Oracle
关注(0)|答案(2)|浏览(111)

我是PL/SQL的新手,所以我想请你帮忙。目前,我将使用PL/SQL处理一个数据库。
下面是一个数据,将进行处理。
x1c 0d1x的数据
这是我无法执行以下步骤的地方:
1.此过程将生成一个SQL语句(例如SELECT * from DB WHERE ···)

  1. SQL得到的记录将被分配给另一个变量(PL/SQL中的Cursor)。
    1.但是获取的记录超过3,000行,生成的SQL将在3,000行分配给变量(Cursor)后停止获取它们
    1.在步骤3发生之后,我们编辑SQL语句,以便在我们再次执行步骤1到步骤3时选择从第3,001条开始的记录。
    是否可以按我们希望的方式循环过程?如果是的话,你能告诉我怎么写代码吗?现在,它是如此模糊,但我可以想象下面的代码:
create or replace procedure TEST1
IS
    strCondition := “WHERE ・・・ ORDER BY ~~~”
    strSQL := “SELECT * FROM DB” + strCondition;
    a NUMBER(3000) := 1;
BEGIN
    LOOP
    (Conduct the SQL to get records until it surpasses 3,000)
        IF a <3000 THEN
            EXIT;
        END IF;
    a := a + 1;
    END LOOP;
END;

字符串
如果您能告诉我每3,000行记录的处理代码,我将不胜感激

yrwegjxp

yrwegjxp1#

也许你应该描述这个问题,而不是你认为应该解决的方式。因为,无论你想做什么,都可能有不同/更好的方法来做到这一点。
例如,为什么要反复生成select语句?我不明白你说你将把这些值赋给游标(*)是什么意思。而且,在3000行的块中做它有什么意义呢?
总之,正如最后一个问题所说
是否可以按照我们想要的方式循环过程?
这是一个选择我没有你的100.000行表,所以我将在Scott的emp表上演示它,该表包含14行,所以在一轮中我只做3行,而不是3.000行。

SQL> set serveroutput on
SQL> declare
  2    l_cnt number;  -- number of outer loop round
  3    l_str clob;    -- collect values returned in inner loop
  4  begin
  5    select ceil(count(*) / 3) into l_cnt from emp;
  6
  7    for i in 1 .. l_cnt loop
  8      for cur_r in (select ename, job
  9                    from (select ename, job,
 10                            row_number() Over (order by ename) rn
 11                          from emp
 12                         )
 13                    where rn > (i - 1) * 3
 14                    fetch first 3 rows only
 15                   )
 16      loop
 17        l_str := l_str || cur_r.ename ||'; '|| cur_r.job || chr(10);
 18      end loop;
 19      dbms_output.put_line('Round ' || i);
 20      dbms_output.put_line(l_str);
 21
 22      l_str := null;
 23    end loop;
 24  end;
 25  /

字符串
结果是

Round 1
ADAMS; CLERK
ALLEN; SALESMAN
BLAKE; MANAGER

Round 2
CLARK; MANAGER
FORD; ANALYST
JAMES; CLERK

Round 3
JONES; MANAGER
KING; PRESIDENT
MARTIN; SALESMAN

Round 4
MILLER; CLERK
SCOTT; ANALYST
SMITH; CLERK

Round 5
TURNER; SALESMAN
WARD; SALESMAN

PL/SQL procedure successfully completed.

SQL>

8yparm6h

8yparm6h2#

在Oracle 12中,创建游标并使用OFFSET x FETCH NEXT y ROWS ONLY对游标进行分页:

CREATE PROCEDURE TEST1(
  i_page   IN  NUMBER := 1,
  o_cursor OUT SYS_REFCURSOR
)
IS
BEGIN
  OPEN o_cursor FOR
    SELECT *
    FROM   db
    WHERE  something = 'true'
    ORDER BY column1
    OFFSET (i_page - 1) * 3000
    FETCH NEXT 3000 ROWS ONLY;
END;
/

字符串
当你想获得第二页(或更高)的结果时,把页码作为参数传递给过程。

相关问题