3

I'm running the below 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;

... and getting the error below...

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'm fairly sure the issue is with the i being substituted into the values but I don't know what exactly is the issue. The VALUE column in the REWARDS table that i is being selected as has data_type = VARCHAR2(20 BYTE). The REWARD_LABEL column that I'm trying to insert it into has data_type = VARCHAR2(50 CHAR).

Stephen Walsh
  • 815
  • 4
  • 18
  • 34

1 Answers1

6

Inside the loop, i refers to the whole record, not to the (unique) field of the record; you need to use i.value instead of 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;

A better approach could be using a single insert-select instead of looping through a cursor; for example:

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
Aleksej
  • 22,443
  • 5
  • 33
  • 38
  • Ah, the second option is so much simpler. Perfect answer. Thanks, @Aleksej !! – Stephen Walsh Sep 16 '16 at 14:14
  • @Aleksej - What tool/url do you use to format the code? Looks very clean. – Utsav Sep 16 '16 at 14:28
  • @Utsav - It's Toad for Oracle v12.1, after some configuration – Aleksej Sep 16 '16 at 14:33
  • You shouldn't really need a tool for formatting one INSERT statement. Personally I prefer to see keywords lined up and no [CAPS LOCK](http://stackoverflow.com/questions/292026/is-there-a-good-reason-to-use-upper-case-for-sql-keywords), but +1 for formatting anyway. – William Robertson Sep 16 '16 at 15:28