我需要编写一个在表上执行一些INSERT的sproc,并根据INSERT的执行情况为每一行编译一个“状态”列表。每一行都将插入一个循环中,循环遍历一个游标,该游标为INSERT语句提供一些值。我需要返回的是一个结果集,如下所示:
FIELDS_FROM_ROW_BEING_INSERTED.., STATUS VARCHAR2
状态由INSERT如何确定。例如,如果INSERT导致DUP_VAL_ON_INDEX异常,表明存在重复行,我将STATUS设置为“Dupe”。如果一切顺利,我会将其设置为“SUCCESS”并继续下一行。
到最后,我有一个N行的结果集,其中N是执行的插入语句的数量,每行包含要插入的行的一些标识信息,以及该行的“STATUS”插入
由于我的数据库中没有表存储我想传回给用户的值,我想知道如何将信息返回给我?临时表? Oracle临时表中似乎是“全局”,不确定我是否需要全局表,是否有任何临时表在会话完成后被删除?
答案 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;
更好的方法是将输入定义为表类型而不是游标。