Страница 2 из 3

Re: Рендеринг отчёта с разными параметрами

Добавлено: 29 янв 2016, 16:06
Леонид
Добрый день!

Итак, провели большое количество экспериментов. В результате понять, что является причиной такого поведения не удалось. Напомню, что проблемы есть только с переменными (объявленные в Dictionary), и именно, когда им присваиваются значения из полей DataSource.

В двух словах, у нас есть отчёт (они разные, Торг-12, Счёт-фактура и пр.), в нём есть переменная FacturaCaption1 типа String. Эту переменную инициализируем в событии BeforePrint, её значения выводятся, но не на каждой странице корректно, т.е., на первой странице выводит номер накладной и её дата, на второй нет, на третей нормально, и так рандомно, - так и не понял почему.
Сам отчёт максимально упростил до трёх полей, и вот какую корелляцию обнаружил, когда данные выбираются из таблицы DUAL адаптера StiOracleSource, то всё выбирается корректно, а когда меняю select на наш обычный, то происходит этот самый "рандомный" баг. Возможно, это не баг, а мы чего-то не знаем, но думаю, что причина всё-таки именно в адаптере данных Oracle в самом отчёте.

К слову, сказать, что пробовали, реально, всё что знаем, в т.ч. и печатать, как EndOfPage, но не помогает.

Для наглядности покажу код при котором корректно работает отчёт (он тоже будет во вложении) и при котором не работает.

1) Некорректная работа при вызове кода:

Код: Выделить всё

SELECT *
  FROM TABLE(DOCUMENTS_REPORTS_PKG.REP_FACTURA(:DOC_CODE, null))
Реальный код процедуры в базе:

Код: Выделить всё

  FUNCTION REP_FACTURA(in_DOC_CODE IN NUMBER, 
                       in_FACTURA_CODE IN NUMBER DEFAULT NULL) RETURN TAB_REP_FACTURA PIPELINED
  AS
    v_rec REC_REP_FACTURA := REC_REP_FACTURA(null, null, null, null, null, null, null, null, null, null, 
                                             null, null, null, null, null, null, null, null, null, null, 
                                             null, null, null, null, null, null, null, null, null, null, 
                                             null, null, null, null, null, null, null, null, null, null,
                                             null, null, null, null, null, null, null, null);   
    v_currency_code NUMBER(15);        
    v_is_blocked    VARCHAR2(1) := 'N';            
    v_prev_factura_code NUMBER(15);     
    v_voucher_doc_date  DATE;  
    v_doc_currency_code NUMBER(15);      
    v_factura_code NUMBER(15) := in_FACTURA_CODE;     
    v_param NUMBER(15);
    v_last_cor_factura_num NUMBER(15);
    
    CURSOR cur_factura IS
      SELECT cf.FACTURA_CODE
        FROM corrective_factura cf
       WHERE cf.DOC_CODE = in_DOC_CODE
         AND cf.FACTURA_CODE < v_factura_code         
         AND cf.FACTURA_TYPE = 2
    ORDER BY cf.FACTURA_CODE DESC;
    
  BEGIN
    -- Получаем данные по валюте
    SELECT c.CURRENCY_CODE, c.CURRENCY_NAME, c.INTERNATIONAL_CODE
      INTO v_currency_code, v_rec.CURRENCY_NAME, v_rec.CURRENCY_INTERNATIONAL_CODE
      FROM currency c
     WHERE c.F_NATIONAL_CURRENCY = 'Y';  
    
    -- Находим данные по СФ 
    IF (v_factura_code IS NULL) THEN
      SELECT v.FACTURA_CODE
        INTO v_factura_code
        FROM vouchers v 
       WHERE v.DOC_CODE = in_DOC_CODE;
    END IF;
    
    IF (v_factura_code IS NULL) THEN 
      RAISE err_pkg.e_document_not_found;
    END IF;
    
    
    -- Проверяем, были ли корректировочные сф до текущей СФ
    OPEN cur_factura;
    FETCH cur_factura INTO v_param;
    v_rec.USE_CORRECTIVE_FACTURA := (case when cur_factura%FOUND then 'Y' else 'N' end);
    CLOSE cur_factura; 
    
    -- Если были корректировочные СФ, то находим последнюю
    IF v_rec.USE_CORRECTIVE_FACTURA = 'Y' THEN
      SELECT cf.FACTURA_NUM, cf.FACTURA_DATE
        INTO v_last_cor_factura_num, v_rec.LAST_COR_FACTURA_DATE
        FROM corrective_factura cf
       WHERE cf.FACTURA_CODE = v_param;  
    END IF;
    
           
    FOR curr IN (SELECT cf2.FACTURA_CODE as PREV_FACTURA_CODE,
                        cf.IS_BLOCKED,
                        cf.FACTURA_NUM || (case when cf.FACTURA_TYPE <> 1 then org.DOC_INFORMATION end) as FACTURA_NUM_DET,
                        cf.FACTURA_DATE  as FACTURA_DATE,
                        cf.FACTURA_TYPE  as FACTURA_TYPE,
                        cf2.FACTURA_NUM || (case when cf2.FACTURA_TYPE <> 1 then org.DOC_INFORMATION end) as PREV_FACTURA_NUM_DET,
                        cf2.FACTURA_DATE as PREV_FACTURA_DATE,
                        cf2.FACTURA_TYPE as  PREV_FACTURA_TYPE,            
                        cf1.FACTURA_NUM || org.DOC_INFORMATION  as ORIGINAL_FACTURA_NUM_DET,
                        cf1.FACTURA_DATE  as ORIGINAL_FACTURA_DATE,
                        cf.NOTE,
                        v.GOODS,
                        v.DOC_DATE,
                        v.CURRENCY_CODE,
                        c.PROPERTY || ' ' || c.CLIENT_NAME as CLIENT_NAME,
                        (case when c.is_carry = 'Y' then '' else 'X' end) as IS_CARRY,
                        clients_pkg.SELECT_CLIENT_ADDRESS(c.CLIENT_CODE) || (case when c.PHONE IS NULL then '' else ' Телефон ' end) || NVL(c.PHONE, '') as CLIENT_ADDRESS,
                        clients_pkg.SELECT_CLIENT_ADDRESS2(c.CLIENT_CODE) as CLIENT_ADDRESS2, 
                        c.INN as CLIENT_INN,
                        c.OKPO as CLIENT_OKPO,
                        c.KPP as CLIENT_KPP,

                        TRIM(NVL(c.INN_KPP_FACTURA, '')) as INN_KPP_FACTURA,
                        TRIM(NVL(c.ADDRESS_BUYER_FACTURA, '')) as ADDRESS_BUYER_FACTURA,
                        TRIM(NVL(c.SENDER_FACTURA, '')) as SENDER_FACTURA,
                        TRIM(NVL(c.RECIPIENT_FACTURA, '')) as RECIPIENT_FACTURA,
                        TRIM(NVL(c.BUYER_FACTURA, '')) as BUYER_FACTURA,

                        'Банк ' || cb.BANK_NAME || ' БИК ' || cb.BIC || ' р/с ' || cb.ACCOUNT || ' к/с '|| cb.COR_ACCOUNT as CLIENT_BANK,
                        fi.PROPERTY || ' ' || fi.FIRM_NAME as SUPPLIER_NAME, 
                        NVL(fi.ADDRESS, '') || (case when fi.PHONE IS NULL then '' else ' Телефон ' end) || NVL(fi.PHONE, '') as SUPPLIER_ADDRESS,
                        fi.ADDRESS2 as  SUPPLIER_ADDRESS2,
                        fi.OKPO as SUPPLIER_OKPO,
                        fi.INN as SUPPLIER_INN,
                        fi.KPP as SUPPLIER_KPP,                       
                        orgg.ACCOUNTANT_NAME,
                        orgg.CHIEF_NAME,
                        org.DOC_INFORMATION
                   FROM corrective_factura cf
                        inner join vouchers v on v.DOC_CODE = cf.DOC_CODE
                        inner join corrective_factura cf1 on cf1.FACTURA_CODE = v.FIRST_FACTURA_CODE
                        inner join organization org on org.ORG_CODE = v.ORG_CODE 
                        inner join firms fi on v.MY_FIRM = fi.FIRM_CODE
                        inner join clients c on c.CLIENT_CODE = v.CLIENT_CODE
                        inner join rds$users r_us on r_us.USER_NAME = utils_pkg.C_USER_NAME
                        inner join rds$access_organizations orgg on orgg.USER_CODE = r_us.USER_CODE AND orgg.ORG_CODE = v.ORG_CODE
                        left join firm_banks fb on fb.BANK_CODE = c.FIRM_BANK_CODE
                        left join client_banks cb on c.BANK_CODE = cb.BANK_CODE
                        left join corrective_factura cf2 on cf2.FACTURA_CODE = cf.PREV_FACTURA_CODE       
                  WHERE cf.FACTURA_CODE = v_factura_code) 
    LOOP    
      v_rec.USE_CORRECTIVE_FACTURA := (case when curr.FACTURA_TYPE = 2 then 'Y' else v_rec.USE_CORRECTIVE_FACTURA end);
      v_prev_factura_code   := curr.PREV_FACTURA_CODE;
      v_is_blocked          := curr.IS_BLOCKED;
      v_rec.FACTURA_NUM_DET := curr.FACTURA_NUM_DET;
      v_rec.FACTURA_DATE    := curr.FACTURA_DATE;
      v_rec.FACTURA_TYPE    := curr.FACTURA_TYPE;
      v_rec.PREV_FACTURA_NUM_DET  := curr.PREV_FACTURA_NUM_DET;
      v_rec.PREV_FACTURA_DATE     := curr.PREV_FACTURA_DATE;
      v_rec.PREV_FACTURA_TYPE     := curr.PREV_FACTURA_TYPE;           
      v_rec.ORIGINAL_FACTURA_NUM_DET := curr.ORIGINAL_FACTURA_NUM_DET;
      v_rec.ORIGINAL_FACTURA_DATE := curr.ORIGINAL_FACTURA_DATE;
      v_rec.LAST_COR_FACTURA_NUM_DET := v_last_cor_factura_num || curr.DOC_INFORMATION;
            
      v_rec.NOTE     := curr.NOTE;
      v_rec.IS_CARRY := curr.IS_CARRY;
      
      v_voucher_doc_date  := curr.DOC_DATE;
      v_doc_currency_code := curr.CURRENCY_CODE;
                  
      IF curr.GOODS = 'приход' THEN
        v_rec.RECIPIENT_FACTURA := (case when LENGTH(curr.SENDER_FACTURA) > 1 then curr.SENDER_FACTURA else curr.SUPPLIER_NAME || curr.SUPPLIER_ADDRESS end);   --Строка грузополучателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.SENDER_FACTURA    := (case when LENGTH(curr.RECIPIENT_FACTURA) > 1 then curr.RECIPIENT_FACTURA else curr.CLIENT_NAME || curr.CLIENT_ADDRESS end); --Строка грузоотправителя в СЧЕТЕ-ФАКТУРЕ  
        v_rec.ADDRESS_BUYER_FACTURA := curr.SUPPLIER_ADDRESS;                                                                                                   --Строка адреса покупателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.BUYER_FACTURA   := curr.SUPPLIER_NAME;                                                                                                            --Строка покупателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.INN_KPP_FACTURA := (case when LENGTH(curr.INN_KPP_FACTURA) > 1 then curr.INN_KPP_FACTURA else curr.SUPPLIER_INN || '/' || curr.SUPPLIER_KPP end); --Строка ИНН/КПП покупателя в СЧЕТЕ-ФАКТУРЕ 
        
        v_rec.SUPPLIER_NAME := curr.CLIENT_NAME;
        v_rec.SUPPLIER_ADDRESS := curr.CLIENT_ADDRESS;
        v_rec.SUPPLIER_INN := curr.CLIENT_INN;

        v_rec.CLIENT_NAME := curr.SUPPLIER_NAME ;
        v_rec.CLIENT_ADDRESS := curr.SUPPLIER_ADDRESS;
        v_rec.CLIENT_ADDRESS2 := curr.SUPPLIER_ADDRESS2;
        v_rec.CLIENT_INN := curr.SUPPLIER_INN;

      ELSIF curr.GOODS = 'расход' THEN 
        v_rec.RECIPIENT_FACTURA := (case when LENGTH(curr.RECIPIENT_FACTURA) > 1 then curr.RECIPIENT_FACTURA else curr.CLIENT_NAME || curr.CLIENT_ADDRESS2 end); --Строка грузополучателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.SENDER_FACTURA    := (case when LENGTH(curr.SENDER_FACTURA) > 1 then curr.SENDER_FACTURA else curr.SUPPLIER_NAME || curr.SUPPLIER_ADDRESS2 end);   --Строка грузоотправителя в СЧЕТЕ-ФАКТУРЕ
        v_rec.ADDRESS_BUYER_FACTURA := (case when LENGTH(curr.ADDRESS_BUYER_FACTURA) > 1 then curr.ADDRESS_BUYER_FACTURA else curr.CLIENT_ADDRESS end);          --Строка адреса покупателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.BUYER_FACTURA     := (case when LENGTH(curr.BUYER_FACTURA) > 1 then curr.BUYER_FACTURA else curr.CLIENT_NAME end);                                 --Строка покупателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.INN_KPP_FACTURA   := (case when LENGTH(curr.INN_KPP_FACTURA) > 1 then curr.INN_KPP_FACTURA else curr.CLIENT_INN || '/' || curr.CLIENT_KPP end);    --Строка ИНН/КПП покупателя в СЧЕТЕ-ФАКТУРЕ  
        
        v_rec.SUPPLIER_NAME := 'Общество с ограниченной ответственностью "САКС Игрушки", ' || curr.SUPPLIER_NAME ;
        v_rec.SUPPLIER_ADDRESS := curr.SUPPLIER_ADDRESS;
        v_rec.SUPPLIER_INN := curr.SUPPLIER_INN || '/' || curr.SUPPLIER_KPP;

        v_rec.CLIENT_NAME := curr.CLIENT_NAME;
        v_rec.CLIENT_ADDRESS := curr.CLIENT_ADDRESS;
        v_rec.CLIENT_ADDRESS2 := curr.CLIENT_ADDRESS2;
        v_rec.CLIENT_INN := curr.CLIENT_INN;
        
        v_rec.CHIEF_ACCOUNTANT_NAME := curr.ACCOUNTANT_NAME;
        v_rec.CHIEF_NAME := curr.CHIEF_NAME;

      END IF;
    END LOOP;                     
                  
    FOR curr IN (SELECT g.WARE_NAME, 
                        g.PRODUCER_CODE, 
                        g.ARTICLE, 
                        z.QUANTITY, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.F_PRICE) as N_PRICE, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.F_SUM)   as N_SUM,
                        z.NDS, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.F_SUM_NDS)   as N_SUM_NDS,                
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.F_TOTAL_SUM) as N_TOTAL_SUM, 
                        z.WARE_CODE, 
                        z.NUMBER_GTD,
                        z.OLD_QUANTITY, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.OLD_F_PRICE) as OLD_N_PRICE, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.OLD_F_SUM)   as OLD_N_SUM, 
                        z.OLD_NDS,
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.OLD_F_SUM_NDS) as OLD_N_SUM_NDS, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.OLD_F_TOTAL_SUM)   as OLD_N_TOTAL_SUM,                 
                        cs.COUNTRY_NAME,
                        cs.INTERNATIONAL_CODE as COUNTRY_INTERNATIONAL_CODE
                  FROM (SELECT t.WARE_CODE,  
                               NVL(MAX(t.COUNTRY_CODE), MAX(t.OLD_COUNTRY_CODE)) as COUNTRY_CODE,  
                               SUM(t.QUANTITY) as QUANTITY,  
                               SUM(t.F_PRICE) as F_PRICE,  
                               SUM(t.F_SUM) as F_SUM,   
                               MAX(t.NDS) as NDS,  
                               SUM(t.F_SUM_NDS) as F_SUM_NDS,  
                               SUM(t.F_TOTAL_SUM) as F_TOTAL_SUM, 
                               NVL(MAX(t.NUMBER_GTD), MAX(t.OLD_NUMBER_GTD)) as NUMBER_GTD, 
                               SUM(t.OLD_QUANTITY) as OLD_QUANTITY, 
                               SUM(t.OLD_F_PRICE) as OLD_F_PRICE, 
                               SUM(t.OLD_F_SUM) as OLD_F_SUM, 
                               MAX(t.OLD_NDS) as OLD_NDS,
                               SUM(t.OLD_F_SUM_NDS) as OLD_F_SUM_NDS, 
                               SUM(t.OLD_F_TOTAL_SUM) as OLD_F_TOTAL_SUM          
                         FROM (SELECT cfa.WARE_CODE,             
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then NULL else cfa.COUNTRY_CODE end) as COUNTRY_CODE,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then 0 else cfa.QUANTITY    end) as QUANTITY,
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then 0 else cfa.F_PRICE     end) as F_PRICE,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then 0 else cfa.F_SUM       end) as F_SUM,   
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then NULL else cfa.NDS      end) as NDS,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then 0 else cfa.F_SUM_NDS   end) as F_SUM_NDS,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then 0 else cfa.F_TOTAL_SUM end) as F_TOTAL_SUM, 
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then NULL else cfa.NUMBER_GTD end) as NUMBER_GTD,
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.QUANTITY    else 0  end) as OLD_QUANTITY,
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.F_PRICE     else 0  end) as OLD_F_PRICE,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.F_SUM       else 0  end) as OLD_F_SUM,   
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.NDS         else NULL end) as OLD_NDS,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.F_SUM_NDS   else 0  end) as OLD_F_SUM_NDS,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.F_TOTAL_SUM else 0  end) as OLD_F_TOTAL_SUM,
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.COUNTRY_CODE else NULL end) as OLD_COUNTRY_CODE, 
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.NUMBER_GTD   else NULL end) as OLD_NUMBER_GTD      
                                 FROM corrective_factura_assort cfa  
                                WHERE cfa.FACTURA_CODE = v_prev_factura_code
                                   OR cfa.FACTURA_CODE = v_factura_code AND v_is_blocked = utils_pkg.C_YES 
                             union all
                               SELECT a.WARE_CODE,  
                                      a.COUNTRY_CODE,  
                                      a.QUANTITY,  
                                      a.F_PRICE,  
                                      a.F_SUM,   
                                      a.NDS,  
                                      a.F_SUM_NDS,  
                                      a.F_TOTAL_SUM, 
                                      a.NUMBER_GTD, 
                                      0 as OLD_QUQNTITY, 
                                      0 as OLD_F_PRICE, 
                                      0 as OLD_F_SUM, NULL as OLD_NDS, 
                                      0 as OLD_F_SUM_NDS, 
                                      0 as OLD_F_TOTAL_SUM,
                                      NULL as OLD_COUNTRY_CODE,
                                      NULL as OLD_NUMBER_GTD
                                 FROM assortments a      
                                WHERE a.DOC_CODE = in_DOC_CODE 
                                  AND v_is_blocked = utils_pkg.C_NO) t 
                     GROUP BY t.WARE_CODE) z          
                       inner join goods g on z.WARE_CODE = g.WARE_CODE
                       inner join countries cs on z.COUNTRY_CODE = cs.COUNTRY_CODE        
               ORDER BY g.PRODUCER_CODE, 
                        g.ARTICLE) 
    LOOP
      v_rec.WARE_NAME := curr.WARE_NAME;
      v_rec.ARTICLE := curr.ARTICLE;
      v_rec.QUANTITY := curr.QUANTITY;
      v_rec.PRICE := curr.N_PRICE;
      v_rec.SUM_ := curr.N_SUM;
      v_rec.NDS := curr.NDS;
      v_rec.SUM_NDS := curr.N_SUM_NDS;
      v_rec.TOTAL_SUM := curr.N_TOTAL_SUM;
      v_rec.OLD_QUANTITY := curr.OLD_QUANTITY;
      v_rec.OLD_PRICE := curr.OLD_N_PRICE;
      v_rec.OLD_SUM_ := curr.OLD_N_SUM;
      v_rec.OLD_NDS := curr.OLD_NDS;
      v_rec.OLD_SUM_NDS := curr.OLD_N_SUM_NDS;
      v_rec.OLD_TOTAL_SUM := curr.OLD_N_TOTAL_SUM;
      v_rec.NUMBER_GTD := curr.NUMBER_GTD;
      v_rec.COUNTRY_NAME := curr.COUNTRY_NAME;
      v_rec.COUNTRY_INTERNATIONAL_CODE := curr.COUNTRY_INTERNATIONAL_CODE;
      PIPE ROW(v_rec);
    END LOOP;                        
  END REP_FACTURA;
И её типы (Types):

Код: Выделить всё

CREATE OR REPLACE TYPE MERCHANT.REC_REP_FACTURA AS OBJECT(
    FACTURA_NUM_DET NVARCHAR2(20),
    FACTURA_DATE    DATE,
    FACTURA_TYPE    NUMBER(1),
    PREV_FACTURA_NUM_DET NVARCHAR2(20),
    PREV_FACTURA_DATE DATE,
    PREV_FACTURA_TYPE NUMBER(1),          
    ORIGINAL_FACTURA_NUM_DET NVARCHAR2(20),
    ORIGINAL_FACTURA_DATE DATE,    
    LAST_COR_FACTURA_NUM_DET NVARCHAR2(20),
    LAST_COR_FACTURA_DATE DATE,
    SUPPLIER_NAME NVARCHAR2(200),
    SUPPLIER_ADDRESS NVARCHAR2(200),
    SUPPLIER_ADDRESS2 NVARCHAR2(200),
    SUPPLIER_INN NVARCHAR2(100),
    CLIENT_NAME NVARCHAR2(200),
    IS_CARRY VARCHAR2(1),
---------
    INN_KPP_FACTURA NVARCHAR2(1000),
    ADDRESS_BUYER_FACTURA NVARCHAR2(1000),
    SENDER_FACTURA NVARCHAR2(1000),
    RECIPIENT_FACTURA NVARCHAR2(1000),
    BUYER_FACTURA NVARCHAR2(1000),
---------
    CLIENT_ADDRESS NVARCHAR2(200),
    CLIENT_ADDRESS2 NVARCHAR2(253),
    CLIENT_INN NVARCHAR2(100),
    CLIENT_KPP NVARCHAR2(100),
    NOTE NVARCHAR2(300),
    WARE_NAME NVARCHAR2(200),
    ARTICLE NVARCHAR2(100),
    QUANTITY NUMBER,
    PRICE NUMBER(15,2),
    SUM_ NUMBER(15,2),
    NDS NUMBER(15,2),
    SUM_NDS NUMBER(15,2),
    TOTAL_SUM NUMBER(15,2),
    OLD_QUANTITY NUMBER,
    OLD_PRICE NUMBER(15,2),
    OLD_SUM_ NUMBER(15,2),
    OLD_NDS NUMBER(15,2),
    OLD_SUM_NDS NUMBER(15,2),
    OLD_TOTAL_SUM NUMBER(15,2),
    NUMBER_GTD NVARCHAR2(100),
    CHIEF_NAME NVARCHAR2(80),
    CHIEF_ACCOUNTANT_NAME NVARCHAR2(80),
    CURRENCY_NAME NVARCHAR2(40),
    COUNTRY_NAME NVARCHAR2(40),
    CURRENCY_INTERNATIONAL_CODE NUMBER,
    COUNTRY_INTERNATIONAL_CODE NUMBER,
    USE_CORRECTIVE_FACTURA VARCHAR2(1));
/
Здесь и далее можно упростить до 3-х полей для наглядности: factura_date, factura_num_det и ware_name.

2) Корректная работа при вызове кода:

Код: Выделить всё

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 100'
             when :DOC_CODE = 222 then 'Игрушка 200'
             when :DOC_CODE = 333 then 'Игрушка 300'
             when :DOC_CODE = 444 then 'Игрушка 400'
             when :DOC_CODE = 555 then 'Игрушка 500'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 101'
             when :DOC_CODE = 222 then 'Игрушка 201'
             when :DOC_CODE = 333 then 'Игрушка 301'
             when :DOC_CODE = 444 then 'Игрушка 401'
             when :DOC_CODE = 555 then 'Игрушка 501'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 102'
             when :DOC_CODE = 222 then 'Игрушка 202'
             when :DOC_CODE = 333 then 'Игрушка 302'
             when :DOC_CODE = 444 then 'Игрушка 402'
             when :DOC_CODE = 555 then 'Игрушка 502'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 103'
             when :DOC_CODE = 222 then 'Игрушка 203'
             when :DOC_CODE = 333 then 'Игрушка 303'
             when :DOC_CODE = 444 then 'Игрушка 403'
             when :DOC_CODE = 555 then 'Игрушка 503'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 104'
             when :DOC_CODE = 222 then 'Игрушка 204'
             when :DOC_CODE = 333 then 'Игрушка 304'
             when :DOC_CODE = 444 then 'Игрушка 404'
             when :DOC_CODE = 555 then 'Игрушка 504'
        end) as ware_name       
  from dual

Re: Рендеринг отчёта с разными параметрами

Добавлено: 01 фев 2016, 12:53
Aleksey
Здравствуйте,
1) Некорректная работа при вызове кода:
CODE: SELECT ALL
SELECT *
FROM TABLE(DOCUMENTS_REPORTS_PKG.REP_FACTURA(:DOC_CODE, null))
Могли бы вы упростить свою процедуру и прислать тестовые данные для нее, чтобы можно было воспроизвести некорректную работу именно с процедурой.

Спасибо.

Re: Рендеринг отчёта с разными параметрами

Добавлено: 03 фев 2016, 09:38
Леонид
Доброе утро!
Могли бы вы упростить свою процедуру и прислать тестовые данные для нее, чтобы можно было воспроизвести некорректную работу именно с процедурой.
Да, конечно, там по сути, можно ограничиться тремя, думаю, даже двумя полями из одной таблицы.

Вызов процедуры:

Код: Выделить всё

  SELECT factura_date, factura_num_det и ware_name
     FROM TABLE(DOCUMENTS_REPORTS_PKG.REP_FACTURA(:DOC_CODE)
Тело процедуры:

Код: Выделить всё

FUNCTION REP_FACTURA(in_DOC_CODE IN NUMBER) RETURN TAB_REP_FACTURA PIPELINED
  AS
    v_rec REC_REP_FACTURA := REC_REP_FACTURA(null, null, null);   
  BEGIN           
    FOR curr IN (SELECT cf.FACTURA_NUM_DET,
                        cf.FACTURA_DATE,
                        cf.WARE_NAME
                   FROM corrective_factura cf
                        inner join goods g on g.WARE_CODE = cf.WARE_CODE
                  WHERE cf.FACTURA_CODE = :in_DOC_CODE)
    LOOP    
      v_rec.FACTURA_NUM_DET := curr.FACTURA_NUM_DET;
      v_rec.FACTURA_DATE    := curr.FACTURA_DATE;
      v_rec.WARE_NAME       := curr.WARE_NAME;

      PIPE ROW(v_rec);
    END LOOP;
  END REP_FACTURA;
Типы данных для процедуры:

Код: Выделить всё

CREATE OR REPLACE TYPE MERCHANT.REC_REP_FACTURA AS OBJECT(
    FACTURA_NUM_DET NVARCHAR2(20),
    FACTURA_DATE    DATE,
    WARE_NAME NVARCHAR2(200)
);

Re: Рендеринг отчёта с разными параметрами

Добавлено: 03 фев 2016, 14:15
Aleksey
Здравствуйте,

К сожалению, не хватает нескольких объектов - TAB_REP_FACTURA, DOCUMENTS_REPORTS_PKG.

Спасибо.

Re: Рендеринг отчёта с разными параметрами

Добавлено: 03 фев 2016, 14:31
Леонид
не хватает нескольких объектов - TAB_REP_FACTURA

Код: Выделить всё

CREATE OR REPLACE TYPE MERCHANT.TAB_REP_FACTURA AS TABLE OF MERCHANT.REC_REP_FACTURA;
DOCUMENTS_REPORTS_PKG

Код: Выделить всё

CREATE OR REPLACE PACKAGE BODY MERCHANT.DOCUMENTS_REPORTS_PKG AS

FUNCTION REP_FACTURA(in_DOC_CODE IN NUMBER) RETURN TAB_REP_FACTURA PIPELINED
  AS
    v_rec REC_REP_FACTURA := REC_REP_FACTURA(null, null, null);   
  BEGIN           
    FOR curr IN (SELECT cf.FACTURA_NUM_DET,
                        cf.FACTURA_DATE,
                        cf.WARE_NAME
                   FROM corrective_factura cf
                        inner join goods g on g.WARE_CODE = cf.WARE_CODE
                  WHERE cf.FACTURA_CODE = :in_DOC_CODE)
    LOOP    
      v_rec.FACTURA_NUM_DET := curr.FACTURA_NUM_DET;
      v_rec.FACTURA_DATE    := curr.FACTURA_DATE;
      v_rec.WARE_NAME       := curr.WARE_NAME;

      PIPE ROW(v_rec);
    END LOOP;
  END REP_FACTURA;

END DOCUMENTS_REPORTS_PKG;

Re: Рендеринг отчёта с разными параметрами

Добавлено: 03 фев 2016, 15:36
Aleksey
Здравствуйте,

Все закинули в базу. Получаем следующую ошибку, при выполнении запроса:

Спасибо.

Re: Рендеринг отчёта с разными параметрами

Добавлено: 03 фев 2016, 16:19
Леонид
Попробуйте создать декларацию packagе DOCUMENTS_REPORTS_PKG так:

Код: Выделить всё

CREATE OR REPLACE PACKAGE DOCUMENTS_REPORTS_PKG  AS

  FUNCTION REP_FACTURA(in_DOC_CODE IN NUMBER) RETURN TAB_REP_FACTURA PIPELINED;
END DOCUMENTS_REPORTS_PKG ;
а так же таблицу goods (т.к. есть ссылка в select'е) с полем ware_name. Данные в таблицах можно использовать те же, что из первого select'а:

Код: Выделить всё

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 100'
             when :DOC_CODE = 222 then 'Игрушка 200'
             when :DOC_CODE = 333 then 'Игрушка 300'
             when :DOC_CODE = 444 then 'Игрушка 400'
             when :DOC_CODE = 555 then 'Игрушка 500'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 101'
             when :DOC_CODE = 222 then 'Игрушка 201'
             when :DOC_CODE = 333 then 'Игрушка 301'
             when :DOC_CODE = 444 then 'Игрушка 401'
             when :DOC_CODE = 555 then 'Игрушка 501'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 102'
             when :DOC_CODE = 222 then 'Игрушка 202'
             when :DOC_CODE = 333 then 'Игрушка 302'
             when :DOC_CODE = 444 then 'Игрушка 402'
             when :DOC_CODE = 555 then 'Игрушка 502'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 103'
             when :DOC_CODE = 222 then 'Игрушка 203'
             when :DOC_CODE = 333 then 'Игрушка 303'
             when :DOC_CODE = 444 then 'Игрушка 403'
             when :DOC_CODE = 555 then 'Игрушка 503'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 104'
             when :DOC_CODE = 222 then 'Игрушка 204'
             when :DOC_CODE = 333 then 'Игрушка 304'
             when :DOC_CODE = 444 then 'Игрушка 404'
             when :DOC_CODE = 555 then 'Игрушка 504'
        end) as ware_name       
  from dual

Re: Рендеринг отчёта с разными параметрами

Добавлено: 03 фев 2016, 16:24
Леонид
Ах да, забыл сказать, что мы пробовали "завернуть" этот простой select (из DUAL), возвращающий 5 строк в функцию, - в результате всё работает, как и в случае с вашим первым примером, т.е. не работает что-то именно при выборе из package.

Re: Рендеринг отчёта с разными параметрами

Добавлено: 03 фев 2016, 16:26
Леонид
Кстати, у вас на скриншоте ...REP_FACTURA(in_DOC_CODE, null) - это неверно, т.к. второго параметра нет, посмотрите, там в предыдущем посте коротенькая процедура с единственным входным параметром.

Re: Рендеринг отчёта с разными параметрами

Добавлено: 04 фев 2016, 10:48
Aleksey
Здравствуйте, Леонид

Все заработало. Но проблему так и не смогли воспроизвести.
Пожалуйста, посмотрите может мы не так заполнили данными таблицу.

Спасибо.