for문 해결좀 해주세요~ 0 11 1,863

by 자이제시작이야 [PL/SQL] [2017.08.25 14:15:41]


테이블 test_table이 있습니다.

create table test_table(

no1 number,

u_id varchar2(10),

u_pw varchar2(10),

senten varchar2(100)

);

insert into test_table values(1,'kim','1234','동해물과 백두산이 마르고 닳도록 연습하자');

 

 

test_table의 senten 값을 공백 단위로 쪼개고 여러개의 row값을 출력하는 procedure를 짜보고 있는데 잘 안되서요. 해결해 주시면 감사하겠습니다.

-----procedure-----

create or replace procedure split_sentence

is

 

type table_type1 is table of test_table%rowtype

index by binary_integer;

split_word varchar2(100);

i binary_integer := 0;

 

test_table1 table_type1;

 

begin

     DBMS_OUTPUT.ENABLE;

     for s_list in (select senten from test_table where no=1) loop

          i := i + 1;

          test_table1(i) := s_list.senten;

          dbms_output.put_line('test_table(i) || test_table1(i)');

     end loop;

 

     for cnt in 1..i loop

          split_word := regexp_substr(test_table1(cnt).senten, '[^ ]+',1);

          dbms_output.put_line('split_word : ' || split_word);

     end loop;

end;

 

set serveroutput on;

execute split_sentence;

by 우리집아찌 [2017.08.25 14:29:43]
/*수정*/
WITH TEST_TABLE AS (
SELECT 1 no1 , 'KIM' u_id, '1234' u_pw, '동해물과 백두산이 마르고 닳도록 연습하자' senten  FROM DUAL UNION ALL
SELECT 2 no1 , 'LEE' u_id, '5678' u_pw, '기운센 천하장사 무쇠로 만든' senten  FROM DUAL 
), COPY_T AS (
SELECT LEVEL LV FROM DUAL CONNECT BY LEVEL <= (SELECT MAX(REGEXP_COUNT(senten , ' ')) + 1 FROM TEST_TABLE)
)

SELECT A.NO1 , B.LV , REGEXP_SUBSTR(A.senten, '[^ ]+' , 1 , B.LV ) senten
  FROM TEST_TABLE A
      ,COPY_T B
 WHERE REGEXP_COUNT(A.senten,' ') + 1 >= B.LV 
 ORDER BY A.NO1 , B.LV

 


by 자이제시작이야 [2017.08.25 14:59:57]

감사합니다!!!

WHERE REGEXP_COUNT(A.senten,' ') + 1 >= B.LV  이거에 대해서 설명좀 해주실수 있으신가요?...


by jkson [2017.08.25 15:10:52]

연습으로 프로시저 만드시는 것 같은데..

쿼리로 하면 쉽지만 굳이 프로시저로 하시겠다면

의도에 맞게 오류 안 나게만 수정해보았습니다. 잘 작동하는지 확인해보세요.

create or replace procedure split_sentence
is
 type table_type1 is table of test_table%rowtype index by binary_integer;

 split_word varchar2(100);
 i binary_integer := 0;

 test_table1 table_type1;
 cursor cur is
  select *
    from test_table
   where no = 1;
begin
 dbms_output.enable;

 open cur;

 loop
  i := i + 1;

  fetch cur into test_table1(i);

  exit when cur%notfound;

  dbms_output.put_line('test_table(' || i || ') : ' || test_table1(i).senten);
 end loop;

 i := i - 1;

 for cnt in 1 .. i 
 loop
  for word in 1 .. regexp_count(test_table1(cnt).senten, ' ') + 1 
  loop
   split_word  := regexp_substr(test_table1(cnt).senten, '[^ ]+', 1, word);

   dbms_output.put_line('split_word : ' || split_word);
  end loop;
 end loop;
end;

 


by 자이제시작이야 [2017.08.25 15:34:27]

cursor 쓰는게 편리하죠?

공백 수에 +1은 왜 해주는 거에요?

정말 감사합니다!!


by jkson [2017.08.25 15:59:20]

'동해물과 백두산이 마르고 닳도록 연습하자'

에서 공백수는 4개이고 출력해줄 결과 row는 5개이니 + 1을 해주었습니다.


by 자이제시작이야 [2017.08.25 16:02:51]

친절한 답변 너무 감사합니다~~

좋은 하루 되세요~!


by 우리집아찌 [2017.08.25 15:15:26]
 REGEXP_COUNT(A.senten,' ') + 1  -- 공백의 개수 구하기
 >= B.LV                         -- COPY_T ROW ( 위의 샘플에선 4개 ) 
                                 -- 즉 공백갯수 보다 COPY_T LV 가 작거나 같은것만 조회
                                 -- COPY_T 만 따로 조회하시면 알아보실겁니다.

 


by jkson [2017.08.25 15:23:19]

SELECT MAX(REGEXP_COUNT(senten , ' ')) + 1 FROM TEST_TABLE1 하셔야할듯이요~


by 우리집아찌 [2017.08.25 15:29:41]

아 빠졌다.

요즘 다 대충대충해서 ㅎㅎ


by 자이제시작이야 [2017.08.25 15:34:46]

 

감사합니다!!

좋은하루 되세요~~


by 마농 [2017.08.28 10:20:49]

no 가 pk 이고, 항상 조건으로 주어진다면?
커서 사용이나, 배열변수 사용은 필요 없겠네요.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입