2017-10-11 106 views
0

我有一个select语句返回0或更多行。oracle plsql分块行

我想用一个游标想出一个plsql proc来产生xml输出,所有行一次返回100行。我这样做是为了根据需求在一段时间内分块排列。

所以基本上我的程序应遵循以下逻辑

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 

我试图做的SELECT语句的输出转换成XML文本。

输出应该类似于下面:

表: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 

能有人帮

+0

你为什么在同一时间试图只处理100行?你能澄清你的行看起来像什么,或“追加到变量”看起来像什么?例如,您可以将行存储在PL/SQL集合中,但这并不能让它们更容易打印。 – kfinity

+0

我只是试图将行100分段,并将其追加到可以存储到表中的变量中,而不一定要打印。我工作生成一些XML模式文本。从这个select语句返回的值将被用于将其追加到clob_column中。 – user1751356

+0

在这里阅读一些关于使用游标的非常有用的信息,特别是限制您想要执行的检索行以及如何正确知道何时到达结尾(而不是使用NOTFOUND!):http:// www。 oracle.com/technetwork/issue-archive/2008/08-mar/o28plsql-095155.html –

回答

0

首先,你可以用一个INSERT做到这一点... SELECT声明以合理的表现完成你想要的事情?如果你做了一百万行,是的,把它们分成大块可能是一个好主意。但如果它是100,那可能是你最好的选择。

对于您的实际问题,您希望将BULK COLLECT用于收集变量,并可能使用FORALL。所以,你的功能将会是这个样子:

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; 

什么,你绝对不想做的就是读取行,进行处理,提取另一行,等等SQL是一种面向集合的语言,所以尽量在套上操作。每当你将上下文从SQL切换到PL/SQL时,都会产生成本,并可能导致性能下降。

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

+0

嗨Eaolson,非常感谢您的帮助。我目前坚持了解如何处理游标中的下一组行。可以说如果游标没有返回任何行,那么程序应该正常退出,但是如果游标有220行,那么根据你的程序,前100行将在循环中被处理。下一组行如何?我很明白这一点。请帮忙! – user1751356

+0

它在LOOP ... END LOOP结构中,对吧?这将重复,直到EXIT子句为真,每次处理100行。 – eaolson