算法:先吧所有的表名取出来,用“select tablename from dual union“,union的方法将重复的表名去掉SQL> set serveroutput on
SQL> declare
  2    strtablename varchar2(500) :='table1,table2,table1,table3,table4,';
  3    v_sql varchar2(1000);
  4    v_strtable varchar2(50);
  5    i1 number :=1;
  6    i2 number :=1;
  7    type v_cursor is ref cursor;
  8    v_cursortemp v_cursor;
  9  begin
 10    for i in 1..length(strtablename) loop
 11      i2 :=instr(strtablename,',',i1) ;
 12      if i2=0 then
 13        exit;
 14      end if;
 15      v_strtable := substr(strtablename,i1,i2-i1);
 16      dbms_output.put_line('gettablename:' || v_strtable || ';');
 17      i1 := i2+1;
 18      if i =1 then
 19        v_sql := v_sql || 'select '' ' || v_strtable || ' '' from dual';
 20      else
 21        v_sql := v_sql || ' union select '' ' || v_strtable || ' '' from dual
';
 22      end if;
 23    end loop;
 24
 25    open v_cursortemp for v_sql;
 26    loop
 27      fetch v_cursortemp into v_strtable;
 28      exit when v_cursortemp%notfound;
 29      dbms_output.put_line('tablename:' || v_strtable || ';');
 30    end loop;
 31    close v_cursortemp;
 32  end;
 33  /
gettablename:table1;
gettablename:table2;
gettablename:table1;
gettablename:table3;
gettablename:table4;
tablename: table1 ;
tablename: table2 ;
tablename: table3 ;
tablename: table4 ;PL/SQL procedure successfully completed.

解决方案 »

  1.   

    我觉得这个算法应该比较简单,我是这样想的:
    oracle中的instr 函数你用过吧,用这个来实现就很方便。
    设立一个for循环,循环变量i取逗号在该串中的个数。(好象也有这函数,记不太清了)  设立得到的字符串名target_string,变量的初值是‘’
      这样每次循环截取串中,前的一部分:
        判断:instr(target_string,该部分)>0  那么表示已存在,作下一次循环
              不存在:将该部分加入target_string串中。
      

  2.   

    三个变量:
    s1:原来的字符串
    s2:要得到的字符串
    s3:临时变量1。使用instr在s1中对逗号定位,取得表名,放在s3(包含逗号)中,同时,加在s2的末尾。
    2。使用replace,将s1中包含的s3替换为''。
    3。在从1开始,重复。最终,s2就是你想要的。
      

  3.   

    create or replace procedure testarr is
    type arr_type is table of varchar(50) index by binary_integer;
    arr arr_type;
    str1 string(500);
    str2 string(500);
    i integer;
    j integer;
    v_count integer;
    begin
    str1:='table1,tableddd2,table1,table3,tablecc4,table5,tableddd2,tablecc4,table5,tableddd2';
    i:=0;
    --将str1分解放入数组
    while str1 is not null loop 
       arr(i):=substr(str1,1,instr(str1,',')-1);
       j:=length(arr(i));
       str1:=substr(str1,j+2,length(str1));
       i:=i+1;
    end loop;
    v_count:=i-1;
    str2:='';
    --取出不同的表名放入str2
    for i in 0..v_count loop
      if instr(arr(i),'@')=0 then
         str2:=str2||','||arr(i);
         for j in (i+1)..v_count loop
            if arr(i)=arr(j) then
                arr(j):='@'||arr(j);
            end if;
         end loop;
      end if;
    end loop;
    --去掉第一个逗号
    str2:=substr(str2,2,length(str2));dbms_output.put_line(str2);end testarr;
      

  4.   

    zhaoyongzhu(zhaoyongzhu) 的方法很巧妙,用UNION去掉重复的记录,好呀!
      

  5.   

    我认为rady88(猫) 的方法最好,zhaoyongzhu(zhaoyongzhu)  的方法则十分巧妙。
      

  6.   

    没错,rady88(猫) 的方法最好!
      

  7.   

    看到大家都那么热心,我也来参乎一下!:)
    declare
    v_tabname varchar2(500) := 'table1,table2,table1,table3,table4,table2,table3,,table4';
    v_result varchar2(500) := ' ';
    v_tmpstr varchar2(500);
    v_startpos number := 1;
    v_endpos number;
    begin
    loop
    v_endpos := instr(v_tabname, ',', v_startpos);
    if v_endpos = 0 then
    exit;
    end if;
    if v_endpos > v_startpos then
    v_tmpstr := trim(substr(v_tabname, v_startpos, v_endpos - v_startpos)) || ',';
    if instr(v_result, v_tmpstr) = 0 then
    v_result := v_result || v_tmpstr;
    end if;
    end if;
    v_startpos := v_endpos + 1;
    end loop;
    v_result := rtrim(v_result, ',');
    DBMS_OUTPUT.PUT_LINE('result:' || v_result);
    end;
    /
    另:该程序在ORACLE8i上测试通过,在ORACLE8上需要将trim函数替换为ltrim(rtrim())函数的形式。附:zhaoyaongzhu的方法的确巧妙,只是太复杂了一点;
    rady88可惜没有源程序,无法瞻仰其高手风范,可惜啊可惜!
    CHENGXB使用两重循环……,似乎无此必要。
    呵呵!小弟在此胡言,各位大侠莫要见怪!!!
    ================================================================CSDN 论坛助手 Ver 1.0 B0402提供下载。 改进了很多,功能完备!★  浏览帖子速度极快![建议系统使用ie5.5以上]。 ★  多种帖子实现界面。 
    ★  保存帖子到本地[html格式]★  监视您关注帖子的回复更新。
    ★  可以直接发贴、回复帖子★  采用XML接口,可以一次性显示4页帖子,同时支持自定义每次显示帖子数量。可以浏览历史记录! 
    ★  支持在线检测程序升级情况,可及时获得程序更新的信息。★★ 签名  ●  
         可以在您的每个帖子的后面自动加上一个自己设计的签名哟。Http://www.ChinaOK.net/csdn/csdn.zip
    Http://www.ChinaOK.net/csdn/csdn.rar
    Http://www.ChinaOK.net/csdn/csdn.exe    [自解压]