1

I would like to insert a couple of records using PL/SQL loops, but when I execute below block in SQL Developer I am getting the following error:

declare
    loop_size number;

begin
    loop_size := 10;

    while loop_size > 0
    loop
        INSERT INTO CM.CUSTOMER (ID, FIRST_NAME, LAST_NAME, STATUS )
        VALUES (CM.SQ_CUSTOMER.nextval, 'Jhon', 'Jhon',10);

        loop_size := loop_size -1;      
    end loop;
end; 

Error

PLS-00225: subprogram or cursor 'CM' reference is out of scope
3
  • 1
    What do you think CM is? A schema? What user runs this? Commented Dec 23, 2018 at 9:06
  • yes, it is schema. Commented Dec 23, 2018 at 11:42
  • So will you be running this as another user? Generally it is best practice not to hardcode schema names unless you really have to. I would prefer to leave out the schema name and run it from the CM account. (By the way, you have a status variable but you don't use it. Is it a sting or a number?) Commented Dec 23, 2018 at 17:33

4 Answers 4

2

I couldn't reproduce your error, but one problem is that CM.CUSTOMER can't be both a table and a sequence.

Generally it is best practice not to hardcode schema names unless you really have to. I would prefer to leave out the schema name here and just run it from the CM account.

I created a sequence named customer_seq and the following runs without error:

create table customer
( id          number primary key 
, first_name  varchar2(20)
, last_name   varchar2(20)
, status      number );

create sequence customer_seq;

declare
    status varchar(10) := '10';
    loop_size number := 10;
begin
    while loop_size > 0
    loop
        insert into customer (id, first_name, last_name, status)
        values (customer_seq.nextval, 'Jhon', 'Jhon', status);

        loop_size := loop_size -1;      
    end loop;
end;
/

If using Oracle 12.1 or later I would prefer to use an identity column and stop micro-managing sequences. You also don't need to manage the loop index yourself as PL/SQL has a convenient for loop construct:

create table customer
( id          number generated always as identity primary key 
, first_name  varchar2(20)
, last_name   varchar2(20)
, status      number );

declare
    status varchar(10) := '10';
    loop_size number := 10;
begin
    for i in 1..loop_size loop
        insert into customer (first_name, last_name, status )
        values ('Jhon', 'Jhon', status);
    end loop;
end;
/
Sign up to request clarification or add additional context in comments.

1 Comment

Good spot that the OP had used CM.CUSTOMER for both table and sequence name.
1

You may achieve this without dynamic SQL:

INSERT INTO CM.CUSTOMER (FIRST_NAME, LAST_NAME, STATUS)
SELECT 'Jhon', 'Jhon', '10'
FROM dual
CONNECT BY rownum <= 10;

This answer assumes that the ID column be auto increment, which it probably should be.

1 Comment

Umm, in the OP's version value of STATUS is 10.
0

Remove last unnecessary commas and select sequence from dual:

  INSERT INTO CM.CUSTOMER (ID, FIRST_NAME, LAST_NAME, STATUS)
  select ln.SQ_CUSTOMER, 'Jhon', 'Jhon', 10 from dual;

update to sequence to ln.SQ_CUSTOMER

3 Comments

That won't work, Either remove VALUES, or remove SELECT & FROM DUAL.
Also CM.CUSTOMER can't be both a table and a sequence.
@user7294900, it seems, doesn't recognize schema ln, I get the following error: PLS-00225: subprogram or cursor 'LN' reference is out of scope
0

Many thanks for your responses, finally I solved my problem as bellow:

declare
loop_size number;
rec_id NUMBER;

begin
  loop_size := 10;

  while loop_size > 0
  loop

    execute immediate 'select cm.SQ_CUSTOMER.nextval from dual' into rec_id;

    INSERT INTO CM.CUSTOMER (ID, FIRST_NAME, LAST_NAME, STATUS )
    VALUES (rec_id, 'Jhon', 'Jhon',10);

    loop_size := loop_size -1;      
  end loop;
end; 

2 Comments

See my updated answer without using execute immediate
Why are you using execute immediate for the (pre-12c style) sequence? (And why is it in a different schema from the table?) You can just assign it like your other variables: rec_id := sq_customer.nextval. Or better, just use it directly in the insert statement with no need for any intermediate variable. Or even better, use an identity column and forget about sequences (see my answer).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.