未测试,试一下
create or replace procedure DP_TEST(h_key in VARCHAR2,h_value in VARCHAR2 ) is
  v_key VARCHAR2(100);
  v_value VARCHAR2(100);
  v_splitkey varchar2(10):=';'; 
begin
  loop
    exit when h_key is null or h_value is null;
    if instr(h_key,v_splitkey)>0 then
      v_key:=substr(h_key,1,instr(h_key,v_splitkey)-1);
      h_key:=substr(h_key,instr(h_key,v_splitkey)+1);
    else
      v_key:=h_key;
      h_key:=null;
   end if;
   if if instr(h_value,v_splitkey)>0 then
      v_value:=substr(h_value,1,instr(h_value,v_splitkey)-1);
      h_value:=substr(h_value,instr(h_value,v_splitkey)+1);
    else
      v_value:=h_value;
      h_value:=null;
    end if;
    insert into t(key,value)values(v_key,v_value);
  end loop;
  commit;
end;

解决方案 »

  1.   

    获取长度的方法比较简单
    获取字符串中分号的个数加一即可
    length(h_key)-length(replace(h_key,';',''))+1
      

  2.   

    编译唔通过啊。
    这里有两个 if if 是不是写错了?
    我删除了一个还是错误。
      

  3.   

    参数不能作为赋值的目标,另建两个变量处理,那两个if是笔误写重了
    create or replace procedure DP_TEST(h_key in VARCHAR2,h_value in VARCHAR2 ) is
      p_key varchar2(4000);
      p_value varchar2(4000);
      v_key VARCHAR2(100);
      v_value VARCHAR2(100);
      v_splitkey varchar2(10):=';'; 
    begin
      p_key:=h_key;
      p_value:=h_value;
      loop
        exit when p_key is null or p_value is null;
        if instr(p_key,v_splitkey)>0 then
          v_key:=substr(p_key,1,instr(p_key,v_splitkey)-1);
          p_key:=substr(p_key,instr(p_key,v_splitkey)+1);
        else
          v_key:=p_key;
          p_key:=null;
       end if;
       if instr(p_value,v_splitkey)>0 then
          v_value:=substr(p_value,1,instr(p_value,v_splitkey)-1);
          p_value:=substr(p_value,instr(p_value,v_splitkey)+1);
        else
          v_value:=p_value;
          p_value:=null;
        end if;
        insert into t(key,value)values(v_key,v_value);
      end loop;
      commit;
    end;
      

  4.   

    ok.编译已通过。还有几个小问题:    if instr(p_key,v_splitkey)>0 then
          v_key:=substr(p_key,1,instr(p_key,v_splitkey)-1);
          p_key:=substr(p_key,instr(p_key,v_splitkey)+1);
        else
          v_key:=p_key;
          p_key:=null;
       end if; 能否把这段诠释写一写。看得不是很明白,所以我不知道v_key 有多少个值。如果我想取A 或者B 出来怎么取?
      

  5.   

    想知道有多少个值,可以加个循环变量,循环一次 变量加1if instr(p_key,v_splitkey)>0 then--如果p_key中存在分号
          v_key:=substr(p_key,1,instr(p_key,v_splitkey)-1);--把字符串中的第一个字符分离出来,存到v_key
          p_key:=substr(p_key,instr(p_key,v_splitkey)+1);--把剩余的字符串存到p_key
        else--若不存在分号,则此次的字符为最后一个字符
          v_key:=p_key;--把p_key赋值给v_key
          p_key:=null;--同时把p_key置空,以推出循环
       end if;
      

  6.   

    哈啊、谢谢大哥。调式一次看懂了!
    如何我现在还要把分割出来的值拼接成:decode(key,A,0,B,0,C,0,D,0,F,0,1) 
    这个怎么拼了。
      

  7.   

    decode(key,'A',0,'B',0,'C',0,'D',0,'F',0,1)
    应该是拼成这样吧,字符串需要用引号引起来的,加了几行,拼接的结果放在v_result里面了
    create or replace procedure DP_TEST(h_key in VARCHAR2,h_value in VARCHAR2 ) is
      p_key varchar2(4000);
      p_value varchar2(4000);
      v_key VARCHAR2(100);
      v_value VARCHAR2(100);
      v_splitkey varchar2(10):=';'; 
      v_result varchar2(4000);
    begin
      p_key:=h_key;
      p_value:=h_value;
      loop
        exit when p_key is null or p_value is null;
        if instr(p_key,v_splitkey)>0 then
          v_key:=substr(p_key,1,instr(p_key,v_splitkey)-1);
          p_key:=substr(p_key,instr(p_key,v_splitkey)+1);
        else
          v_key:=p_key;
          p_key:=null;
       end if;
       if instr(p_value,v_splitkey)>0 then
          v_value:=substr(p_value,1,instr(p_value,v_splitkey)-1);
          p_value:=substr(p_value,instr(p_value,v_splitkey)+1);
        else
          v_value:=p_value;
          p_value:=null;
        end if;
        v_result:=v_result||','''||v_key||''',0'
        insert into t(key,value)values(v_key,v_value);
      end loop;
      v_result:='decode(key'||v_result||',1) '
      commit;
    end;
      

  8.   

    这个拼接是没有问题,可以我放入原句执行就给我报一个错:无效的数组。我用排除法给排了出来,就是这个拼接的问题,我觉得应该是  v_result:='decode(key'||v_result||',1) '  中 'decode(key'  这个单引号(‘’)的原因。如果我去除这个单引号就报错了。还有啥办法
      

  9.   

    select DC_ID into ID from da_test group by DC_ID having sum(decode(DC_KEY,'我了个去。',0))=0; 嗯,就用这条语句试试,会报一个无效字符。
      

  10.   

    sum(decode(DC_KEY,'我了个去。',0)) 结果有可能是空,需要处理下
      

  11.   

    大哥、你会错意了。我说用你那个拼接起来的放进去,就会报错!
    v_result:=v_result||','''||v_key||''',0'
    v_result:='decode(key'||v_result||',1) '
    如果我代入 select DC_ID into ID from da_test group by DC_ID having sum(v_result)=0; 这里就好报错无效的字符。
    或者 select DC_ID into ID from da_test group by DC_ID having sum('decode(key'||v_result||',1) ')=0; 都是一样报无效字符
      

  12.   

    拼接的结果是字符串,sum(‘字符串’)肯定会报错的
    想拼接到里面正常运行,需要用动态语句执行的
      

  13.   

    拼接的结果是字符串,sum(‘字符串’)肯定会报错的
    想拼接到里面正常运行,需要用动态语句执行的动态?对我来说是新词语啊!怎么才叫动态?有例子么?
      

  14.   

    declare
     ID number
     type curtype   is     REF    cursor;
      A  curtype;
    begin
      open A FOR 'select DC_ID from da_test group by DC_ID having sum('||v_result||')=0';
      fetch A into id;
      close A;
    END;
      

  15.   

    create or replace procedure DP_TEST(h_key in VARCHAR2,h_value in VARCHAR2 ) is
      p_key varchar2(4000);
      p_value varchar2(4000);
      v_key VARCHAR2(100);
      v_value VARCHAR2(100);
      v_splitkey varchar2(10):=';'; 
      v_result varchar2(4000);
     ID number;
     type curtype   is     REF    cursor;
      A  curtype;
    begin
      p_key:=h_key;
      p_value:=h_value;
      loop
        exit when p_key is null or p_value is null;
        if instr(p_key,v_splitkey)>0 then
          v_key:=substr(p_key,1,instr(p_key,v_splitkey)-1);
          p_key:=substr(p_key,instr(p_key,v_splitkey)+1);
        else
          v_key:=p_key;
          p_key:=null;
       end if;
       if instr(p_value,v_splitkey)>0 then
          v_value:=substr(p_value,1,instr(p_value,v_splitkey)-1);
          p_value:=substr(p_value,instr(p_value,v_splitkey)+1);
        else
          v_value:=p_value;
          p_value:=null;
        end if;
        v_result:=v_result||','''||v_key||''',0'
        insert into t(key,value)values(v_key,v_value);
      end loop;
      v_result:='decode(key'||v_result||',1) '
      commit;
      open A FOR 'select DC_ID from da_test group by DC_ID having sum('||v_result||')=0';
      fetch A into id;
      close A;end;
      

  16.   

     啊哈、虽然自己也研究出来是这样镶进去,但还是很感谢的说。
    我的查询语句得到的是多个id的,怎么只给我返回一个id?其他的呢?
      

  17.   

    可以用游标循环取出的
    open A FOR '你的语句';
      fetch A into id;
      while A %found loop
       --逐个id进行处理
         fetch A into id;
       end loop;
      close A;
      

  18.   

    现在我要根据分割的值来查询ID ,判断ID 的值是否为空,如果为空就插入,如果不为空就更新 我这样判断怎么就报错了?
      

  19.   

    还是建议你从基础知识一步一步学习下吧
    你这个是语法问题
    前面写了if,后面没有end if与他对应
    需要在end前增加 end if;另外感觉你的业务逻辑可能有点问题ps:你这帖子也太长了,与开贴时的问题已经基本没啥关系了