Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 фильтрация курсоров  [new]
C-Strelok
Member

Откуда: Саянск (Иркутская область), ОАО "СаянскХимпласт"
Сообщений: 631
Обращаюсь на форум как на последнюю инстанцию:

Есть отчёт (xls), из него происходит обращение к хранимым процедурам (процедур несколько).
Public cnn1 As ADODB.Connection

Public rs1  As ADODB.Recordset
Public cmd1  As ADODB.Command

Public rs2  As ADODB.Recordset
Public cmd2  As ADODB.Command

Set cmd1 = New ADODB.Command
cmd1.CommandType = adCmdStoredProc
cmd1.ActiveConnection = cnn1
cmd1.CommandText = "logistic.otg_sald"

Set cmd2 = New ADODB.Command
cmd2.CommandType = adCmdStoredProc
cmd2.ActiveConnection = cnn1
cmd2.CommandText = "logistic.otg_sald_free_pp"
Данные процедуры результат возвращают посредством: TYPE cursorType IS REF CURSOR;
----------
В чём собственно проблема:

- первая процедура(ogistic.otg_sald) возвращает список контрагентов по которым есть неоплаченные счёта-фактуры
- вторая процедура(logistic.otg_sald_free_pp) возвращает список контрагентов у которых есть оплата

В обоих рекордсетах есть наименование контрагента, причём одно и тоже наименование встречается несколько раз.

???????????????????????????????????
возможно ли как то получить курсор или рекордсет который будет содержать DISTINCT по наименованиям контрагентов, то есть, просто список без дубликатов и с одним полем?

Идея:во время выполнения первой и второй процедур, в момент заполнения, или после заполнения возвратного refcursor, обратиться к нему и записывать значения наименования контрагентов в отдельный курсор или pl/sql-таблицу, но не могу сообразить как это сделать.

Может у кого есть какие идеи?
Можно ли как то делать select distinct contr_name from ref_cursor?

ps: и как то так вот,.... непонятно - оно работает :)
11 май 10, 12:19    [8753008]     Ответить | Цитировать Сообщить модератору
 Re: фильтрация курсоров  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
C-Strelok,

процедуры на сервере поправьте/(напишите новые)
а именно - в каждый запрос добавьте соответствующую группировку.
11 май 10, 18:38    [8756515]     Ответить | Цитировать Сообщить модератору
 Re: фильтрация курсоров  [new]
C-Strelok
Member

Откуда: Саянск (Иркутская область), ОАО "СаянскХимпласт"
Сообщений: 631
orawish, несколько не понял что вы имеете в виду:
- "процедуры на сервере поправьте/(напишите новые)"
- "в каждый запрос добавьте соответствующую группировку.", что значит соответствующую группировку?

Мне бы хотелось после выполнения "open reference" обработать результат в курсоре REFERENCE, - получить на базе этого курсора другой курсор но с одним полем "cnt03_cnt01_id", те что то типа такого:
open reference2 for select distinct cnt03_cnt01_id from cursor(reference)
Мне просто нужно получить distinct список контрагентов, который я буду обрабатывать в макросе экселя. Конечно можно написать ещё один селект в котором будут выбираться только distinct контрагенты, но это же дополнительный запрос, + процедур аналогичных приведённой ниже у меня "пять" штук, и запросы в них не из лёгких, - очень большой объём результирующих данных.

вот пример одной из процедур которая возвращает refcursor в excel:
PROCEDURE otg_sald_free_pp (company IN INTEGER, customer IN VARCHAR2, p_type IN VARCHAR2, end_date IN DATE, p_curr IN NUMBER, REFERENCE OUT logistic.cursortype)
   AS
   BEGIN
      OPEN REFERENCE FOR
         SELECT   cnt03_cnt01_id,
                  dtp_code,
                  doc_num,
                  doc_date,
                  curr_sum,
                  name1,
                  alone,
                  op_id,
                  transfer,
                  logistic_units.get_bd_dh_by_pp (op_id, ' - ') bd_dh_info,
                  cr_iso,
                  DECODE (cr_iso, 'RUR', 0, logistic_units.course_difference (op_id, curr_sum, cr_iso, doc_date, end_date)) cur_rz   -- курсовая разница по данному документу
             FROM (SELECT   bnk50.cnt03_cnt01_id,
                            DECODE (opd.cr_iso, 'RUR', '', '$>') || 'ВПП' dtp_code,
                            opd.doc_num doc_num,
                            opd.doc_date doc_date,
                            SUM (op_is.curr_sum * DECODE (p_curr, 0, opd.curr_rate, 1)) curr_sum,
                            logistic_units.get_name_contragent_by_id (bnk50.cnt03_cnt01_id) name1,
                            NVL (logistic_units.check_in_invoice (company, bnk50.cnt03_cnt01_id, p_type, end_date), 0) alone,
                            opd.ID op_id,
                            (opd.curr_sum - SUM (op_is.curr_sum)) * DECODE (p_curr, 0, opd.curr_rate, 1) transfer,
                            opd.cr_iso
                       FROM op_docs opd,
                            bnk_50_all_docs bnk50,
                            op_items_sum op_is,
                            op_items_using op_iu,
		                    (SELECT *
                               FROM TABLE (CAST (boss_cxp.group_type_schf_stu (p_type || ',') AS boss_cxp.vtable_char))) dtp_rec
                      WHERE DECODE (opd.cr_iso, 'RUR', 0, 1) = p_curr
                        AND NOT EXISTS (SELECT 1
                                          FROM mtm_op_history_links mol
                                         WHERE mol.doc_type_name <> 'БУХ_СПР'
                                           AND mol.op_id = opd.ID
                                           AND mol.reg_date <= end_date
                                           AND scf_dtp_code not in  ('СЧ.ФК.РС.Ф', 'СЧФ.ППЛ.Ф'))
                        AND opd.dtp_code = 'ВПП'
                        AND opd.cnt_company_id = company
                        AND bnk50.ID = opd.ID
			AND op_is.op_02_id = opd.ID
                        AND op_iu.op_41_id = op_is.op_41_id
                        AND op_iu.dtp_code = dtp_rec.column_value
                        AND opd.doc_date <= end_date
                   GROUP BY bnk50.cnt03_cnt01_id,
                            DECODE (opd.cr_iso, 'RUR', '', '$>') || 'ВПП',
                            opd.doc_num,
                            opd.doc_date,
                            logistic_units.get_name_contragent_by_id (bnk50.cnt03_cnt01_id),
                            NVL (logistic_units.check_in_invoice (company, bnk50.cnt03_cnt01_id, p_type, end_date), 0),
                            opd.ID,
                            opd.curr_sum,
                            opd.curr_rate,
                            opd.cr_iso
---------------------------------------
                   UNION ALL
---------------------------------------
                   SELECT   cs02.cnt03_cnt01_id,
                            DECODE (opd.cr_iso, 'RUR', '', '$>') || 'ПКО' dtp_code,
                            opd.doc_num doc_num,
                            opd.doc_date doc_date,
                            SUM (op_is.curr_sum * DECODE (p_curr, 0, opd.curr_rate, 1)) curr_sum,
                            logistic_units.get_name_contragent_by_id (cs02.cnt03_cnt01_id) name1,
                            NVL (logistic_units.check_in_invoice (company, cs02.cnt03_cnt01_id, p_type, end_date), 0) alone,
                            opd.ID op_id,
                            (opd.curr_sum - SUM (op_is.curr_sum)) * DECODE (p_curr, 0, opd.curr_rate, 1) transfer,
                            opd.cr_iso
                       FROM op_docs opd,
                            cs_02_receipt_orders cs02,
                            op_items_sum op_is,
                            op_items_using op_iu,
                            (SELECT *
                               FROM TABLE (CAST (boss_cxp.group_type_schf_stu (p_type || ',') AS boss_cxp.vtable_char))) dtp_rec
                      WHERE DECODE (opd.cr_iso, 'RUR', 0, 1) = p_curr
                        AND NOT EXISTS (SELECT 1
                                          FROM mtm_op_history_links mol
                                         WHERE opd.ID = mol.op_id
                                           AND mol.reg_date <= end_date
                                           AND scf_dtp_code not in  ('СЧ.ФК.РС.Ф', 'СЧФ.ППЛ.Ф'))
                        AND opd.cnt_company_id = company
                        AND opd.dtp_code = 'ПКО'
                        AND cs02.ID = opd.ID
                        AND op_is.op_02_id = opd.ID
                        AND op_iu.op_41_id = op_is.op_41_id
                        AND op_iu.dtp_code = dtp_rec.column_value
                        AND opd.doc_date <= end_date
                   GROUP BY cs02.cnt03_cnt01_id,
                            DECODE (opd.cr_iso, 'RUR', '', '$>') || 'ПКО',
                            opd.doc_num,
                            opd.doc_date,
                            logistic_units.get_name_contragent_by_id (cs02.cnt03_cnt01_id),
                            NVL (logistic_units.check_in_invoice (company, cs02.cnt03_cnt01_id, p_type, end_date), 0),
                            opd.ID,
                            opd.curr_sum,
                            opd.curr_rate,
                            opd.cr_iso)
         ORDER BY name1;
END otg_sald_free_pp;
12 май 10, 06:56    [8757796]     Ответить | Цитировать Сообщить модератору
 Re: фильтрация курсоров  [new]
suPPLer
Member

Откуда: Харків, Україна
Сообщений: 7794
Блог
C-Strelok
Мне бы хотелось после выполнения "open reference" обработать результат в курсоре REFERENCE


Обработайте в макросе Excel. Вы итеративно там обрабатываете данные этих двух ссылочных курсоров? Вот и пишите в цикле в какой-нибудь массив данные контрагентов.
12 май 10, 12:05    [8759458]     Ответить | Цитировать Сообщить модератору
 Re: фильтрация курсоров  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
C-Strelok
orawish, несколько не понял что вы имеете в виду:
- "процедуры на сервере поправьте/(напишите новые)"
- "в каждый запрос добавьте соответствующую группировку.", что значит соответствующую группировку?

Мне бы хотелось после выполнения "open reference" обработать результат в курсоре REFERENCE, - получить на базе этого курсора другой курсор но с одним полем "cnt03_cnt01_id", те что то типа такого:
..[/src]


сделать курсор из курсора у вас не получится.
можно сделать курсор на основе (модификации текста) запроса другого курсора.

declare
  c1 sys_refcursor;
  c2 sys_refcursor;
  a_sql varchar2(500) := 'select * from scott.emp';
begin
  open c1 for a_sql;
  open c2 for 'select distinct deptno from ('||a_sql||')';
end;
12 май 10, 12:17    [8759556]     Ответить | Цитировать Сообщить модератору
 Re: фильтрация курсоров  [new]
C-Strelok
Member

Откуда: Саянск (Иркутская область), ОАО "СаянскХимпласт"
Сообщений: 631
orawish


сделать курсор из курсора у вас не получится.
можно сделать курсор на основе (модификации текста) запроса другого курсора.

declare
  c1 sys_refcursor;
  c2 sys_refcursor;
  a_sql varchar2(500) := 'select * from scott.emp';
begin
  open c1 for a_sql;
  open c2 for 'select distinct deptno from ('||a_sql||')';
end;


в таком случае будет два селекта, таким образом возрастёт время построения отчёта, а оно и так не маленькое.
13 май 10, 08:12    [8764904]     Ответить | Цитировать Сообщить модератору
 Re: фильтрация курсоров  [new]
C-Strelok
Member

Откуда: Саянск (Иркутская область), ОАО "СаянскХимпласт"
Сообщений: 631
В общем мои изыскания как сделать селект из курсора ни к чему не привели.
Сделал следующим образом:

в процедуру добавил тип:
TYPE TEMP_TYPE IS RECORD (
        cnt03_cnt01_id 	bnk_50_all_docs.cnt03_cnt01_id%type,
        dtp_code 	   	op_docs.dtp_code%type,
        doc_num		   	op_docs.doc_num%type,
        doc_date		op_docs.doc_date%type,
        curr_sum		op_docs.curr_sum%type,
        name1			cnt_01_hoz_subjects.name1%TYPE,
        alone 			bnk_50_all_docs.cnt03_cnt01_id%type,
        op_id			op_docs.id%type,
        curr_sum2		op_docs.curr_sum%type,
        bd_dh_info 		varchar2(2000),
        cr_iso 			op_docs.cr_iso%type,
        cur_rz			number);
	
    L_TMP TEMP_TYPE;

после выполнения:
OPEN REFERENCE FOR
         SELECT   cnt03_cnt01_id,
                  dtp_code,
                  doc_num,
                  doc_date,
                  curr_sum
...........

профетчил в L_TMP и загрузил все записи в pl/sql таблицу, НО!

появилась проблема которая заключается в том что процедура возвращает экселю ссылку на курсор "MBER, REFERENCE OUT logistic.cursortype)", а данный курсор кончился, - его профетчили...

на фоне этого вопрос: как можно вернуть состояние курсора как будто его вообще не фетчили?
13 май 10, 08:40    [8764958]     Ответить | Цитировать Сообщить модератору
 Re: фильтрация курсоров  [new]
Elic
Member

Откуда:
Сообщений: 29990
C-Strelok
как можно вернуть состояние курсора как будто его вообще не фетчили?
Никак.
13 май 10, 08:44    [8764971]     Ответить | Цитировать Сообщить модератору
 Re: фильтрация курсоров  [new]
C-Strelok
Member

Откуда: Саянск (Иркутская область), ОАО "СаянскХимпласт"
Сообщений: 631
пляяяяяяя.
Тема закрыта.
13 май 10, 09:43    [8765221]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить