简体   繁体   English

oracle plsql对行进行分块

[英]oracle plsql chunking the rows

I have a select statement which returns 0 or more rows. 我有一条选择语句,它返回0或更多行。

I'm trying to come up with a plsql proc with a cursor to produce xml output fro, all rows returned into 100 rows at a time. 我试图提出一个带有光标的plsql proc来回生成xml输出,所有行一次返回100行。 i'm doing this to chunk loo rows at a time based on requirement. 我正在根据需要一次将行排成块。

So basically my program should follow below logic 所以基本上我的程序应该遵循以下逻辑

cursor c1 is select id,code_id,code_desc from table order by id; --returns some rows  

if c1%notfound
  then return;` -- exit from procedure 
else
loop
  grab first 100 rows from select and append to a variable
  and assign it to a variable; 
  update this variable into a clob field in a table. 
  grab next 100 rows and append into a variable
  update this variable into a clob field in a table in another row;see below 
  table data 

   and so on
   and grab remaining rows and append into a variable 
   print the variable;
until no data found;
exit

I'm trying to do convert the output from select statement into xml text. 我正在尝试将select语句的输出转换为xml文本。

The output should look something like below: 输出应如下所示:

TABLE: STG_XML_DATA 表格:STG_XML_DATA

LOOP_NO(NUMBER), XML_TEXT(CLOB), ROWS_PROCESSED
1                <XML><id>1</ID><id>2</ID>..<ID>100</ID></XML>     100
2                <XML><id>101</ID><id>102</ID>..<ID>200</ID></XML> 200 
3                <XML><id>301</ID><id>102</ID>..<ID>320</ID></XML> 20

Can someone please help 有人可以帮忙吗

First of all, can you do this with a single INSERT ... SELECT statement that does what you want with reasonable performance? 首先,您可以使用单个INSERT ... SELECT语句来执行此操作吗? If you're doing a million rows, yes, breaking them up into chunks may be a good idea. 如果您要进行一百万行,是的,将它们分成几块可能是个好主意。 But if it's 100, that might be your best bet. 但是,如果是100,那可能是您最好的选择。

For your actual question, you want to use BULK COLLECT into a collection variable and possibly FORALL . 对于您的实际问题,您想使用BULK COLLECT到一个收集变量中,并可能使用FORALL So your function is going to look something like this: 因此,您的函数将如下所示:

DECLARE
    TYPE id_tt IS TABLE OF NUMBER;
    TYPE desc_tt IS TABLE OF VARCHAR2(100);
    l_ids         id_tt;
    l_code_ids    id_tt;
    l_code_descs  desc_tt;
    cursor c1 is select id,code_id,code_desc from table 
BEGIN
    OPEN c1;
    LOOP
        FETCH c1 BULK COLLECT INTO l_ids, l_code_ids, l_code_descs
        LIMIT 100;

        EXIT WHEN l_ids.COUNT = 0;

        FORALL idx IN 1..l_ids.COUNT
        INSERT [... some insert statement here ...]

        [... maybe some other processing here...]
    END LOOP;
    CLOSE c1;
END;

What you absolutely do not want to do is fetch a row, process it, fetch another row, etc. SQL is a set-oriented language, so try to operate on sets. 您绝对不希望做的是获取一行,对其进行处理,获取另一行等。SQL是一种面向集合的语言,因此请尝试对集合进行操作。 Every time you switch context from SQL to PL/SQL there is a cost and it can kill your performance. 每次将上下文从SQL切换到PL / SQL时,都会付出代价,并且会降低性能。

See: http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52plsql-1709862.html 请参阅: http : //www.oracle.com/technetwork/issue-archive/2012/12-sep/o52plsql-1709862.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM