Oracle SQl Заполнение курсора в процедуре из оператора SQL, сохраненного в поле таблицы - PullRequest
0 голосов
/ 11 февраля 2011

Мы хотим заполнить курсор в процедуре, которая заполняется из оператора выбора в таблице.

Мы создали таблицу с именем сохраненные_стали_сталицы с двумя столбцами: Created_date & Sql_statement.В эту таблицу мы вставим оператор выбора, который выбирает другие данные из базы данных на основе потребностей клиентов.Пример: вставка в значения сохраненных_каталогов (Created_date, Sql_statement) ('1.02.2011', 'Выберите Client_idn, что-то из cool_table где animal =' dog '')

Затем в процедуре мы имеем кучукод, который делает то, что ему нужно, который никогда не изменится, но оператор выбора, который мы имеем в курсоре, периодически меняется.Нам всегда нужно возвращать 2 поля, но остальная часть оператора select изменяется.

Так что теперь нам нужно заполнить курсор в процедуре тем, что оператор SELECT придет из таблицы.Если он возвращал только 1 строку, мы имеем: объявляем x varchar2 (600);номер rec1 (10);rec2 varchar2 (15);начать выполнение немедленного выбора Sql_statement в x из сохраненных_стадий_статей, где create_date = '2/1/2011';немедленно выполнить x в rec1, rec2;...

Это работает, но нам не нужно, чтобы оно входило в 2 переменные, нам нужно, чтобы оно входило в курсор.Реальное выражение select (приведенный выше код является простым примером того, что нам нужно сделать) возвращает тысячи записей, поэтому нам нужно использовать курсор.

Надеюсь, все это имеет смысл

Так что, если кто-нибудь знает, как это сделать, это будет оценено.

Ответы [ 2 ]

0 голосов
/ 11 февраля 2011
SQL> drop table stack_overflow;

Table dropped.

SQL> create table stack_overflow (created_date date constraint stack_overflow_pk primary key
  2      , sql_statement varchar2(4000) not null)
  3  /

Table created.

SQL> drop table source_data;

Table dropped.

SQL> create table source_data (vc varchar2(10) null
  2      , n number);

Table created.

SQL> insert into source_data values ('a', 100);

1 row created.

SQL> insert into source_data values ('a', 0);

1 row created.

SQL> insert into source_data values ('b', 50);

1 row created.

SQL> insert into source_data values ('c', null);

1 row created.

SQL> insert into stack_overflow values (sysdate - 3/24, 'select vc, sum(n)
  2      from source_data
  3      group by vc
  4      order by vc asc');

1 row created.

SQL> insert into stack_overflow values (sysdate - 2/24 , 'select vc, avg(n)
  2      from source_data
  3      group by vc
  4      order by vc desc');

1 row created.

SQL> insert into stack_overflow values (sysdate - 1/24 , 'select vc, count(*)
  2      from source_data
  3      group by vc');

1 row created.

SQL> insert into stack_overflow values (sysdate, 'select vc, count(n)
  2      from source_data
  3      group by vc');

1 row created.

SQL> commit;

Commit complete.

SQL> declare
  2      type stack_overflow_type is record (col_1 varchar2(10), col_2 number);
  3      type stack_overflow_cur_type is ref cursor return stack_overflow_type;
  4      cursor sql_statement_cur is select sql_statement
  5          from stack_overflow
  6          order by created_date;
  7      --
  8      function get_cursor_by_date (i_created_date in date) return stack_overflow_cur_type is
  9          l_return_cur sys_refcursor; -- stack_overflow_cur_type;
 10          l_sql_statement stack_overflow.sql_statement%TYPE;
 11      begin
 12          select sql_statement into l_sql_statement
 13          from stack_overflow
 14          where created_date = i_created_date;
 15          --
 16          open l_return_cur for l_sql_statement;
 17          return l_return_cur;
 18      end get_cursor_by_date;
 19      --
 20      procedure process_and_close_cursor (i_cursor in stack_overflow_cur_type) is
 21          l_current_rec stack_overflow_type;
 22      begin
 23          loop
 24              fetch i_cursor into l_current_rec;
 25              exit when i_cursor%NOTFOUND;
 26              dbms_output.put_line('col_1: ' || l_current_rec.col_1
 27                  || ' col_2: ' || to_number(l_current_rec.col_2));
 28          end loop;
 29          --
 30          close i_cursor;
 31      end;
 32      --
 33  begin
 34      for l_row in (select created_date
 35          from stack_overflow
 36          order by created_date)
 37      loop
 38          dbms_output.put_line('Processing the SQL statement created on: '
 39             || to_char(l_row.created_date, 'YYYY-MM-DD HH24:Mi:SS'));
 40          --
 41          process_and_close_cursor(get_cursor_by_date(l_row.created_date));
 42          --
 43          dbms_output.new_line;
 44      end loop;
 45  end;
 46  /
Processing the SQL statement created on: 2011-02-11 10:01:16
col_1: a col_2: 100
col_1: b col_2: 50
col_1: c col_2:

Processing the SQL statement created on: 2011-02-11 11:01:16
col_1: c col_2:
col_1: b col_2: 50
col_1: a col_2: 50

Processing the SQL statement created on: 2011-02-11 12:01:17
col_1: a col_2: 2
col_1: b col_2: 1
col_1: c col_2: 1

Processing the SQL statement created on: 2011-02-11 13:01:17
col_1: a col_2: 2
col_1: b col_2: 1
col_1: c col_2: 0


PL/SQL procedure successfully completed.
0 голосов
/ 11 февраля 2011

Вы пытаетесь динамически заполнить курсор-указатель ?если это так, то это не сложно сделать:

set serveroutput on
declare


 sql1 varchar2(500);
 sql2 varchar2(500);
 procedure runProcess(sqlstatement IN varchar2)
 AS
     refcrs sys_refcursor;
     DTE DATE;
     LEVELB NUMBER;
 BEGIN
  dbms_output.put_line(sqlstatement);
     open refcrs for
      sqlstatement; -- use 'using' to bind those variables
        loop
          fetch refcrs into DTE, LEVELB;
          exit when refcrs%notfound;
          dbms_output.put_line(TO_CHAR(DTE,'MMDDYYYY') || '/' || LEVELB);
        end loop;     
    CLOSE REFCRS;     
 END runProcess;

begin
    sql1 := 'select (sysdate - level) a, level b from dual connect by level < 5';
    sql2:= 'select (sysdate + level) a, -level b from dual connect by level < 5';

    runProcess(SQL1);
    runProcess(SQL2);


end ;

/**
select (sysdate - level) a, level b from dual connect by level < 5
02102011/1
02092011/2
02082011/3
02072011/4
select (sysdate + level) a, -level b from dual connect by level < 5
02122011/-1
02132011/-2
02142011/-3
02152011/-4
**/

Как видите, я динамически выполняю два разных оператора выбора в одной и той же процедуре и выводю их результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...