怎样用字典表的数据替换另一个表中某个字段的值?

时间:2022-12-30 14:54:36
现有 字典表tba
字段如下  
dm  nr
01  新增
02  修改
03  统计
04  XX
05  aaa
06  ...

用户表  user  (字段qx对应 字典表tba的dm,每个id可以有多个功能,用逗号分隔 )

id       qx

admin   功能1,功能2,功能3
001     01
002     01,02
003     01,03 
004     05

现在想显示这样的效果  (把qx地段里的代码替换成 字段表tba里的nr)

admin   新增,修改,统计
001     新增
002     新增,修改
003     新增,统计 
004     aaa

这个sql语句该怎样写呀?



谢谢大家

11 个解决方案

#1


不好做,如果字典中的数据不确定,不能使用系统函数,还是自已写个函数实现吧。。。

#2


引用 1 楼 quiettown 的回复:
不好做,如果字典中的数据不确定,不能使用系统函数,还是自已写个函数实现吧。。。



应该咋写呀

#3


首先判断的逗号的个数,然后依据逗号逐段的截取字符,然后与码表关联。

#5


分两步
--1、单行字段拆分为多行,下面只是给个以前的例子
with t1 as
(
select '张三' c1,'胸外科,皮肤科' c2,date'2000-11-19' c3  from dual
union all
select '李四','胸外科',date'2001-01-04'  from dual
union all
select '王五','妇产科,骨科',date'2001-01-08' from dual
)

select c1,
  substr(','||c2||',',instr(','||c2,',',1,b.rn)+1,
  instr(c2||',',',',1,b.rn)-instr(','||c2,',',1,b.rn)) c2,c3
from t1,
  (select rownum rn from t1
  connect by rownum<10
--connect by rownum < nvl(length(regexp_replace(c2,'[^,]')),0)
) b
  where length(c2)-length(replace(c2,','))+1>=b.rn
order by c1,b.rn
--10这个常量也可以改为读取字段中信息:nvl(length(regexp_replace(c2,'[^,]')),0)

--2、拆分的结果与字典表联立查询,这个你应该会吧

--3、The Oracle WM_CONCAT Function,WM_CONCAT再把字段重新拼回来。

#6



create or replace function fn_convertcode(
    p_instr in varchar2
) return varchar2 is

    v_instr    varchar2(100);
    v_typeid   varchar2(10);
    v_typename varchar2(100);    
    v_result varchar2(100);    
begin

    v_instr  := p_instr;
    v_result := '';
    
    loop  
        v_typeid := substr(v_instr, 1, 
            case when instr(v_instr, ',') > 0 then instr(v_instr, ',') - 1 else length(v_instr) end);  
        
        begin
            select nvl(nr, 'unknow') into v_typename
              from tba
             where dm = v_typeid;
        exception
            when no_data_found then
                v_typename := 'unknow'; 
        end;            
        
        v_result := v_result || v_typename || ',';
        exit when instr(v_instr, ',') = 0 or v_instr is null;        
        
        v_instr  := substr(v_instr, instr(v_instr, ',') + 1); 
        
    end loop;
       
    v_result := substr(v_result, 1, length(v_result) - 1);
    return(v_result);
    
end fn_convertcode;


#7


很不错哦 ,我也在学习Oracle  希望有所帮助 怎样用字典表的数据替换另一个表中某个字段的值?

#8


其中最重要的是“用户表  user”的分割问题
1) 先看一下字典表的最大数据(如果大的话放弃这个方法),按字典表一个一个分割后用union all 连起来

select id, substr(qx || ',', 1, instr(qx || ',', ',') - 1)
  from user
union all
select id,
       substr(replace(qx || ',',
                      substr(qx || ',', 1, instr(qx || ',', ',')),
                      ''),
              1,
              instr(replace(qx || ',',
                            substr(qx || ',', 1, instr(qx || ',', ',')),
                            ''),
                    ',') - 1)
  from user
union all
...
;


2)自定义函数分割,这个楼上几位已经有答案了。

#9


谢谢大家。我试试

#10


搞的好复杂啊  写个函数查询代码对应的值  带入user表查询下就出来的

#11


搞定了,谢谢

#1


不好做,如果字典中的数据不确定,不能使用系统函数,还是自已写个函数实现吧。。。

#2


引用 1 楼 quiettown 的回复:
不好做,如果字典中的数据不确定,不能使用系统函数,还是自已写个函数实现吧。。。



应该咋写呀

#3


首先判断的逗号的个数,然后依据逗号逐段的截取字符,然后与码表关联。

#4


#5


分两步
--1、单行字段拆分为多行,下面只是给个以前的例子
with t1 as
(
select '张三' c1,'胸外科,皮肤科' c2,date'2000-11-19' c3  from dual
union all
select '李四','胸外科',date'2001-01-04'  from dual
union all
select '王五','妇产科,骨科',date'2001-01-08' from dual
)

select c1,
  substr(','||c2||',',instr(','||c2,',',1,b.rn)+1,
  instr(c2||',',',',1,b.rn)-instr(','||c2,',',1,b.rn)) c2,c3
from t1,
  (select rownum rn from t1
  connect by rownum<10
--connect by rownum < nvl(length(regexp_replace(c2,'[^,]')),0)
) b
  where length(c2)-length(replace(c2,','))+1>=b.rn
order by c1,b.rn
--10这个常量也可以改为读取字段中信息:nvl(length(regexp_replace(c2,'[^,]')),0)

--2、拆分的结果与字典表联立查询,这个你应该会吧

--3、The Oracle WM_CONCAT Function,WM_CONCAT再把字段重新拼回来。

#6



create or replace function fn_convertcode(
    p_instr in varchar2
) return varchar2 is

    v_instr    varchar2(100);
    v_typeid   varchar2(10);
    v_typename varchar2(100);    
    v_result varchar2(100);    
begin

    v_instr  := p_instr;
    v_result := '';
    
    loop  
        v_typeid := substr(v_instr, 1, 
            case when instr(v_instr, ',') > 0 then instr(v_instr, ',') - 1 else length(v_instr) end);  
        
        begin
            select nvl(nr, 'unknow') into v_typename
              from tba
             where dm = v_typeid;
        exception
            when no_data_found then
                v_typename := 'unknow'; 
        end;            
        
        v_result := v_result || v_typename || ',';
        exit when instr(v_instr, ',') = 0 or v_instr is null;        
        
        v_instr  := substr(v_instr, instr(v_instr, ',') + 1); 
        
    end loop;
       
    v_result := substr(v_result, 1, length(v_result) - 1);
    return(v_result);
    
end fn_convertcode;


#7


很不错哦 ,我也在学习Oracle  希望有所帮助 怎样用字典表的数据替换另一个表中某个字段的值?

#8


其中最重要的是“用户表  user”的分割问题
1) 先看一下字典表的最大数据(如果大的话放弃这个方法),按字典表一个一个分割后用union all 连起来

select id, substr(qx || ',', 1, instr(qx || ',', ',') - 1)
  from user
union all
select id,
       substr(replace(qx || ',',
                      substr(qx || ',', 1, instr(qx || ',', ',')),
                      ''),
              1,
              instr(replace(qx || ',',
                            substr(qx || ',', 1, instr(qx || ',', ',')),
                            ''),
                    ',') - 1)
  from user
union all
...
;


2)自定义函数分割,这个楼上几位已经有答案了。

#9


谢谢大家。我试试

#10


搞的好复杂啊  写个函数查询代码对应的值  带入user表查询下就出来的

#11


搞定了,谢谢