2017-09-25 41 views
1

當嘗試編譯複合觸發器時,出現此錯誤(PLS-00642)。我剛剛瞭解了類型和集合,所以它仍然很混亂。SQL中不允許的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