2016-07-31 4 views
0

У меня возникла проблема с записью рекурсивной таблицы в DB2.DB2 recursive UDF Table

У меня есть таблица значений ....

With t (Adjustment) as (
VALUES (100) 
    , (200) 
    , (300) 
) select * from t; 

мне нужно перейти к таблице UDF функционировать значение открытия (скажем, 5000) и фактор (скажем, 0,1)

мне нужно чтобы показать результат следующим образом ....

Opening Shift Adjustment Closing 
(3)  (1)  (2) 
================================================== 
5000 500  100  5600    
5600 560  200  6360 
6360 636  300  7296 
  1. Shift = Открытие * 0,1
  2. Закрытие = Открытие + Shift + Закрытие
  3. Открытие является закрытие предыдущего ряда

Моя рекурсивная функция застревает, когда я пытался принести перенесенный ... (SQL0345N Полная выборка рекурсивного общего табличного выражения)

Цените любую идею, как это сделать. Я знаю, что хранимая процедура может это сделать, но мне нужно использовать UDF, чтобы он мог быть расширен в другом UDF.

+0

Что определяет сопоставление данных в таблице T так, что может быть определена _прерывная строка_; row_number() over() без особого порядка? Кроме того, 2) в ОП определяется как «Открытие + Сдвиг + Закрытие», но ясно, согласно результатам, выражение должно быть «Открытие + Сдвиг + Коррекция» – CRPence

ответ

1

Я не уверен, если я интерпретировал сценарий правильно, но вот что я сделал:

Для начала, я создать несколько переменных, чтобы имитировать вход в функцию, а затем составить выражение Рекурсивный Common Table (РКТО) для создания отчета с использованием данных, полученных от этих переменных:

create variable OpenedWith decimal  default 5000  
; 
create variable Factor  decimal(2, 1) default 0.1 
; 


with               
    t (adjustment) as (values(100), (200), (300))    
, ordRows (rn, Adjustment) as         
    (select row_number() over(), Adjustment from t)   
, addRows (rn, Opening, Shift, Adjustment, closing) as   
    (select rn, OpenedWith, OpenedWith*Factor , Adjustment  
      , (OpenedWith + (OpenedWith*Factor) + Adjustment) 
     from ordRows            
     where rn = 1            
    union all             
     select b.rn, a.Closing, a.Closing * Factor , b.Adjustment 
      , (a.Closing + (a.Closing * Factor) + b.Adjustment) 
     from addRows a            
     join ordRows b            
     on a.rn = (b.rn - 1)         
    )               
select int(rn) as rn, int(opening) as opening 
     , int(shift) as shift, adjustment  
     , int(closing) as closing    
from addRows         


Ниже приводится отчет из приведенного выше запроса:

RN   OPENING   SHIFT  ADJUSTMENT   CLOSING 
    1   5,000    500    100   5,600 
    2   5,600    560    200   6,360 
    3   6,360    636    300   7,296 

И теперь, чтобы изменить вышеуказанные скриптовые переменные творения и запрос в User Defined Table Function (UDTF), который работает с данными в таблице с именем T:

create function shifted_vals 
    (OpenedWith decimal(5)  
    , Factor  decimal(3, 2) 
)        
    returns table     
    (Opening  int   
    , Shift  int   
    , Adjustment int   
    , Closing  int   
)        
return       
with       
    ordRows (rn, Adjustment) as 
    (select row_number() over(), Adjustment from t)   
, addRows (rn, Opening, Shift, Adjustment, closing) as   
    (select rn, OpenedWith, OpenedWith*Factor , Adjustment  
      , (OpenedWith + (OpenedWith*Factor) + Adjustment) 
     from ordRows            
     where rn = 1            
    union all             
     select b.rn, a.Closing, a.Closing * Factor , b.Adjustment 
      , (a.Closing + (a.Closing * Factor) + b.Adjustment) 
     from addRows a            
     join ordRows b            
     on a.rn = (b.rn - 1)         
    )               
select opening, shift, adjustment, closing      
from addRows             
order by rn              


Теперь вызвать UDTF с отмеченным значением открытия и фактора в качестве аргументов; то есть больше не зависит от созданных переменных, а вместо значений, полученных через входные параметры:

select t.*        
from table(shifted_vals(5000, 0.1)) as t 
; -- results as report, follows: 
    OPENING   SHIFT  ADJUSTMENT   CLOSING 
    5,000    500    100   5,600 
    5,600    560    200   6,360 
    6,360    636    300   7,296 
+0

Спасибо CRPence. Когда я выполнил ваш первый запрос, я столкнулся с ошибкой ... SQL0345N Полный выбор рекурсивного общего выражения таблицы « .ADDROWS» должен быть UNION из двух или более полных наборов и не может включать функции столбцов, предложение GROUP BY, HAVING, ORDER BY или явное соединение, включающее предложение ON. –

+0

Это работает !! CRPence Мне просто нужно удалить предложение ON ... объединение всех выберите b.rn, a.Closing, a.Closing * 0,1, b.Adjustment, (a.Closing + (a.Closing * 0,1) + b.Adjustment) из addRows а, б ordRows где a.rn = (b.rn - 1) –

+0

Ах! Эти нюансы вариантов DB2 и отсутствие тега для уточнения того, что используется. Я должен был отметить, что я использовал; приведенный синтаксис JOIN допустим для DB2 for i SQL, на котором выполнялись эти запросы, и показанный результат был получен в IBM i 7.1. Если вы не предложите иное [например, что я отредактирую ответ], я позволю этим комментариям служить помощником для тех, кто сталкивается с ошибками. – CRPence

Смежные вопросы