Correct answers have already been given, but a little worked out.
Simulating your current situation:
SQL> declare 2 cursor cur_t 3 is 4 select ename 5 from emp 6 where deptno = 10 7 ; 8 v_texttoadd emp.ename%type; 9 v_string varchar2(100); 10 begin 11 open cur_t; 12 loop 13 fetch cur_t into v_texttoadd; 14 v_string := v_string || v_texttoadd; 15 exit when cur_t%notfound; 16 end loop 17 ; 18 dbms_output.put_line(v_string); 19 end; 20 / CLARKKINGMILLERMILLER PL/SQL-procedure is geslaagd.
Here MILLER is printed twice. Just by switching the EXIT statement and v_string assignment, you get the desired result:
SQL> declare 2 cursor cur_t 3 is 4 select ename 5 from emp 6 where deptno = 10 7 ; 8 v_texttoadd emp.ename%type; 9 v_string varchar2(100); 10 begin 11 open cur_t; 12 loop 13 fetch cur_t into v_texttoadd; 14 exit when cur_t%notfound; 15 v_string := v_string || v_texttoadd; 16 end loop 17 ; 18 dbms_output.put_line(v_string); 19 end; 20 / CLARKKINGMILLER PL/SQL-procedure is geslaagd.
However, your PL / SQL code becomes easier when using a cursor for a loop. Then you can skip the v_texttoadd variable and the number of lines in your loop decreases:
SQL> declare 2 cursor cur_t 3 is 4 select ename 5 from emp 6 where deptno = 10 7 ; 8 v_string varchar2(100); 9 begin 10 for r in cur_t 11 loop 12 v_string := v_string || r.ename; 13 end loop 14 ; 15 dbms_output.put_line(v_string); 16 end; 17 / CLARKKINGMILLER PL/SQL-procedure is geslaagd.
You can also use direct SQL to do the job. An example with the suggestion of the SQL model if you are on version 10g or higher:
SQL> select string 2 from ( select string 3 , rn 4 from emp 5 where deptno = 10 6 model 7 dimension by (rownum rn) 8 measures (ename, cast(null as varchar2(100)) string) 9 ( string[any] order by rn desc = ename[cv()] || string[cv()+1] 10 ) 11 ) 12 where rn = 1 13 / STRING ----------------------------------------------------------------------------------- CLARKKINGMILLER 1 rij is geselecteerd.
Regards, Rob.
Rob van Wijk
source share