Ошибка компиляции PL / SQL - PLS-00382: выражение неправильного типа

Я использую PL / SQL ниже ...

DECLARE
BEGIN 
FOR i IN (select VALUE from REWARDS)
LOOP 
insert into BT_CMS.T_REWARDS_TYPES 
(ID, REWARD_LABEL, REWARD_VALUE, REWARD_METHOD, UPDATE_USER, UPDATE_DATE, PAYMENT_PROVIDER_ID, CREATE_DATE, COUNTRY_CODE_ID) 
values 
(BT_CMS.SEQ_REWARD_TYPE_ID.nextval, 'R' || i || ' Real Time', i, 'Airtime', 'DEVOPS-826', sysdate, 120, sysdate, 206); 
END LOOP; 
END;

... и получаю сообщение об ошибке ниже ...

ORA-06550: line 8, column 72:
PLS-00382: expression is of wrong type
ORA-06550: line 8, column 52:
PLS-00382: expression is of wrong type
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.

Я почти уверен, что проблема заключается в замене i в значениях, но я не знаю, в чем именно проблема. Столбец VALUE в таблице REWARDS, в котором выбирается i, имеет data_type = VARCHAR2 (20 BYTE). Столбец REWARD_LABEL, в который я пытаюсь вставить его, имеет data_type = VARCHAR2 (50 CHAR).


person Stephen Walsh    schedule 16.09.2016    source источник


Ответы (1)


Внутри цикла i относится ко всей записи, а не к (уникальному) полю записи; вам нужно использовать i.value вместо i:

DECLARE
BEGIN
    FOR i IN (SELECT VALUE FROM REWARDS)
    LOOP
        INSERT INTO BT_CMS.T_REWARDS_TYPES(
                                           ID,
                                           REWARD_LABEL,
                                           REWARD_VALUE,
                                           REWARD_METHOD,
                                           UPDATE_USER,
                                           UPDATE_DATE,
                                           PAYMENT_PROVIDER_ID,
                                           CREATE_DATE,
                                           COUNTRY_CODE_ID
                                          )
             VALUES (
                     BT_CMS.SEQ_REWARD_TYPE_ID.NEXTVAL,
                     'R' || i.VALUE || ' Real Time',
                     i.VALUE,
                     'Airtime',
                     'DEVOPS-826',
                     SYSDATE,
                     120,
                     SYSDATE,
                     206
                    );
    END LOOP;
END;

Лучшим подходом могло бы быть использование одной вставки-выбора вместо цикла по курсору; Например:

INSERT INTO BT_CMS.T_REWARDS_TYPES(
                                   ID,
                                   REWARD_LABEL,
                                   REWARD_VALUE,
                                   REWARD_METHOD,
                                   UPDATE_USER,
                                   UPDATE_DATE,
                                   PAYMENT_PROVIDER_ID,
                                   CREATE_DATE,
                                   COUNTRY_CODE_ID
                                  )
    SELECT BT_CMS.SEQ_REWARD_TYPE_ID.NEXTVAL,
           'R' || r.VALUE || ' Real Time',
           r.VALUE,
           'Airtime',
           'DEVOPS-826',
           SYSDATE,
           120,
           SYSDATE,
           206
      FROM REWARDS r
person Aleksej    schedule 16.09.2016
comment
Ах, второй вариант намного проще. Прекрасный ответ. Спасибо, @Aleksej !! - person Stephen Walsh; 16.09.2016
comment
@Aleksej - Какой инструмент / URL вы используете для форматирования кода? Выглядит очень чисто. - person Utsav; 16.09.2016
comment
@Utsav - Это жаба для Oracle v12.1, после некоторой настройки - person Aleksej; 16.09.2016
comment
Вам действительно не нужен инструмент для форматирования одного оператора INSERT. Лично я предпочитаю, чтобы ключевые слова были выстроены в ряд и не CAPS LOCK, но +1 для форматирования в любом случае. - person William Robertson; 16.09.2016