简体   繁体   中英

How can I insert rows from one table to another in PL SQL using the cursor for loop?

I don't know how much of this is right

DECLARE    
    CURSOR cur_depts IS
    SELECT *
    FROM dept;
BEGIN
    FOR i IN cur_depts
    LOOP
       INSERT INTO dept_backup
       VALUES(i);
    END LOOP;
    CLOSE  cur_depts;
END;

And this is the error I got

Error report -
ORA-06550: line 8, column 20:
PL/SQL: ORA-00947: not enough values
ORA-06550: line 8, column 8:
PL/SQL: SQL Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

I'm using the tables from Scott schema here.

i is the cursor record, you cannot insert it directly to another table, you need to refer to the specific columns. For example,

INSERT INTO dept_backup (b_col1, b_col2, b_col3) values(i.c_col1,i.c_col2,i.c_col3);

You do not need a cursor (and should not use one as individual inserts in a loop will be slower and generate a lot more logging). You can simply use a single INSERT ... SELECT ... statement:

INSERT INTO dept_backup
SELECT * FROM dept;

As you were told, you don't really need PL/SQL nor cursors nor loops, but - if you're learning about them, then here's how.

SQL> create table dept_backup as select * From dept where 1 = 2;

Table created.

SQL> declare
  2    cursor cur_depts is
  3      select deptno, dname, loc
  4      from dept;
  5  begin
  6    for i in cur_depts loop
  7      insert into dept_backup (deptno, dname, loc)
  8        values (i.deptno, i.dname, i.loc);
  9    end loop;
 10  end;
 11  /

PL/SQL procedure successfully completed.

SQL> select * from dept_backup;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

SQL>

Even shorter option is not to explicitly declare a cursor - use cursor FOR loop:

SQL> truncate table dept_backup;

Table truncated.

SQL> begin
  2    for i in (select deptno, dname, loc from dept) loop
  3      insert into dept_backup (deptno, dname, loc)
  4        values (i.deptno, i.dname, i.loc);
  5    end loop;
  6  end;
  7  /

PL/SQL procedure successfully completed.

SQL> select * from dept_backup;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

SQL>

Note that you don't have to close a cursor if you use such a syntax; you would have to declare a cursor variable, open the cursor, fetch from it, exit the loop and close the cursor if you used this syntax:

SQL> truncate table dept_backup;

Table truncated.

SQL> declare
  2    cursor cur_depts is select deptno, dname, loc from dept;
  3    cd_r   cur_depts%rowtype;
  4  begin
  5    open cur_depts;
  6    loop
  7      fetch cur_depts into cd_r;
  8      exit when cur_depts%notfound;
  9      insert into dept_backup (deptno, dname, loc)
 10        values (cd_r.deptno, cd_r. dname, cd_r.loc);
 11    end loop;
 12    close cur_depts;
 13  end;
 14  /

PL/SQL procedure successfully completed.

SQL> select * from dept_backup;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

SQL>

Obviously, cursor FOR loop is way simpler.

Two issues (assuming dept and dept_backup have matching columns)

  1. there should be no brackets around the record variable when using this syntax
  2. you cannot explicitly close a for-loop cursor after the loop has completed and already implicitly closed it.

Try this:

declare
    cursor cur_depts is
        select * from dept;
begin
    for r in cur_depts loop
        insert into dept_backup values r;
    end loop;
end;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM