sql语句中不允许使用PL / SQL本地集合类型

时间:2017-09-25 20:39:30

标签: oracle plsql oracle11g

我在尝试编译复合触发器时遇到此错误(PLS-00642)。我刚刚了解了类型和集合,所以它仍然非常令人困惑。

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;

是不是因为我正在访问select循环中的集合?这有一个简单的解决方法吗?

1 个答案:

答案 0 :(得分:2)

在Oracle 11g中,您不能在SQL范围内使用PL / SQL中声明的集合类型。您需要在SQL范围中创建它们。

CREATE OR REPLACE TYPE num_list IS TABLE OF NUMBER;

并从触发器中删除类型声明。