如何在过程中使用返回 Oracle REF_CURSOR 的函数

发布于 2024-12-17 08:53:31 字数 707 浏览 1 评论 0原文

我必须编写一个 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;

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

先感谢您!

I have to write an Oracle procedure which should invoke an Oracle function returning REF_CURSOR. The function is declared like that

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;

Can you tell me what I need to write in order to invoke the function from within my procedure? I'd like to insert all the returned values (shaped a table with two columns) into a rational table.

Thank you in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白鸥掠海 2024-12-24 08:53:32

类似的事情应该有效(显然,我猜测表名和列名以及您要实现的确切逻辑)

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;

Something along the lines of this should work (obviously, I'm guessing about table names and column names and the exact logic that you're trying to implement)

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;

As Ollie points out, it would be more efficient to do a BULK COLLECT and a FORALL. If you're just dealing with a few thousand rows (since your function is just parsing the data in a delimited string, I'm assuming you expect relatively few rows to be returned), the performance difference is probably minimal. But if you're processing more data, the difference can be quite noticeable. Depending on the Oracle version and your specific requirements, you may be able to simplify the INSERT statement in the FORALL to insert a record rather than listing each column from the record individually.

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文