如何在过程中使用返回 Oracle REF_CURSOR 的函数
Posted
技术标签:
【中文标题】如何在过程中使用返回 Oracle REF_CURSOR 的函数【英文标题】:How to use function returning Oracle REF_CURSOR in a procedure 【发布时间】:2011-11-22 15:46:40 【问题描述】:我必须编写一个 Oracle 过程,它应该调用一个返回 REF_CURSOR 的 Oracle 函数。函数是这样声明的
FUNCTION "IMPACTNET"."TF_CONVERTPARA" (PARASTRING IN NVARCHAR2) RETURN SYS_REFCURSOR
AS
c SYS_REFCURSOR;
BEGIN
OPEN c FOR
SELECT SUBSTR(element, 1, INSTR(element, '|') - 1) as key,
SUBSTR(element, INSTR(element, '|') + 1, 99999) as val
FROM (
SELECT REGEXP_SUBSTR(PARASTRING, '[^;]+', 1, LEVEL) element
FROM dual
CONNECT BY LEVEL < LENGTH(REGEXP_REPLACE(PARASTRING, '[^;]+')) + 1
);
RETURN c;
END;
你能告诉我为了从我的过程中调用函数我需要写什么吗?我想将所有返回值(形成一个有两列的表格)插入到一个有理表格中。
提前谢谢你!
【问题讨论】:
【参考方案1】:类似的东西应该可以工作(显然,我猜测的是表名和列名以及您尝试实现的确切逻辑)
CREATE PROCEDURE some_procedure_name
AS
l_rc SYS_REFCURSOR := impactnet.tf_convertpara( <<some string>> );
l_key VARCHAR2(100);
l_val VARCHAR2(100);
BEGIN
LOOP
FETCH l_rc
INTO l_key, l_val;
EXIT WHEN l_rc%notfound;
INSERT INTO some_table( key_column, val_column )
VALUES( l_key, l_val );
END LOOP;
END;
正如 Ollie 指出的那样,执行 BULK COLLECT
和 FORALL
会更有效。如果您只处理几千行(因为您的函数只是解析分隔字符串中的数据,我假设您希望返回相对较少的行),性能差异可能很小。但是,如果您要处理更多数据,则差异可能会非常明显。根据 Oracle 版本和您的具体要求,您可以简化 FORALL
中的 INSERT
语句以插入记录,而不是单独列出记录中的每一列。
CREATE PROCEDURE some_procedure_name
AS
TYPE key_val_rec
IS RECORD(
key VARCHAR2(100),
val VARCHAR2(100)
);
TYPE key_val_coll
IS TABLE OF key_val_rec;
l_rc SYS_REFCURSOR := impactnet.tf_convertpara( <<some string>> );
l_coll key_val_coll;
BEGIN
LOOP
FETCH l_rc
BULK COLLECT INTO l_coll
LIMIT 100;
EXIT WHEN l_coll.count = 0;
FORALL i IN l_coll.FIRST .. l_coll.LAST
INSERT INTO some_table( key_column, val_column )
VALUES( l_coll(i).key, l_coll(i).val );
END LOOP;
END;
【讨论】:
批量收集结果然后使用 FORALL 一次性插入不是更好吗? @Ollie - 这绝对会更有效率。我追求简单而不是性能。但我采纳了您的建议并使用BULK COLLECT
发布了一个示例以上是关于如何在过程中使用返回 Oracle REF_CURSOR 的函数的主要内容,如果未能解决你的问题,请参考以下文章
如何在过程中使用返回 Oracle REF_CURSOR 的函数
如何使用 RefCursor 返回类型测试 Oracle 存储过程?