如何将集合提供给游标参数?

时间:2014-05-16 15:38:54

标签: oracle collections plsql cursor

请在代码中找到rc1。我想将v_TeminatKayit集合返回到此光标。我该怎么办?

这不起作用;

 OPEN RC1 FOR
 SELECT *
   FROM TABLE(CAST(v_TeminatKayit AS t_TeminatTip));

这不起作用?如何将收集作为光标作为out参数返回!?3

 CREATE OR REPLACE PROCEDURE KRD_SEL_GNAKDIRISKDETAY_SP
    (
       p_MusteriNo IN NUMBER DEFAULT 0,
       RC1         IN OUT SYS_REFCURSOR,
       RC2         IN OUT SYS_REFCURSOR
    ) AS
       v_RCRTeminat       SYS_REFCURSOR;
       v_UrunAdi          VARCHAR2(80);
       v_RiskTutar        NUMBER(26, 2);
       v_GNakdiRiskToplam NUMBER(26, 2) := 0;
       v_KullandirimTarih DATE;
       v_Vade             DATE;
       v_Muhatap          VARCHAR2(300);
       v_Konu             VARCHAR2(600);
       TYPE t_TeminatTip IS RECORD(
          v_urunAdi   VARCHAR2(80),
          v_mektupTtr NUMBER(26, 2),
          v_mektupTar DATE,
          v_kkrVade   DATE,
          v_muhatap   VARCHAR2(300),
          v_konu      VARCHAR2(600));

       TYPE t_TeminatBilgi IS TABLE OF t_TeminatTip INDEX BY BINARY_INTEGER;
       v_TeminatKayit t_TeminatBilgi;

    BEGIN
       BEGIN
          KRD_SEL_TEMINATMEKTUPRISK_SP(p_MusteriNo => p_MusteriNo, RC1 => v_RCRTeminat);
          IF v_RCRTeminat%ISOPEN THEN
             FETCH v_RCRTeminat BULK COLLECT
                INTO v_TeminatKayit;

          END IF;
       -- how can I serve the collection to cursor parameter ?
          OPEN RC1 FOR
             SELECT *
               FROM TABLE(CAST(v_TeminatKayit AS t_TeminatTip));


       EXCEPTION
          WHEN OTHERS THEN
             raise_application_error(-20101, '');
       END;

    END KRD_SEL_GNAKDIRISKDETAY_SP;

1 个答案:

答案 0 :(得分:1)

您正在尝试将未知数量的数据提取到内存中,以便您可以使用它,这不是PL / SQL中常见的编程习惯。在一个小型数据库中,这可能没问题 - 但是让我们想象您的数据库是一个BIG数据库,并且您正在使用BIG数据,并且打开一个返回1亿行的查询,而没有意识到返回集将有多大然后,然后你尝试将其收集到一个内存中。如果你很幸运,这一切都会导致你的进程崩溃。如果你不太幸运,你可能会导致数据库实例失败,这可能会让DBA非常非常不满。如果你真的有一个糟糕的一天,你可以关闭服务器,虽然从远处观看可能是有趣的,当你接近行动通常没有多少乐趣 - 尤其当三个DBA,两个系统管理员和一个红脸的经理突然出现在你的小隔间时喊道:“你做了什么?!?!?!?”。真的,这不好玩。不要问我怎么知道...: - }

如果你想从这个例程中返回一个光标,最好的办法就是重写你的例行程序来做到这一点:

CREATE OR REPLACE PROCEDURE KRD_SEL_GNAKDIRISKDETAY_SP
  (
  p_MusteriNo IN NUMBER DEFAULT 0,
  RC1         IN OUT SYS_REFCURSOR,
  RC2         IN OUT SYS_REFCURSOR
  )
AS
BEGIN
  BEGIN
    KRD_SEL_TEMINATMEKTUPRISK_SP(p_MusteriNo => p_MusteriNo, RC1 => RC1);
  EXCEPTION
    WHEN OTHERS THEN
      raise_application_error(-20101, '');
  END;
END KRD_SEL_GNAKDIRISKDETAY_SP;

似乎KRD_SEL_TEMINATMEKTUPRISK_SP足以让你打开光标 - 所以你已经完成了。然后,KRD_SEL_GNAKDIRISKDETAY_SP的调用者应该以适当的方式从光标(它们将要做什么,对吧?)读取。

祝你好运。

分享并享受。