db2 多值数据字典解析

问题描述:

一般情况下,业务数据中存储的字典值为单值,比如"1"或"2",直接关联字典表后,可以解析出字典值;
但有时因业务要求,需要存储多选值,比如:“1,2,11,12”,此时,无法直接关联字典表进行解析;
本文讲解如下通过函数,进行多值字典解析;

适用范围

DB2 9.7/10.5

示例数据

业务字典表:

GUPIDGUPNAME
1分组1
2分组2
3分组3
4分组4
5分组5
11分组11
12分组12

业务数据表:

IDGUPIDS
11,2,3
21,11,12
34,5

最终需要解析成如下结果:

IDGUPIDGUPNAME
11分组1
12分组2
12分组3
21分组1
211分组11
212分组12
34分组4
35分组5

解决办法:

首先创建3个解析函数,分别为:f_elemIdx,f_split,f_exists_dic_item;
然后给出函数的调用方式。

/*函数:f_elemIdx*/
CREATE FUNCTION f_elemIdx ( pi_str CLOB(64K) )
   RETURNS TABLE ( ordinal INTEGER, index INTEGER )
   LANGUAGE SQL
   --DETERMINISTIC
   NO EXTERNAL ACTION
   --CONTAINS SQL
   F1: BEGIN ATOMIC
   RETURN
      WITH t(ordinal, index) AS
         ( VALUES ( 0, 0 )
           UNION ALL
           SELECT ordinal+1, COALESCE(NULLIF(
                     -- find the next delimiter ','
                     LOCATE(',', pi_str, index+1), 0),
                     LENGTH(pi_str)+1)
           FROM   t
                  -- to prevent a warning condition for infinite
                  -- recursions, we add the explicit upper
                  -- boundary for the "ordinal" values
           WHERE ordinal < 100 AND
                  -- terminate if there are no further delimiters
                  -- remaining
                  LOCATE(',', pi_str, index+1) <> 0 )
      SELECT ordinal, index
      FROM   t
      UNION ALL
      -- add indicator for the end of the string
      SELECT MAX(ordinal)+1, LENGTH(pi_str)+1
      FROM   t
      ORDER BY 1;
    END;

/*函数:f_split*/
CREATE FUNCTION f_split( string VARCHAR(255) )
   RETURNS TABLE ( elements VARCHAR(255) )
   LANGUAGE SQL
   DETERMINISTIC
   NO EXTERNAL ACTION
   --CONTAINS SQL
   F1: BEGIN ATOMIC
   RETURN
      WITH t(ordinal, index) AS
         ( SELECT ordinal, index
           FROM   TABLE ( f_elemIdx(string) ) AS x )
      SELECT SUBSTR(string, t1.index+1, t2.index - t1.index - 1)
      -- the join below makes sure that we have the lower and
      -- upper index where we can find each of the ',' delimiters
      -- that are separating the elements. (For this, we exploit
      -- the additional indexes pointing to the beginning and end
      -- of the string.)
      FROM   t AS t1 JOIN t AS t2 ON
                ( t2.ordinal = t1.ordinal+1 ) ;
  
END;

/*函数:f_exists_dic_item*/
CREATE FUNCTION f_exists_dic_item(col VARCHAR(255), item VARCHAR(255))
LANGUAGE SQL
RETURNS char(1)
DETERMINISTIC NO EXTERNAL ACTION
BEGIN ATOMIC
	Declare sReturn VARCHAR(255);  
    SET sReturn = (
    	SELECT elements FROM TABLE(f_split(col)) WHERE elements = item
    );
    IF sReturn IS NULL THEN 
    	RETURN '0';
    ELSE 
    	RETURN '1';
    END IF;
END;

/*
db2创建别名,兼容oracle dual
*/
CREATE ALIAS DUAL FOR SYSIBM.DUAL;

/*
db2多值字典解析
*/
with  x0 as (/* 业务字典表 */
	select 1 as gupId, '分组1' as gupName from dual union all 
	select 2 as gupId, '分组2' as gupName from dual union all 
	select 3 as gupId, '分组3' as gupName from dual union all 
	select 4 as gupId, '分组4' as gupName from dual union all 
	select 5 as gupId, '分组5' as gupName from dual union all 
	select 11 as gupId, '分组11' as gupName from dual union all 
	select 12 as gupId, '分组12' as gupName from dual 
), x1 as (/* 业务数据表 */
	select 1 as id, '1,2,3' as gupIds from dual union all 
	select 2 as id, '1,11,12' as gupIds from dual union all 
	select 3 as id, '4,5' as gupIds from dual 
)
SELECT x1.id, x1.gupIds, x0.gupId, x0.gupName 
FROM x1,x0
WHERE f_exists_dic_item(x1.gupIds,x0.gupId)='1'
ORDER BY 1,3
;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值