我在尝试编译复合触发器时遇到此错误(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循环中的集合?这有一个简单的解决方法吗?
答案 0 :(得分:2)
在Oracle 11g中,您不能在SQL范围内使用PL / SQL中声明的集合类型。您需要在SQL范围中创建它们。
CREATE OR REPLACE TYPE num_list IS TABLE OF NUMBER;
并从触发器中删除类型声明。