Процедура в PL/SQL с созданием и курсором

Можем ли мы провести процедуру с

Сначала создайте таблицу, предположим

  create table INCOME_GROUP(income_compare_groups varchar(100)) ;

Затем вставьте данные в эту таблицу.

 insert into INCOME_GROUP values (10-20);

Затем используйте эту таблицу в курсор.

 CURSOR c1 IS(select *from INCOME_GROUP);

Например, я делаю это.

BEGIN 
create table INCOME_GROUP(income_compare_groups varchar(100)) ;
DECLARE

   CURSOR c1 IS(select * income_Group);
BEGIN
   FOR acct IN c1 LOOP  -- process each row one at a time

      INSERT INTO temp_test
            VALUES (acct.income_compare_groups);


   END LOOP;
   COMMIT;
END;
END;

Но я получаю некоторую ошибку.

ORA-06550: line 2, column 4:
PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:

   ( begin case declare exit for goto if loop mod null pragma
   raise return select update while with <an identifier>
   <a double-quoted delimited-identifier> <a bind variable> <<
   continue close current delete fetch lock insert open rollback
   savepoint set sql execute commit forall merge pipe purge

Прочитав комментарии, я попробовал это -

BEGIN 
     EXECUTE IMMEDIATE 'create table INCOME_GROUP
 (
  income_compare_groups varchar(100)
  )'; 
DECLARE

   CURSOR c1 IS
     (select * from
       INCOME_GROUP
    );



BEGIN

 FOR acct IN c1 LOOP  -- process each row one at a time



      INSERT INTO temp_test
            VALUES (acct.income_compare_groups, null);


   END LOOP;
   COMMIT;
END;
END;

Но кажется, что это не создает таблицу.!!!!


person Java_Alert    schedule 28.11.2013    source источник
comment
Вы не можете запускать операторы DDL (create) в процедуре напрямую. Вам нужно использовать динамический SQL.   -  person a_horse_with_no_name    schedule 28.11.2013
comment
Обновите вопрос с ошибками, которые вы получаете.   -  person Bishan    schedule 28.11.2013
comment
@a_horse_with_no_name, не могли бы вы рассказать, как использовать динамический sql, потому что я новичок в программировании процедур.   -  person Java_Alert    schedule 28.11.2013
comment
@Bishan Готово с необходимым!!!   -  person Java_Alert    schedule 28.11.2013
comment
Подробнее об использовании динамического SQL см. в руководстве: docs.oracle.com/cd/E11882_01/appdev.112/e25519/   -  person a_horse_with_no_name    schedule 28.11.2013


Ответы (3)


Вы можете сделать это следующим образом:

create or replace procedure cpy_inc_comp_grps
as
cur_1 sys_refcursor;
compare_group varchar2(100);
begin
  execute immediate 'create table income_group(income_compare_groups varchar2(100))';
  open cur_1 for 'select income_compare_groups from income_group';

  LOOP
  FETCH cur_1 INTO compare_group;
    DBMS_OUTPUT.PUT_LINE('INSERT INTO temp_test VALUES (rec.income_compare_groups');
  EXIT WHEN cur_1%NOTFOUND;
  END LOOP;
  close cur_1;
  execute immediate 'drop table income_group';
end;

И протестируйте его с помощью следующего кода:

begin
  cpy_inc_comp_grps;
end;

Вы должны заменить часть dbms_output.put_line(...) любыми вставками, которые вы хотите сделать.

person Armunin    schedule 28.11.2013
comment
Если предположим, что у меня есть таблица INCOME_GROUP с несколькими столбцами, то как ее перебрать. - person Java_Alert; 28.11.2013
comment
И если вы хотите вставить данные, просто используйте обычный оператор SQL INSERT INTO table_name VALUES (value1, value2, ...). Вам не нужно execute immediate для INSERT-оператора - person Armunin; 28.11.2013
comment
еще одна вещь, почему эта процедура занимает много времени! - person Java_Alert; 28.11.2013
comment
Я не знаю, это выполняется довольно быстро для меня. Вы имеете в виду этот пример или ваше последнее утверждение? - person Armunin; 28.11.2013

Должно быть так:

DECLARE
    cur SYS_REFCURSOR;
     v_income_compare_groups VARCHAR(100);
BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE INCOME_GROUP(income_compare_groups VARCHAR(100))';
    OPEN cur FOR 'SELECT * income_Group';
    LOOP
        FETCH cur INTO v_income_compare_groups;
        EXIT WHEN cur%NOTFOUND;
        INSERT INTO temp_test VALUES (v_income_compare_groups);
    END LOOP;
    CLOSE cur;
    COMMIT;
END;

Вы должны использовать динамический курсор, потому что при компиляции пакета таблица INCOME_GROUP еще не существует, и вы получите сообщение об ошибке CURSOR c1 IS(select * income_Group);.

Однако есть несколько проблем: вы получите сообщение об ошибке, если таблица уже существует. Вы должны сначала проверить это или написать обработчик исключений. Процедура бесполезна, потому что вы сначала создаете (пустую) таблицу, а затем выбираете ее - она ​​никогда ничего не выберет!

person Wernfried Domscheit    schedule 28.11.2013
comment
можем ли мы вставить данные также с помощью немедленного выполнения - person Java_Alert; 28.11.2013
comment
Если предположим, что у меня есть таблица INCOME_GROUP с несколькими столбцами, то как ее перебрать. - person Java_Alert; 28.11.2013
comment
Вы можете поместить почти все в EXECUTE IMMEDIATE '', включить операторы вставки с несколькими столбцами. - person Wernfried Domscheit; 29.11.2013

Попробуй это.

execute immediate 'create table INCOME_GROUP(income_compare_groups varchar(100))';
person Bishan    schedule 28.11.2013