PL/sql存储过程引用游标作为参数

PL/sql存储过程引用游标作为参数,sql,oracle,Sql,Oracle,我需要将多行传递给存储过程。我可以使用ref游标吗?因为我试过以下方法: 在我的包裹内,我有: TYPE FACT_VND_RECORD IS RECORD ( COD_NOMCPDT P6PCM2_PARMCMS.COD_NOMCPDT%TYPE, LIB_LIBNOMCPDT P6PCM2_PARMCMS.LIB_LIBNOMCPDT%TYPE, DHS_MAJ P6PCM2_PARMCMS.DHS_MAJ%TYPE, LIB_AUTH_MAJ P6P

我需要将多行传递给存储过程。我可以使用ref游标吗?因为我试过以下方法:

在我的包裹内,我有:

TYPE FACT_VND_RECORD
IS
  RECORD
  (
    COD_NOMCPDT P6PCM2_PARMCMS.COD_NOMCPDT%TYPE,
    LIB_LIBNOMCPDT P6PCM2_PARMCMS.LIB_LIBNOMCPDT%TYPE,
    DHS_MAJ P6PCM2_PARMCMS.DHS_MAJ%TYPE,
    LIB_AUTH_MAJ P6PCM2_PARMCMS.LIB_AUTH_MAJ%TYPE );

TYPE FACT_VND_CURSOR
    IS
      REF
      CURSOR
        RETURN FACT_VND_RECORD;
和2个程序:

PROCEDURE REC_FACT_VND(
      P_IN_NUM_VND   IN OUT P6PCM2_PARMCMS.NUM_VND%TYPE,
      P_OUT_FACT_VND IN OUT FACT_VND_CURSOR,
      P_OUT_CODE_RET OUT INTEGER,
      P_OUT_MSG_ERR OUT VARCHAR2);

  PROCEDURE MAJ_FACT_VND(
      P_IN_NUM_VND   IN OUT P6PCM2_PARMCMS.NUM_VND%TYPE,
      P_IN_FACT_VND IN OUT FACT_VND_CURSOR,
      P_OUT_CODE_RET OUT INTEGER,
      P_OUT_MSG_ERR OUT VARCHAR2); 
接收先前填充的光标并对数据执行某些操作

我用这两个电话;第一个工作正常,我可以看到ref游标C1内的数据,然后我尝试使用它

C1 PACK_REC_FACT_VND.FACT_VND_CURSOR;
--other definitons
      PACK_REC_FACT_VND.REC_FACT_VND(NUM_VND,C1,COD_RET,MSG_ERR);
    PACK_REC_FACT_VND.MAJ_FACT_VND(NUM_VND,C1,COD_RET,MSG_ERR);
我无法对数据进行迭代,因为它未定义: (代码来自第二个程序)


或者我应该切换到记录表吗?

我们不能像那样使用ref游标;我们需要使用显式游标语法。尝试此操作(警告:未测试的代码!):

但是,如果将记录提取到集合中,则可以获得更好的性能。大概是这样的:

        type LIGNE_TAUX_NT is table of PACK_REC_FACT_VND.FACT_VND_RECORD;
        LIGNE_TAUX_COLL LIGNE_TAUX_NT;
    BEGIN
      DELETE FROM P6PCM2_PARMCMS WHERE NUM_VND=P_IN_NUM_VND;

      fetch P_IN_FACT_VND bulk collect  into LIGNE_TAUX_COLL; 
      close P_IN_FACT_VND;

      -- while we're at it why not use the more efficient FORALL syntax 
      -- to perform the inserts?


      forall idx in LIGNE_TAUX_COLL.first() .. LIGNE_TAUX_COLL.last()
            INSERT
           INTO P6PCM2_PARMCMS VALUES
              (
            P_IN_NUM_VND,   
            LIGNE_TAUX_COLL(idx).COD_NOMCPDT, 
            LIGNE_TAUX_COLL(idx).LIB_LIBNOMCPDT, 
            LIGNE_TAUX_COLL(idx).DHS_MAJ, 
            LIGNE_TAUX_COLL(idx).LIB_AUTH_MAJ);

我们不能像那样使用ref游标;我们需要使用显式游标语法。尝试此操作(警告:未测试的代码!):

但是,如果将记录提取到集合中,则可以获得更好的性能。大概是这样的:

        type LIGNE_TAUX_NT is table of PACK_REC_FACT_VND.FACT_VND_RECORD;
        LIGNE_TAUX_COLL LIGNE_TAUX_NT;
    BEGIN
      DELETE FROM P6PCM2_PARMCMS WHERE NUM_VND=P_IN_NUM_VND;

      fetch P_IN_FACT_VND bulk collect  into LIGNE_TAUX_COLL; 
      close P_IN_FACT_VND;

      -- while we're at it why not use the more efficient FORALL syntax 
      -- to perform the inserts?


      forall idx in LIGNE_TAUX_COLL.first() .. LIGNE_TAUX_COLL.last()
            INSERT
           INTO P6PCM2_PARMCMS VALUES
              (
            P_IN_NUM_VND,   
            LIGNE_TAUX_COLL(idx).COD_NOMCPDT, 
            LIGNE_TAUX_COLL(idx).LIB_LIBNOMCPDT, 
            LIGNE_TAUX_COLL(idx).DHS_MAJ, 
            LIGNE_TAUX_COLL(idx).LIB_AUTH_MAJ);

记录表是我的第二个想法……我要试一试!我切换到记录表作为输入参数,因为我发现使用它更安全:)10x无论如何,记录表是我的第二个想法..我会尝试一下!我切换到记录表作为输入参数,因为我发现使用:)10x更安全
        type LIGNE_TAUX_NT is table of PACK_REC_FACT_VND.FACT_VND_RECORD;
        LIGNE_TAUX_COLL LIGNE_TAUX_NT;
    BEGIN
      DELETE FROM P6PCM2_PARMCMS WHERE NUM_VND=P_IN_NUM_VND;

      fetch P_IN_FACT_VND bulk collect  into LIGNE_TAUX_COLL; 
      close P_IN_FACT_VND;

      -- while we're at it why not use the more efficient FORALL syntax 
      -- to perform the inserts?


      forall idx in LIGNE_TAUX_COLL.first() .. LIGNE_TAUX_COLL.last()
            INSERT
           INTO P6PCM2_PARMCMS VALUES
              (
            P_IN_NUM_VND,   
            LIGNE_TAUX_COLL(idx).COD_NOMCPDT, 
            LIGNE_TAUX_COLL(idx).LIB_LIBNOMCPDT, 
            LIGNE_TAUX_COLL(idx).DHS_MAJ, 
            LIGNE_TAUX_COLL(idx).LIB_AUTH_MAJ);