DB2递归UDF表

时间:2016-07-31 11:47:00

标签: sql recursion db2

我在DB2中编写递归表函数时遇到问题。

我有一张价值表......

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 = Opening * 0.1
  2. 结束=开始+转+关闭
  3. 打开是前一行的结束
  4. 当我试图提出结果时,我的递归函数卡住了...(SQL0345N全面选择递归公用表表达式)

    欣赏任何想法如何做到这一点。我知道存储过程可以做到这一点,但我需要使用UDF,以便它可以在另一个UDF中扩展。

1 个答案:

答案 0 :(得分:1)

我不确定我是否正确解释了这个场景,但这就是我所做的:

首先,我将创建一些变量来模仿函数的输入,然后组成一个递归公用表表达式(RCTE),使用从这些变量中获取的数据生成报告:

 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

现在修改上面的脚本变量创建并查询用户定义表函数(UDTF),该函数针对名为T的TABLE中的数据进行操作:

 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