::NPTEAM:: Network Programer Team

검색 :
RSS 구독 : 글 / 댓글 / 트랙백 / 글+트랙백

정규식을 이용하여 보다 쉽게 쿼리문을 작성해 보자_02

DB 쿼리 작업을 하다보면, 테이블에 insert 쿼리문를 대량으로 작성해야 하는 경우가 많다.
특히, 엑셀로 작업한 결과물을 DB에 insert 하거나, update 해야 할 경우 쿼리문 작성으로 고단한 경우가 종종 발생한다.

정규식을 활용하여 원하는 정보를 쿼리식으로 손쉽게 만드는 방법에 대해서 알아보자.


위와 같은 테이블 정보에 아래의 데이터를 INSERT 해야 한다.

엑셀과 같이 입력하고 싶은 자료를 정규식을 지원하는 Notepad2와 같은 편집기에 복사 & 붙여넣기한다.

라인의 처음 시작 부분은 정규식에서 ^로 표시한다.

^(\d{4})한 줄의 시작 부분이 숫자(\d)로된 4자리 글자를 먼저 선택한다.(숫자 4자리 선택)
이렇게 한 줄의 첫번째 되는 부분을 정확히 일치시켜야 줄 중간에서 숫자 4자리를 무시하고 처리할 수 있다.
선택 범위 :  [8001]

^(\d{4})[\t]+숫자 4자리로 시작하고, 그 다음 탭으로 떨어진 공간을 선택한다.(TAB까지 선택)
선택 범위 :  [8001 TAB]

^(\d{4})[\t]+([^\t]+)탭으로 떨어진 공간 다음에, 탭이 아닌 문자를 선택한다.(TOM까지 선택)
선택 범위 :  [8001 TAB TOM]

위와 같이 탭으로 떨어진 문자 [\t]+, 탭이 아닌 문자 ([^\t]+) 를 반복적으로 기입한다.

^(\d{4})[\t]+([^\t]+)[\t]+([^\t]+)[\t]+([^\t]+)[\t]+([^\t]+)[\t]+([^\t]+)[\t]+([^\t]+)[\t]+(\d+)$선택 범위 :  [8001 TAB TOM TAB DBA TAB 8400 TAB 1981-12-03 TAB 3000 TAB 10 TAB 40]

중간 부분은 [\t]+ 탭과 ([^\t]+) 탭을 포함하지 않은 문자열로 구분하면 되지만,
시작부분과 마찬가지로 종료 부분에는(\d+)$      : 숫자로 종료(0-9)
(\w+)$      : 문자로 종료(a-z, A-Z)
([\d|\w]+)$ : 숫자나 문자로 종료(0-9, a-z, A-Z)
를 명시적으로 표기해야 한다.
(단, \w는 a-z, A-Z의 문자열을 말하며 한글 문자열을 지원하지 않는다.)

위와 같이 작성된 정규표현식을 찾을문자에 입력하고 찾기 버튼을 누르면, 한 줄씩 선택되는 것을 확인할 수 있다.

이때, 중요한 점! 지난번에도 언급했듯이 정규표현식에서 () 괄호로 묶은 것은 그룹으로 처리된다.
첫번째 괄호로 묶인 문자열은 \1로 치환할 수 있고,
두번재 괄호로 묶인 문자열은 \2로 치환할 수 있다....
또한, 괄호로 묶인 전체 문자열 \0로 치환할 수 있다.

우리가 치환하고자 하는 부분은 이미 괄호로 8번 묶어 놓은 상태 이므로,
바꿀 문자에 다음과 같이 입력하고 모두 바꾸기를 수행해 보자.

INSERT INTO TEST_EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values ( \1, '\2', '\3', \4, '\5', \6, \7, \8);


위와 같이 모두 바꾸기를 수행하면 다음과 같은 결과를 볼 수 있다.

지금까지 INSERT 문을 정규표현식을 이용하여 간단히 바꾸는 과정을 알아 보았다.

간단하지만 강력한 정규표현식.
위와 같이 적은 양의 자료를 입력할때에는 복사 붙여넣기로 해결되지만,
최소 천건에서 2-3만건의 자료를 처리할 때에는 정규표현식을 만드신 분이 정말 눈물나게 고맙게 느껴진다. ^^;

2009/03/28 11:32 2009/03/28 11:32

맨 위로

[ORACLE] ROW 데이터를 구분자 포함하여 가로로 출력하는 방법

2009/03/24 16:52, 글쓴이 TTF
select LTRIM( SUBSTR( MAX( SYS_CONNECT_BY_PATH( COLUMN_NAME, ', ') ), 2 ) ) as "OUTPUT_COLUMN" 
from ( 
    select 1 as INDEX_NO, 'AAA' as COLUMN_NAME FROM DUAL
    union all
    select 2 as INDEX_NO, 'BBB' as COLUMN_NAME FROM DUAL
    union all
    select 3 as INDEX_NO, 'CCC' as COLUMN_NAME FROM DUAL )
start with INDEX_NO = 1 
connect by prior INDEX_NO = INDEX_NO - 1

위와 같은 쿼리로 각 Row의 데이터를 하나의 Row로 출력할 수 있다.
2009/03/24 16:52 2009/03/24 16:52

맨 위로

정규식을 이용하여 윈도우 방화벽 사용자 지정 목록 편집하기


윈도우 방화벽은 이제 없어서는 안될 필수품이 되었다.
그렇지만 원하는  IP 주소 범위를 변경하기 위해서는 엄청난 키보드 화살표 오른쪽 버튼의 압박에 시달리게 된다.

빌 게이츠 횽 왜 윈도우 방화벽은 이렇게 사용하기 불편한 건가요?


이렇게 탄식을 하더라도, MS에서 방화벽 UI를 바꿔주길 기대하는 것은 무리다.
"윈도우 그림판으로 포토샵처럼 편집하고 싶어요~" -_-;

우리는 정규표현식을 이용해서 이번 난관도 아주 약간 편하게 헤쳐나갈 수 있다.


사용자 지정 목록의 내용을 복사해서 notepad2에 붙여넣기 해 보자.
(안타깝게도 MS 기본 메모장에서는 정규식을 지원하지 않는다.)


오~ 스크롤 압박!!
모니터를 확! ... 참자, 우리에겐 정규표현식이 있다.



찾을 문자에 ,
바꿀 문자에 ,\r\n
을 입력하고 모두 바꾸기를 클릭한다.



오~ 완전 깔끔하게 정리되었다.
IP 범위 수정을 모두 마쳤으면, 바꿀 문자와 찾을 문자를 바꿔서 넣고 모두 바꾸기를 한다.



다시 1줄로 정리되었다.

이렇게 쉽고 강력하지만, 우리는 윈도우 메모장에서는 정규표현식을 사용할 수 없다.

빌 게이츠 횽 UI 개선 안해줘도 좋은데요. 메모장에서 정규표현식 지원해 주시면 안되나요?
2009/03/21 04:30 2009/03/21 04:30

맨 위로

정규식을 이용하여 보다 쉽게 쿼리문을 작성해 보자_01

위와 같이 test_emp 테이블에서 원하는 EMPNO를 선택하여,

select *
from test_emp
where in ( ... )

select 쿼리문을 만들다 보면, EMPNO 컬럼을 드래그 복사해서 where in ( 7369, 7499 ...)
이렇게 한번에 넣고 싶을때가 많다.

이렇게 선택하고 텍스트 편집기 창에 복사하면, 다음과 같이 나온다.

위와 같이 나온 text를 전체 선택하여, 주석처리를 한다.

그리고 다음과 같이 "--" 텍스트를 ", "로 치환하고

다음과 같이 쿼리문을 작성하여 실행하면, 편하게 쿼리문을 작성할 수 있다.


이건 누구나 다 아는 내용이다.
게다가 정규식은 보이지도 않는데 어떻게 된것이냐?
 라고 생각하시는 분들을 위해서 이제부터 본격적으로 정규식을 써 보겠습니다.



위와 같이 선택된 값을 다음과 같은 쿼리문으로 만들려고 합니다.
select *
from test_emp
where
OR ( JOB = 'CLERK' AND EMPNO = '7369' )
OR ( JOB = 'CLERK' AND EMPNO = '7900' )
OR ( JOB = 'MANAGER' AND EMPNO = '7698' )
OR ( JOB = 'SALESMAN' AND EMPNO = '7654' )
이렇게 쿼리를 만들고 where 다음의 OR 글자만 지워주면 됩니다.
아래의 정규표현식을 실행해볼까요?

와우! 정말 한번에 원하는 쿼리와 근접하게 변환되었습니다.


여기까지 잘 따라오셨나요?
이쯤에서 위에서 쓰인 정규표현식을 설명하고 넘어가기로 하죠.

위에서 빨간색 네모로 표시된 정규식은 다음과 같습니다.
^(\w+)\t(\d+)^  : 한 줄의 시작부분을 의미합니다.
     ^이 없으면, 한 줄의 중간 부분에서도 정규식 패턴이 발견되면, 해당 문자열을 찾아냅니다.
() : 괄호로 묶은 곳이 2군데가 있는데요.
     괄호로 문장을 묶으면 해당 문자열을 그룹으로 치환할 수 있습니다.
     이 부분은 아래에서 더 자세히 설명드리죠.
\w : 알파벳으로 이루어진 한 문자를 찾습니다. (a~z, A~Z) 사이의 문자를 말하는거죠.
\t : 탭으로 띄어쓰기된 공간을 찾습니다.
\d : 숫자로 이루어진 한 문자를 찾습니다. (0~9) 사이의 문자를 찾습니다.
+  : 바로 앞의 문자가 1번이상 계속 반복되는 것을 말합니다.


해석하면,
1. 한 줄의 시작부분이 (\w+) 알파벳으로 연속된 문자열을 찾아서 그룹으로 묶는다.
2. \t 탭으로 띄어쓰기된 공간을 찾는다.
3. (\d+) 숫자로 연속된 문자열을 찾아서 그룹으로 묶는다.


여기까지 이해 가셨나요? 그렇다면 바꿀 문자(파란 네모안의 정규식)에 해당하는 정규식을 살펴 보기로 하죠.
OR ( JOB = '\1' AND EMPNO = '\2' )여기에서는 중요한 포인트가 바로 \1 과 \2 입니다.
\1 : 찾을 문자(빨간 네모안의 정규식)에서 첫번째로 그룹화된 문장을 이 부분에 끼워넣기 한다.
\2 : 찾을 문자(빨간 네모안의 정규식)에서 두번째로 그룹화된 문장을 이 부분에 끼워넣기 한다.

자 이제 이해가 가셨나요?
정규표현식으로 다양한 문자 치환 방법이 있는데요. 그중에서 자주 쓰이는 그룹 치환에 대해서 알아 보았습니다.

이처럼 정규표현식을 활용하면, 다양하고 복잡한 문자열을 손쉽게 바꿀 수 있습니다.

TIP.
Tab으로 띄어진 문자열을 구분하기 위해서는 다음의 정규식으로 검색한 후 치환하세요.
^(\d+|\w+)\t(\d+|\w+)\t(\d+|\w+)
2009/03/21 03:26 2009/03/21 03:26

맨 위로

USB On 2.0 - autorun.inf 바이러스로 부터 해방~

2009/03/10 21:28, 글쓴이 TTF

지긋지긋한 USB 자동 실행 바이러스
윈도우 OS에서는 예전부터 "autorun.inf" 의 정보를 이용해서 CD-ROM 컨텐츠를 자동 실행하여 설치할 수 있도록 하였습니다.

CD-ROM 미디어에 포함되어 있는 컨텐츠는
 1. 대부분 바이러스 검사를 마친 배포 프로그램
 2. 읽기 전용인 미디어 특성
때문에 autorun.inf 파일로 자동실행되는 것이 문제되지 않았습니다.

그러나 읽기 / 쓰기가 가능한 USB 메모리를 사용하면서 문제가 발생한다.
autorun.inf 파일에 설정된 프로그램을 자동 실행할 수 있기 때문에 USB를 컴퓨터에 꼽는 것만으로도 루트킷 설치, 프로그램 설치 등등의 작업을 진행할 수 있다.

USB On은 autorun.inf 이름의 폴더를 생성하고, 만들어진 폴더의 읽기 쓰기가 불가능하도록 방지하기 때문에, 이러한 Autorun.inf 바이러스의 실행을 미리 방지할 수 있다.

2009/03/10 21:28 2009/03/10 21:28

맨 위로

TextCube를 잘못 설치해서 난감한...

호스팅을 이전하기전 방문자 수가 하루 평균 200명이었으나,
호스팅을 이전한 후에는 방문자 평균 6-7명으로 급격히 감소했습니다.

그러던 중 원인이 될만한 사실을 발견하였습니다. -_-;
예전에는 http://www.npteam.net/111 과 같은 링크 주소를 사용하였는데요.
웹호스팅 업체에 텍스트큐브 자동 설치를 의뢰한 후, http://npteam.net/tc/111 과 같이 변경되었습니다.

결국 웹 루트/tc 폴더에 설치되면서 생긴 헤프닝이었습니다.
이 문제를 해결해 보려고 여러가지 방법을 사용하였는데요.
index.php 파일을

<?php
header("Location: /tc/".$_SERVER['QUERY_STRING']);
?>
와 같이 만들어서 사용해 보았으나,
http://www.npteam.net/index.php?123 이렇게 작성해야만
http://www.npteam.net/tc/123 으로 포워딩 되었습니다.

어떻게든 텍스트큐브를 다시 설치하지 않는 방법으로 진행하려고 노력하였으나,
tc 폴더를 웹 root로 Move 한 다음, config.php를 삭제하고 html폴더 권한을 777로 수정한 후
결국 단일블로그형으로 다시 설치하였습니다.
설치 완료된 후 html 폴더 권한을 원상 복귀 해주는 것은 기본 센스죠. ^^;

오랫만에 블로그 업데이트를 하니 좋은점이 많네요.
제 블로그에 방문해 주시는 모든 분들에게 다시 한번 감사드립니다.

행복하시고, 건강하세요~.
2009/03/10 18:57 2009/03/10 18:57

맨 위로