전에도 포스팅 했던게 있을듯 한데,
첨부파일이나, 태그 같은걸 구분자를 줘서 하나의 필드로 묶어야 하는 경우가 종종 있다.
(사실은 내가 하는 일에선 자주 있다)

그런데, 오라클이 많다보니 오라클에서 작업하다가 얼마전
MS-SQL을 접하게 되었다... ㄷㄷㄷㄷ

간단히 예를 들면?
TB_BBS( BOARD_ID, TITLE, CONTENTS ...) 라는 테이블이 있고,
태그를 관리하기 위해 BOARD_ID를 기준으로 태그를 관리한다고 치자.
TB_TAG( TAG_ID, BOARD_ID, TAG_NAME ...)

즉, 게시물 번호 1 의 태그들을  알려면
select TAG_NAME from TB_TAG where board_id = '1' 라는 말이다.



CREATE FUNCTION FN_TAGS (@pkey varchar(20)) RETURNS varchar(1000) AS

/***************************

태그 묶음 펑션

2009.02.26 V001 @정민철

****************************/

BEGIN

             DECLARE curTag CURSOR FOR

             SELECT TAG_NAME FROM TB_TAG WHERE BOARD_ID = @pkey

             OPEN curTag

 

             DECLARE @tagnames varchar(1000)

             DECLARE @tagname varchar(20)

             SET @tagnames = ''


             FETCH NEXT FROM curTag INTO @tagname

             WHILE @@FETCH_STATUS = 0

             BEGIN

               IF @tagnames = ''

                            BEGIN

                                       SET @tagnames = @tagname

                            END

               ELSE

                            BEGIN

                                       SET @tagnames = @tagnames + ',' + @tagname

                            END

 

               FETCH NEXT FROM curTag INTO @tagname

             END

            

             CLOSE curTag

             DEALLOCATE curTag

 

             return @tagnames

END



이렇게 만들면 아래같은 쿼리를 통해서

select FN_TAGS(board_id) as TAGS, TB_BBS.* from TB_BBS;

TAGS = 태그1, 태그2, 태그3
같은 값을 얻어올수 있당.

 

종종..어플을 개발하던 어찌하던
필드 하나에 여러개의 필드값을 구분자로 저장해야 하는 경우가 생긴다.

예를들면,
"도서>국내도서>소설" 같이

분류를 나타내야 하는데, 
하위 detph제한 없이 스키마를 구성하려면, 한필드에 구분자를 넣어서 집어 넣는 경우가 생긴다.
물론 이건 자바같은것에선 str.split('>') 같이 사용하면 되지만,

갑자기 1depth, 2depth, 3depth 의 필드로 구분된 뷰를 만들어 달라고 했다면 ???

어찌할것인가? 만약 내부함수만으로 한다면 instr과 substr등이 남발되면서
sql문이 상당히 길어지므로 개인적으론 프로시저(펑션)을 만드는것을 추천한다.

오라클 기준으로 만든 소스...


create or replace
FUNCTION FN_JMC_SPLIT (str IN VARCHAR, del IN VARCHAR,  idx IN INTEGER)
RETURN CHAR IS
/***************************************
abc:de:fghi 를 구분자(:)를
기준으로 idx번째 데이터를 가져옴

만약 해당 데이터가 없다면 null
@make by 정민철
****************************************/
temp_idxst INTEGER; --시작
temp_idxed INTEGER; --끝
temp_leng INTEGER;  --길이
temp_limit INTEGER;
cnt INTEGER;
codersb VARCHAR2(100);
BEGIN
  codersb := '';
  temp_limit := length(str);
  cnt := 0;
  temp_idxst := 1;
  temp_idxed := 1;
 
  for cnt IN 1..idx loop
      temp_idxed := instr(str, del, temp_idxst);
     
      -- 구분자를 찾을수 없을때(마지막데이터임)
      if temp_idxed = 0  then 
        temp_idxed := temp_limit + 1;
      end if;
      temp_leng  := temp_idxed - temp_idxst;
     
      -- 해당 index라면 codersb값을 세팅해줌
      if cnt = idx then
        codersb := substr(str,temp_idxst, temp_leng);
      end if;
     
      -- 시작 index를 갱신
      temp_idxst := temp_idxed + 1;
  end loop;

 
  RETURN codersb;
END FN_JMC_SPLIT;



[결과]

Select FN_JMC_SPLIT('도서>국내도서>소설','>', 1) ... from ....  ==> 도서
Select FN_JMC_SPLIT('도서>국내도서>소설','>', 2) ... from ....  ==> 국내도서
Select FN_JMC_SPLIT('도서>국내도서>소설','>', 3) ... from ....  ==> 소설
Select FN_JMC_SPLIT('도서>국내도서>소설','>', 4) ... from ....  ==> null
자바스크립트를 통해 이벤트를 처리할 경우는 참 많다.
그리고 개발자를 위해서 디자이너가 이벤트를 다 만들어서
제공하는 nice한 경우도 있지만,

정말... 디자인만 주는 디자이너도 존재하기 때문에 해당 이벤트를 내가 컨트롤 해줘야 하는 경우도 존재한다.

사용자 삽입 이미지






한가지 예를 들면 ,
붉은 동그라미친 + - 이미지를 바꾸는 일을 하는 이벤트를 만들어야 한다면?


가장 심플한 방식으론 다음과 같다.

>>자바스크립트

function treeshowhidden(imgid)
 {
     var imgobj = document.getElementById(imgid);
 
     if ( imgobj.getAttribute("src").indexOf("hide.gif") > 0 )
    {
          imgobj.src = imgobj.getAttribute("src").replace("hide.gif","show.gif");
    }
    else
    {
          imgobj.src = imgobj.getAttribute("src").replace("show.gif","hide.gif");
     }
 }

>> HTML샘플

<dl>
     <dt><a href="javascript:treeshowhidden('taxtree_<%=++idx%>')">
      <img id = "taxtree_<%=idx%>"src="/images/btn/btn_hide.gif" alt="hide"/></a>
     </dt>
 </dl>


대충 이런식으로 id를 jsp, php 단에서 달아주고,
id로 컨트롤 하는 방식... 사실 이경우가 제일 단순한 방법이긴 하다.

자바스크립트에서 이미지 파일 이름 비교할때,
if ( imgobj.getAttribute("src") =="/images/btn/btn_hide.gif") 로 안하고
if ( imgobj.getAttribute("src").indexOf("hide.gif") > 0 )

하는 이유는, 실제 src가 리턴될때 http:/xxxx.xxx/adsf/images/bin/btn_hide.gif 처럼
full 주소로 나오기 때문에 이렇게 비교함 !!!!

사실 간단한 사실인데... 막상 처리할때 헤맨다 -_-;


근데.. 세상이 이렇게 단순한 형태만 지원되길 원하지 않는다.
암 그렇고 말고

사용자 삽입 이미지


맨날 id 노가다로 해결하던 유저에게 가치관의 혼란이 오기 시작한다. 뭔가 방법은 없을까?
하지만, 몇번끄적거리다가,,,, 많은 사람들은 jsp, php에서
다음과 같이  이중포문으로 id 를 막 달고 이벤트를 걸기 시작한다   (-ㅅ-)

for (int i=0; i<cnt1; i++) {
  for (int j=0; j<cnt2; j++)
  {
       <img id = "imgid_<%=i%>_<%=j%>" .... />
  }
}


중요한 사실이 있다...
우리는 웹으로 개발할때 종종...
웹에서의 특성으로 해결 할 수 있는걸... id남발을 하는 경우도 있다.
(사실 html은 계층적 구조라서 하위 노드 접근도 가능하다)

<script>
function treeshow(id)
{
 var ulobj = document.getElementById(id);
 var liobj = ulobj.getElementsByTagName("li");
 var cnt = liobj.length;
 for(var i=0; i < cnt; i++)
 {
  if ( liobj[i].getElementsByTagName("img")[0].getAttribute("src").indexOf("hide.gif") > 0 )
  {
    liobj[i].getElementsByTagName("img")[0].src = liobj[i].getElementsByTagName("img")[0].getAttribute("src").replace("hide.gif","show.gif");
  }
  else
  {
   liobj[i].getElementsByTagName("img")[0].src = liobj[i].getElementsByTagName("img")[0].getAttribute("src").replace("show.gif","hide.gif");
  }
 }
}
</script>
<div>
 <dl>
  <dt><a href="javascript:treeshow('tree_1');">1. 하위 내용만 이미지변경</a></dt>
  <dd>
  <ul id="tree_1">
   <li>일.<img src="/images/btn/btn_hide.gif"/></li>
   <li>이.<img src="/images/btn/btn_hide.gif"/></li>
   <li>삼.<img src="/images/btn/btn_hide.gif"/></li>
  </ul>
  </dd>
 </dl>
 <dl>
  <dt><a href="javascript:treeshow('tree_2');">2. 하위 내용만 이미지변경</a></dt>
  <dd>
  <ul id="tree_2">
   <li>일.<img src="/images/btn/btn_hide.gif"/></li>
   <li>이.<img src="/images/btn/btn_hide.gif"/></li>
  </ul>
  </dd>
 </dl>
</div>

사실 위 소스는...
고정된 내용에 대해 에러체크도 없이 만든 ..
즉 쉽게 말하면 조금 후진소스다...

그래도 html의 각 태그별 하위 계정에 접근할 수 있다는걸 보여주는 아주 simple한 예제...

id를 남발해서 처리하기보다는...
자바스크립트에서 하위계정으로 접근해서 바꾸는 방식으로
한번쯤 해보는것도 나쁘지 않을듯...





+ Recent posts