【问题标题】:How to use function returning Oracle REF_CURSOR in a procedure如何在过程中使用返回 Oracle REF_CURSOR 的函数
【发布时间】: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;

你能告诉我为了从我的过程中调用函数我需要写什么吗?我想将所有返回值(形成一个有两列的表格)插入到一个有理表格中。

提前谢谢你!

【问题讨论】:

    标签: oracle plsql procedure


    【解决方案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 COLLECTFORALL 会更有效。如果您只处理几千行(因为您的函数只是解析分隔字符串中的数据,我假设您希望返回相对较少的行),性能差异可能很小。但是,如果您要处理更多数据,则差异可能会非常明显。根据 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 发布了一个示例
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多