0

複数の行をストアド プロシージャに渡す必要があります。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); 

以前に満たされたカーソルを受け取り、データで何かをします。

これら 2 つの呼び出しを使用します。最初のものは問題なく動作し、参照カーソル 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);

データが未定義であるため、データを反復処理できません: (2 番目の手順のコード)

LIGNE_TAUX PACK_REC_FACT_VND.FACT_VND_RECORD;
    BEGIN
      DELETE FROM P6PCM2_PARMCMS WHERE NUM_VND=P_IN_NUM_VND;
      FOR LIGNE_TAUX IN P_IN_FACT_VND
      LOOP
        INSERT
        INTO P6PCM2_PARMCMS VALUES
          (
            P_IN_NUM_VND,   
LIGNE_TAUX.COD_NOMCPDT, 
LIGNE_TAUX.LIB_LIBNOMCPDT, 
LIGNE_TAUX.DHS_MAJ, 
LIGNE_TAUX.LIB_AUTH_MAJ);
      END LOOP;

Error(48,21): PLS-00221: 'P_IN_FACT_VND' is not a procedure or is undefined

それとも、TABLE OF RECORD に切り替える必要がありますか?

4

1 に答える 1

3

そのような参照カーソルは使用できません。明示カーソル構文を使用する必要があります。これを試してください (警告: テストされていないコードです!):

        LIGNE_TAUX PACK_REC_FACT_VND.FACT_VND_RECORD;
    BEGIN
      DELETE FROM P6PCM2_PARMCMS WHERE NUM_VND=P_IN_NUM_VND;

      LOOP
         fetch P_IN_FACT_VND   into LIGNE_TAUX; 
         exit when P_IN_FACT_VND%notfound;
        INSERT
        INTO P6PCM2_PARMCMS VALUES
          (
            P_IN_NUM_VND,   
            LIGNE_TAUX.COD_NOMCPDT, 
            LIGNE_TAUX.LIB_LIBNOMCPDT, 
            LIGNE_TAUX.DHS_MAJ, 
            LIGNE_TAUX.LIB_AUTH_MAJ);
      END LOOP;

  close P_IN_FACT_VND;

ただし、レコードをコレクションにフェッチすると、パフォーマンスが向上します。このようなもの:

        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);

詳細をご覧ください

于 2012-04-09T15:03:00.317 に答える