2012-04-09 107 views
0

我需要將多行傳遞給存儲過程。我可以使用遊標嗎?因爲我已經試過如下:PL/sql存儲過程引用光標作爲參數

裏面我的包,我有:

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

臨危先前充滿光標並執行對數據進行處理。

我使用這兩個調用;第一個工作正常,我可以看到引用光標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); 

我不能對數據進行迭代,因爲它是不確定的: (代碼從第二個過程)

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 

或者我應該切換到表記錄?

回答

3

我們不能使用這樣的ref遊標;我們需要使用顯式遊標語法。試試這個(警告:未經測試的代碼!):

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

Find out more

+0

記錄表是我的第二個想法..我會試一試!並回答一個答案。 – Samson 2012-04-09 15:05:28

+0

我切換到記錄表作爲輸入參數,因爲我覺得它更安全的使用:)反正10倍 – Samson 2012-04-10 08:49:53