Как использовать Member of в Oracle SQL и почему моя реализация выбрасывает неверное количество типов аргументов - PullRequest
0 голосов
/ 22 апреля 2020
CREATE OR REPLACE TRIGGER MYTRIGGER 
BEFORE INSERT OR UPDATE OR DELETE ON MAP_CALCULATION_SHOP_LIMITS
FOR EACH ROW
DECLARE
    TYPE table_is_delete IS TABLE OF map_calculation.is_delete%TYPE INDEX BY PLS_INTEGER;
    TYPE table_is_editable IS TABLE OF map_calculation.is_editable%TYPE INDEX BY PLS_INTEGER;
    var_table_is_delete table_is_delete;
    var_table_is_editable table_is_editable;
BEGIN
    SELECT IS_DELETE, IS_EDITABLE 
    BULK COLLECT INTO var_table_is_delete, var_table_is_editable
    FROM MAP_CALCULATION MC 
    INNER JOIN map_calculation_group MG ON MC.ID_CALC = MG.ID_CALC 
    WHERE MG.ID_CALC = MC.ID_CALC 
    AND (mg.id_group = :old.id_group OR mg.id_group = :new.id_group);

    IF (UPDATING OR INSERTING) 
    AND 'F' MEMBER OF var_table_is_editable THEN
        RAISE_APPLICATION_ERROR( -20004, '.......' );   
    ELSIF DELETING 
    AND ('T' MEMBER OF (var_table_is_delete)) THEN
        RAISE_APPLICATION_ERROR( -20005, '...............' );
  END IF;
END;
/

Этот Select всегда возвращает две строки. Каждая строка имеет 2 поля. Я делю их на 2 коллекции по полю. Все поля имеют тип Varchar2 (1Byte). Где это не так? Может быть, index by не так? Хотя, когда я пытался изменить его, он вызывал еще больше ошибок.

1 Ответ

0 голосов
/ 22 апреля 2020

MEMBER OF используется во вложенной таблице, так как у вас ассоциативный массив, который вы должны использовать, как показано ниже

 IF var_table_is_editable.COUNT > 0 
 THEN  
 FOR i in var_table_is_editable.FIRST..var_table_is_editable.LAST
 LOOP
 IF (UPDATING OR INSERTING)
 AND  var_table_is_editable(i)='F'
 THEN
 RAISE_APPLICATION_ERROR( -20004, '.......' ); 
 ELSIF DELETING AND var_table_is_delete(i)='T' THEN
    RAISE_APPLICATION_ERROR( -20005, '...............' );
 END IF;
 END LOOP;
 END IF;

ИЛИ вы можете сделать что-то подобное ниже без использования коллекций

    CREATE OR REPLACE TRIGGER MYTRIGGER 
    BEFORE INSERT OR UPDATE OR DELETE ON MAP_CALCULATION_SHOP_LIMITS
    FOR EACH ROW
    DECLARE
          var_is_delete NUMBER;
          var_is_editable NUMBER;

    BEGIN
        SELECT COUNT(1) 
        INTO var_is_delete
        FROM MAP_CALCULATION MC 
        INNER JOIN map_calculation_group MG ON MC.ID_CALC = MG.ID_CALC 
        WHERE MG.ID_CALC = MC.ID_CALC 
        AND (mg.id_group = :old.id_group OR mg.id_group = :new.id_group)
        AND IS_DELETE='T';

        SELECT COUNT(1) 
        INTO var_is_editable
        FROM MAP_CALCULATION MC 
        INNER JOIN map_calculation_group MG ON MC.ID_CALC = MG.ID_CALC 
        WHERE MG.ID_CALC = MC.ID_CALC 
        AND (mg.id_group = :old.id_group OR mg.id_group = :new.id_group)
        AND is_editable='F';



        IF (UPDATING OR INSERTING) 
        AND  var_is_editable > 0 THEN
            RAISE_APPLICATION_ERROR( -20004, '.......' );   
        ELSIF DELETING 
        AND var_is_delete > 0 THEN
            RAISE_APPLICATION_ERROR( -20005, '...............' );
      END IF;
    END;
...