Прошу помощи - скрипт - вывод курсора в отчет.

Павел А. Яковлев
Дата: 10.03.2011 09:39:04
Доброго времени суток!!

Главный вопрос:
Как сделать чтобы подставлять любой select в курсор и автоматически без ручной обработки - получать "распечатку" его строк.

Задача: Создать скрипт в который подставляется запрос - на выходе получать строки запроса в виде текста с разделителями...
SELECT запроса подставляется в курсор и может быть любой сложности...
от простого
select count(*) otvet from guides
до сложного
SELECT  H.*, ( SELECT  Name FROM Types WHERE  Type_id = H.Type_doc ) Nam , -Pledger.Saldo ( 'X', Account, Currency, SYSDATE ) Saldo
  FROM  (SELECT /*+ INDEX (c CONTRACT_NEXT_NDX)*/ K.Full_name, K.Doc_seria || K.Doc_number, K.Date_reg, ',' || C.Account || ',', C.Currency, C.Type_doc
               , NVL ( Universe.Date_cor ( C.Bach, C.Reference, 'PROLONGATION', C.Currency, TRUNC ( SYSDATE ) ), C.Date_open )+ Period Dp
               , K.Phone || K.Fax Tel
           FROM  Contracts C, Clients K
          WHERE  C.Type_doc IN (1, 2, 3, 4, 5) AND C.Status IN (1, 2) AND K.Reference = C.R_client AND K.Bach = C.B_client AND ( K.Phone || K.Fax IS NOT NULL )) H
 WHERE  Dp >= TO_DATE ( '01.03.2011', 'dd.mm.yyyy' ) AND Dp <= TO_DATE ( '31.03.2011', 'dd.mm.yyyy' );
Пример решения при простом запросе и предварительной редакции курсора под одну переменную:
DECLARE
  CURSOR Cur IS
    SELECT  Curr_id || CHR ( 9 ) || Rec_id || CHR ( 9 ) || Name || CHR ( 9 ) || Date_off || CHR ( 9 ) || Loggi Otvet
      FROM  Ha_log
     WHERE  Status LIKE '* S%' AND Date_off > TO_DATE ( '01.05.2010', 'dd.mm.yyyy' ) AND Date_off < TO_DATE ( '30.06.2010', 'dd.mm.yyyy' );
BEGIN
  DELETE FROM  Balance WHERE  Id = 'N1';
  FOR X IN Cur LOOP
    INSERT INTO  Balance ( Id, Text ) VALUES  ( 'N1', X.Otvet );
  END LOOP;
  COMMIT;
END;
env
Дата: 10.03.2011 09:56:11
Павел А. Яковлев
Главный вопрос:
Как сделать чтобы подставлять любой select в курсор и автоматически без ручной обработки - получать "распечатку" его строк.

Задача: Создать скрипт в который подставляется запрос - на выходе получать строки запроса в виде текста с разделителями...
SELECT запроса подставляется в курсор и может быть любой сложности...


Приведённое "решение" не коррелирует с постановкой задачи. Переформулируйте вопрос.
dbms_sql, sqlplus + spool...
Какую задачу решаете на самом деле?
Павел А. Яковлев
Дата: 10.03.2011 10:18:11
Коррелирует :)
Задача - вставить в текст скрипта "селект" и на выходе получить заполнение таблицы текстовыми строками с разделителем - в примере это табуляторы.

Проблема в универсальном решении - создать цикл перебора полей неизвестного курсора.
dba123
Дата: 10.03.2011 10:21:57
Павел А. Яковлев,

print_table.sql можно посмотреть на форуме и у T.Kyte
env
Дата: 10.03.2011 10:22:11
Павел А. Яковлев,

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

Первое легко решается через sqlplus.

Второе через dbms_sql. (можно извратиться - sqlplus + sqlldr + shell script)
Павел А. Яковлев
Дата: 10.03.2011 10:37:18
env,

Второе описание более подробное и правильное..

Буду благодарен за пример цикла с инсёртом!
-2-
Дата: 10.03.2011 10:41:16
Павел А. Яковлев
Задача: Создать скрипт в который подставляется запрос - на выходе получать строки запроса в виде текста с разделителями...
SQL> var cur refcursor
SQL> exec open :cur for select level x, dummy from dual connect by level<=3

PL/SQL procedure successfully completed.

SQL> print cur

         X DUM
---------- ---
         1 X
         2 X
         3 X
env
Дата: 10.03.2011 10:50:51
Павел А. Яковлев,

У Кайта всё подробно описано.
srjm
Дата: 10.03.2011 10:51:46
На скорую руку вот такое получилось:
declare
  cur integer;
  ret integer;
  sSQL  varchar2(4000);
  iTmp  integer;
  col_cnt integer;
  desc_t dbms_sql.desc_tab;
  result_string varchar2(4000);
  vals dbms_sql.Number_Table;
begin
  
  sSQL := 'select 1, 2, 3, 4  from dual';
  cur := dbms_sql.open_cursor;
  dbms_sql.parse(cur, sSQL, dbms_sql.native);
  ret	:= dbms_sql.execute(cur);
  --
  dbms_sql.describe_columns(cur, col_cnt, desc_t);
  dbms_output.put_line('Cols: '||itmp);
  
  for i in 1..col_cnt loop
      vals(i) := null;
      DBMS_SQL.DEFINE_COLUMN(cur,i,vals(i));
  end loop;
  
  iTmp := DBMS_SQL.FETCH_ROWS(cur);
  
  for i in 1..col_cnt loop
      DBMS_SQL.COLUMN_VALUE(cur,i,vals(i));
      result_string := result_string||vals(i)||'; ';
  end loop;
  dbms_output.put_line(result_string);
end;
srjm
Дата: 10.03.2011 10:56:37
Пардон, курсор забыл закрыть :)
declare
  cur integer;
  ret integer;
  sSQL  varchar2(4000);
  iTmp  integer;
  col_cnt integer;
  desc_t dbms_sql.desc_tab;
  result_string varchar2(4000);
  vals dbms_sql.Number_Table;
begin
  
  sSQL := 'select 1, 2, 3, 4  from dual';
  cur := dbms_sql.open_cursor;
  dbms_sql.parse(cur, sSQL, dbms_sql.native);
  ret  := dbms_sql.execute(cur);
  --
  dbms_sql.describe_columns(cur, col_cnt, desc_t);
  dbms_output.put_line('Cols: '||itmp);
  
  for i in 1..col_cnt loop
      vals(i) := null;
      DBMS_SQL.DEFINE_COLUMN(cur,i,vals(i));
  end loop;
  
  iTmp := DBMS_SQL.FETCH_ROWS(cur);
  
  for i in 1..col_cnt loop
      DBMS_SQL.COLUMN_VALUE(cur,i,vals(i));
      result_string := result_string||vals(i)||'; ';
  end loop;
  dbms_output.put_line(result_string);
  dbms_sql.close_cursor(cur);
end;