create or replace procedure pre_allRate (p_cust_no       in  varchar2,
                         p_cust_rate     out varchar2
                         )
as 
  curs rate.ratefree;
  --curs2 rate.ratefree;
  v_cust_rate  varchar2(2000):='aa';beginopen curs for'
   select cust_no||''~''||
           exch_code||''~''||
           vari_code||''~''||
           deliv_date||''~''||
           eo_commi_amt||''~''||
           eo_commi_rate||''~''||
           eo_add_fee1_amt||''~''||
           eo_add_fee1_rate||''~''||
           eo_add_fee2_amt||''~''||
           eo_add_fee2_rate||''~''||
           ot_commi_amt||''~''||
           ot_commi_rate||''~''||
           ot_add_fee1_amt||''~''||
           ot_add_fee1_rate||''~''||
           ot_add_fee2_amt||''~''||
           ot_add_fee2_rate||''~''||
           deliv_commi_amt||''~''||
           deliv_commi_rate||''~''||
           oper_code||''~''||
           oper_date||''~''||
           oper_time
      
      from SYB_CUST_COMMI
     where cust_no=:p_cust_no
     
 ' 
 using p_cust_no; 
  
   loop
        fetch curs into v_cust_rate;
         exit when  curs%notfound ;
        p_cust_rate := p_cust_rate+v_cust_rate+'~';
       
    end loop; if v_cust_rate='aa' then
 
    open curs for'                     select TEMPLATE_NO||''~''||                         EXCH_CODE||''~''||
                         VARI_CODE||''~''||
                         DELIV_DATE||''~''||
                         EO_COMMI_AMT||''~''||
                         EO_COMMI_RATE||''~''||
                         EO_ADD_FEE1_AMT||''~''||
                         EO_ADD_FEE1_RATE||''~''||
                         EO_ADD_FEE2_AMT||''~''||
                         EO_ADD_FEE2_RATE||''~''||
                         OT_COMMI_AMT||''~''||
                         OT_COMMI_RATE||''~''||
                         OT_ADD_FEE1_AMT||''~''||
                         OT_ADD_FEE1_RATE||''~''||
                         OT_ADD_FEE2_AMT||''~''||
                         OT_ADD_FEE2_RATE||''~''||
                         DELIV_COMMI_AMT||''~''||
                         DELIV_COMMI_RATE||''~''||
                         OPER_CODE||''~''||
                         OPER_DATE||''~''||
                         OPER_TIME
                    from SYB_COMMI_TEMPLATE
                    where cust_no=:p_cust_no
                   '
                   
       using p_cust_no;             
 end if;
   
   loop
        fetch curs into v_cust_rate;
         exit when  curs%notfound ;
        p_cust_rate := p_cust_rate+v_cust_rate+'~';
       
    end loop;
   
 if v_cust_rate='aa' then
 p_cust_rate:='null';
  
               
 end if;
 --p_cust_rate:='aaaa';
 --close curs;
  
end pre_allRate;需求 执行存储过程的时候存进去一个custNo 然后去查询第一张表SYB_CUST_COMMI,如果第一张表中没有数据 就去查询第二张表SYB_COMMI_TEMPLATE  查到的结果用字符串拼接存到p_cust_rate中
结果是类似这样的数据: 
  张三~18~中国~李四~22~美国~王五~33~英国 (如果两张表中都没有数据就给p_cust_rate赋值为“mage”的字符串)
(即把每一行的结果拼成用~分割的字符串)
上面自己写的完成了一部分 但是报错 高手帮忙改一改或者根据需求按照自己的思路写一个 感激不尽

解决方案 »

  1.   

    一个custNO对应多条值 然后把每条值拼成字符串
      

  2.   

    去看看for游标的用法,显然使用for游标会非常简单。另外你的错误是这句:p_cust_rate := p_cust_rate+v_cust_rate+'~';
    你看你字符串拼接用了什么了?+号在Oracle里面只能处理数字相加。
      

  3.   

    --- 把两个表的结构帖出来!-- 当字段与字段之前用“||”拼接成字符串的时候,要注意字段的类型,当是数值型或Date型的时候,需要转换一下才能将其拼接!
      

  4.   

    所有的字段全部是varchar2 类型
      

  5.   


    这个地方已经改过了 但是报错说字符串缓冲区不够     p_cust_rate := p_cust_rate || v_cust_rate || ',';plsql提示这一句挂了说他字符串缓冲区太小 前面的问题解决了
      

  6.   

    楼主可以先添加判断语句  不要直接用游标打开  有了在用游标取出来然后拼凑declare 
    c varchar2(200);
    begin
    c := 1 ||''|| '~'||''|| 2;
    dbms_output.put_line(c);
    end;
      

  7.   

    字符串缓冲区不够指的是你的p_cust_rate给的不够大,看你给了2000长度,看来是超过了,你得跟踪下你获取的数据,超过2000字长了哦。
      

  8.   

    varchar2最大只有4000,你改到8000也是无效的,除非你用CLOB,但是CLOB类型的操作比较麻烦,字符串拼接无法处理CLOB类型的。
      

  9.   

    你要么就  直接
    select ... into v_cust_rate from ...;
    要么就
    吧v_cust_rate  tablename.rowtype;
    p_cust_rate := p_cust_rate+v_cust_rate.col1+'~'+v_cust_rate.col2...;