2017-09-25 32 views
1

複合トリガをコンパイルしようとするとこのエラー(PLS-00642)が発生します。私はタイプとコレクションについて学んだので、それはまだ非常に混乱しています。複合サブルーチンでPL/SQLローカルコレクション型を使用できません

CREATE OR REPLACE TRIGGER trigger_trecho_teste 
FOR DELETE OR UPDATE OF shape ON tr_eixo_lt_ope 
COMPOUND TRIGGER 
    -- Declarative Section (optional) 
    -- Variables declared here have firing-statement duration. 
    TYPE num_list IS TABLE OF NUMBER; 
    trechos num_list; 

    --Trechos : 
    TYPE trechos_update IS VARRAY(2) OF sde.st_geometry; -- This will contain old/new or old/null of trechos 
    TYPE trecho_dict IS TABLE OF trechos_update INDEX BY PLS_INTEGER; -- This is a dictionary of the above, with keys as the cod 
    trechos_dict trecho_dict; 

    --Lts : 
    TYPE trechos_in_lt_to_update IS TABLE OF trechos_update; -- List of trechos above in specific LT 
    TYPE lt_dict IS TABLE OF trechos_in_lt_to_update INDEX BY PLS_INTEGER; -- Dictionary of the above 
    lts_dict lt_dict; 

    -- Auxiliar de iteração : 
    elem trechos_in_lt_to_update; 

    --Executed before each row change- :NEW, :OLD are available 
    BEFORE EACH ROW IS 
    BEGIN 
     trechos.extend; 
     IF UPDATING THEN 
      trechos(trechos.COUNT) := :NEW.PK_CD_TR_LT_OPE; 
      trechos_dict(:NEW.PK_CD_TR_LT_OPE) := trechos_update(:OLD.SHAPE, :NEW.SHAPE); 
     ELSE 
      trechos(trechos.COUNT) := :OLD.PK_CD_TR_LT_OPE; 
      trechos_dict(:NEW.PK_CD_TR_LT_OPE) := trechos_update(:OLD.SHAPE, NULL); 
     END IF; 

    END BEFORE EACH ROW; 

    --Executed aftereach row change- :NEW, :OLD are available 
    AFTER EACH ROW IS 
    BEGIN 
     NULL; 
    END AFTER EACH ROW; 

    --Executed after DML statement 
    AFTER STATEMENT IS 
    BEGIN 
     -- Construindo o dicionário com as lts e os seus trechos modificados 
     FOR resultado IN (SELECT FK_CD_LT_OPE cod_lt,FK_CD_TR_LT_OPE cod_trecho FROM EIXO_LT_OPE_COM_TR_EIXO_LT_OPE WHERE FK_CD_TR_LT_OPE MEMBER OF trechos) 
     LOOP 
      IF lts_dict.EXISTS(resultado.cod_lt) THEN 
       lts_dict(resultado.cod_lt).extend; 
       lts_dict(resultado.cod_lt)(lts_dict(resultado.cod_lt).COUNT) := trechos_dict(cod_trecho); 
      ELSE 
       lts_dict(resultado.cod_lt) := trechos_in_lt_to_update(trechos_dict(cod_trecho)); 
      END IF; 
     END LOOP; 

     -- Iterando o dicionário construído acima 
     elem := lts_dict.FIRST; 
     WHILE elem IS NOT NULL LOOP 
      elem := lts_dict.next(elem); 
      cogeo_utils.rebuild_line('tr_eixo_lt_ope', elem, lts_dict(elem)); 
     END LOOP; 
    END AFTER STATEMENT; 
END trigger_trecho_teste; 

エラーが行で発生します。私は選択ループ内のコレクションにアクセスしていますので、

FOR resultado IN (SELECT FK_CD_LT_OPE cod_lt,FK_CD_TR_LT_OPE cod_trecho FROM EIXO_LT_OPE_COM_TR_EIXO_LT_OPE WHERE FK_CD_TR_LT_OPE MEMBER OF trechos) 
LOOP 
    IF lts_dict.EXISTS(resultado.cod_lt) THEN 
    lts_dict(resultado.cod_lt).extend; 
    lts_dict(resultado.cod_lt)(lts_dict(resultado.cod_lt).COUNT) := trechos_dict(cod_trecho); 
    ELSE 
    lts_dict(resultado.cod_lt) := trechos_in_lt_to_update(trechos_dict(cod_trecho)); 
    END IF; 
END LOOP; 

はそれですか?これは簡単な回避策ですか?

答えて

2

Oracle 11gでは、SQLスコープ内でPL/SQLで宣言されたコレクション型は使用できません。それらをSQLスコープで作成する必要があります。

CREATE OR REPLACE TYPE num_list IS TABLE OF NUMBER; 

トリガーから型宣言を削除します。

+0

これは私が作成したすべてのタイプのものですか?または選択したもののみ – Mojimi

+0

PL/SQLスコープで他のコレクションを使用しています。 'trechos'コレクションはSQLステートメントで使用され、(私が見る限り)変更が必要な唯一のコレクションです。 – MT0

関連する問題