将REF CURSOR返回到过程生成的数据

时间:2011-01-03 21:45:15

标签: oracle stored-procedures plsql

我需要编写一个在表上执行一些INSERT的sproc,并根据INSERT的执行情况为每一行编译一个“状态”列表。每一行都将插入一个循环中,循环遍历一个游标,该游标为INSERT语句提供一些值。我需要返回的是一个结果集,如下所示:

FIELDS_FROM_ROW_BEING_INSERTED.., STATUS VARCHAR2

状态由INSERT如何确定。例如,如果INSERT导致DUP_VAL_ON_INDEX异常,表明存在重复行,我将STATUS设置为“Dupe”。如果一切顺利,我会将其设置为“SUCCESS”并继续下一行。

到最后,我有一个N行的结果集,其中N是执行的插入语句的数量,每行包含要插入的行的一些标识信息,以及该行的“STATUS”插入

由于我的数据库中没有表存储我想传回给用户的值,我想知道如何将信息返回给我?临时表? Oracle临时表中似乎是“全局”,不确定我是否需要全局表,是否有任何临时表在会话完成后被删除?

2 个答案:

答案 0 :(得分:2)

如果您使用的是Oracle 10gR2或更高版本,则应检查DML错误日志记录。这基本上可以实现您想要实现的目标,也就是说,它允许我们通过记录任何错误并按下语句来批处理中执行所有DML。

原则是我们使用PL / SQL内置包DBMS_ERRLOG为我们需要使用的每个表创建一个ERROR LOG表。 Find out more。 DML语法有一个简单的扩展,用于将消息记录到错误日志表中。 See an example here。此方法不会创建比您的提议更多的对象,并且具有使用某些标准Oracle功能的优点。

使用批量处理时(即使用FORALL语法时),我们可以使用内置的SQL%BULK_EXCEPTIONS集合捕获异常。 Check it out。可以将批量异常与DML错误记录相结合,但这可能会在11g中产生问题。 Find out more.

答案 1 :(得分:1)

临时表中的“全局”只意味着它们是永久性的,这是暂时的数据。

我会定义一个与光标匹配的记录类型,以及状态字段。然后定义该类型的表。

TYPE t_record IS
(
    field_1,
    ...
    field_n,
    status VARCHAR2(30)
);

TYPE t_table IS TABLE OF t_record;

FUNCTION insert_records
(
    p_rows_to_insert IN SYS_REFCURSOR
)
    RETURN t_table;

更好的方法是将输入定义为表类型而不是游标。