【问题标题】:PL/SQL local collection types not allowed in sql satementssql 语句中不允许使用 PL/SQL 本地集合类型
【发布时间】:2017-09-26 04:48:44
【问题描述】:

我在尝试编译复合触发器时收到此错误 (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;

是因为我正在访问选择循环内的集合吗?有没有简单的解决方法?

【问题讨论】:

    标签: oracle plsql oracle11g


    【解决方案1】:

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

    CREATE OR REPLACE TYPE num_list IS TABLE OF NUMBER;
    

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

    【讨论】:

    • 那么这适用于我创建的所有类型吗?或者选择中只有这个
    • 您正在使用 PL/SQL 范围内的其他集合; trechos 集合是唯一一个在 SQL 语句中使用并且需要修改的集合(据我所知)。
    猜你喜欢
    • 2014-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-16
    • 2012-01-17
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    相关资源
    最近更新 更多