어제 :
오늘 :
총합 :

'사실 난 진지함'에 해당되는 글 3건

  1. 그냥 이것저것 잡다한 팁 10 2009.12.31
  2. 신에게 질문을 할 수 있다면? 3 2008.04.28
  3. 투표할 때 반대표 기능을 추가하자 3 2008.04.10

그냥 이것저것 잡다한 팁

from 기타 2009. 12. 31. 14:24

한해를 마무리하면서, 올해 일하면서 얻게 된 짜잘한 프로그래밍 팁들을 정리해봅니다.

오라클 관련
외부 조인 (Outer Join)을 할때 IN 연산 문제
오라클에서 외부 조인을 할때는 IN이나 OR 조건을 쓰지 못합니다.
실행할 때 에러가 나죠.
이걸 고치는 방법입니다.

SELECT * FROM TABLE1 A, TABLE2 B
WHERE A.ID = B.ID(+)
AND B.VALUE(+) IN ('X', 'Y')

이렇게 하면 외부조인에서는 IN이나 OR가 안된다고 에러가 납니다.
위의 쿼리를 다음과 같이 고쳐줍시다

SELECT * FROM TABLE1 A, TABLE2 B
WHERE A.ID = B.ID(+)
AND DECODE(B.VALUE(+), 'X', 1, 'Y', 1) = 1
 
이러면 정상적으로 외부 조인이 됩니다.

위의 필드명이나 값은 어디까지나 예제로 넣은 것이니 자기가 쓰는 데이터에 맞게 변형하시면 됩니다.

다들 쿼리보면 바로 이해할 정도는 되잖아요~?



통계함수에서의 PARTITION 사용
오라클에서 쓰는 통계함수... ROW_NUMBER() 라던가 RANK()라던가 DENSE_RANK()... 사용하기에 따라서 상당히 편하게 작업할 수 있게 해줍니다.
한 사람의 여러개의 데이터 중에서 가장 최초의 기록을 찾는다던가 할때 저는 주로 ROW_NUMBER()를 사용해 일련번호를 생성하고, 그 번호가 1인 기록만을 찾는 식으로 씁니다.
이때,
ROW_NUMBER() OVER (PARTITION BY A.REGNO1, A.REGNO2 ORDER BY A.REGDATE) AS rn
대충 이런 모양으로 쓸 수가 있는데요....
문제가 되는게 바로 이 PARTITION BY 부분.
역할은 대충 GROUP BY랑 비슷하게 그룹으로 묶어주는 역할을 하는데요... 위의 예제처럼 쓰다보니 가~끔 예상과는 다른 결과가 나오는 경우가 있더군요. (원인을 찾느냐고 좀 고생했습니다)
문제는, PARTITION BY 뒤에는 단지 표현식. 하나만 쓰라고 되어있네요....
그걸 바탕으로 수정한 결과물 ->
ROW_NUMBER() OVER (PARTITION BY A.REGNO1 || A.REGNO2 ORDER BY A.REGDATE) AS rn
이렇게 하면 REGNO1, REGNO2를 결합한 값으로 그룹을 만들고, 거기서 REGDATE 순으로 정렬하여 번호를 생성해 줍니다.
이건 REGNO1과 REGNO2가 고정길이값을 가졌다는 전제하이고요... 만일 필드길이를 정확히 알 수 없다면 RPAD나 SUBSTR 등을 조합해서 만들면 될겁니다.



자바스크립트 관련
parseInt의 문제

보통 문자에서 숫자로 변환할 때 parseInt를 많이 씁니다.
하지만 문제가 있는데, 예를 들어 데이터가 "0123"이라고 들어있을 때 이 값을 parseInt하면 숫자가 123이 나오는게 아니라 83이 나옵니다. 맨 앞에 나오는 0이라는 값 때문에 이것을 10진수가 아닌 8진수로 인식해서 변환했기 때문이죠. 물론 parseInt에 형식을 더 지정해 줄 수도 있지만... 귀찮으니 Number("0123") 이렇게 하면 바로 123으로 변환되서 나옵니다.
eval도 비슷하게 쓸 수 있지만, eval은 단순히 변환용으로 쓰기에는 너무 강력하니 추천하지 않습니다. 어떤 내용이 들어왔느냐에 따라 단순히 숫자 변환이 아니라, 함수를 실행시키거나 할 수도 있거든요...


함수인자 갯수를 동적으로 받기
자바스크립트에서 함수 인자를 받을 때 인자가 몇개 올지 모르는 경우....
인자를 동적으로 받을 수 있습니다.

function testFunc() {
    var args = this.testFunc.arguments;
    var i;

    for (i = 0; i < args.length; i++) {
        alert((i+1) + "번째 인자 : " + args[i]);
    }
}

위와 같은 방식으로 함수를 짜면
testFunc("A");
testFunc("A", "B", "C");
이렇게 다양하게 호출이 가능합니다.


엑셀 자동화에서의 팁
다른 프로그램(자바스크립트나 VB 등)에서 오피스 프로그램 등을 호출하고 제어할 수 있는데요
(엑셀의 경우 셀의 값을 지정한다거나 서식을 준다거나)
이때 최종적으로 파일 저장시에 약간의 문제가 생깁니다.
파일명을 test.xls라고 준다고 해도
파일 저장형식이 현재 컴퓨터에 깔려져 있는 엑셀의 버전에 맞춰지기 때문이죠.

최신 엑셀 프로그램이 깔려있다면... 저렇게 확장자를 xls로 지정해도 실제적으로 xlsx파일로 저장됩니다.
저는 개인적으로 xlsx는 좀 싫어하는데요...
기존 버전의 엑셀 쓰는데서는 열리지 않는 문제도 있고요... 제가 잘쓰는 WinM에서는 저 파일을 압축파일로 인식해 자동으로 압축파일 보기 모드로 들어가지거든요... (xlsx는 내부적으로는 zip으로 압축된 파일입니다)
따라서 파일 저장시에 "구버전 엑셀 XLS파일"로 형식을 지정해주는게 좋습니다.

자바스크립트에서 할 경우에는
var oXL = new ActiveXObject("Excel.Application");
var oWB = oXL.Workbooks.Add();
var oSheet = oWB.ActiveSheet;

.....(엑셀 처리 작업을 한다).....

// 최종 저장시에
oSheet.SaveAs(fileName, 56);

이런 식으로 해주면 됩니다.
파일 형식 번호 56번은 엑셀 97-2003 포맷을 의미합니다.
제가 실험해본 결과, 더 이전 버전에서는 셀 병합에서 약간 문제가 생기더군요.
그래서 엑셀 97-2003 포맷을 추천합니다.
비베 같은데서는 상수로 이름이 나오지만, 자바스크립트에서는 안나오니 그냥 저렇게 숫자로 지정~~

저장을 안하고 그냥 사용자에게 바로 보여줄 경우에는, 사용자가 알아서 저장하라고 하면 되겠죠? ~.~


아웃룩 자동화에서의 팁
오피스의 아웃룩 자동화를 통해 프로그램에서 바로 일정이나, 할 일 등을 지정할 수도 있습니다.
그런데 문제는 아웃룩 어플리케이션이 실행되어있지 않을 때 작업을 하면, 그 작업 내용이 날라간다는 겁니다.
사실 아웃룩이 내부적으로는 실행되는 중인데, 사용자 로그인 문제 때문에 데이터가 어느 계정에 저장될지가 불확실해서 이런 문제가 발생하는 거죠.
이 문제의 해결을 위해서는 해결 방법이 3가지 정도 있습니다.

1. 아웃룩이 실행되어 있지 않으면 아웃룩을 강제로 실행시켜준다.
...이렇게 정보를 쓴 곳도 종종 있지만... outlook.exe를 실행시키는 방식이라 뭔가 찜찜. 비추천.

2. 아웃룩 창을 강제적으로 디스플레이 시켜준다.
var ol = new ActiveXObject("Outlook.Application");
var olns = ol.GetNamespace("MAPI");
var objFolder = olns.GetDefaultFolder(9);   // 9는 아웃룩에서 일정의 폴더 번호
objFolder.Display();
이렇게 하면 아웃룩의 일정창이 디스플레이 되는데요.
이 상태에서 새 약속/행사 등을 저장하면 제대로 들어갑니다.
하지만 화면에 뭔가 뜨기 때문에, 백그라운드로 얌전히 하려는 사람에게는 비추.

3. 아웃룩에 사용자 계정 로그인을 한다.
var ol = new ActiveXObject("Outlook.Application");
var olns = ol.GetNamespace("MAPI");
olns.Logon("", "", false, false);


이렇게 하면 사용자프로필, 암호가 없는 상태로 로그인을 합니다.
이러면 기본 사용자 로그인 상태가 되겠죠?

이 상태로 새 작업을 만들고 저장하면, 기본 사용자의 일정 등에 작업이 추가가 됩니다.
(프로필명이나 암호가 지정되있다면, 그건 사용자에게 입력을 받으면 되겠죠)

최종적으로는 ol.Application.Quit(); 로 메모리에서 제거해주시는거 잊지마시구요.

이 방법을 쓰면 뭐가 일어났는지 사용자가 모르게, 아웃룩을 제어하는게 가능합니다.
nonVisible상태에서 작업이 다 끝나니까요...



--------------------------------------------------------------------------------
이런 것 말고도 다른 팁들도 있지만...
현재 일하는 곳에서 사용하는 프레임워크에 종속된 팁들도 있고 하니...
일단 범용으로 쓰이는 오라클이랑 자바스크립트에 대한 것만 살짝 올려봤습니다.

건전한 블로그에 맞는 건전한 한해 마무리 포스팅이였습니다. ^^
(아 근데 이 블로그를 IT 관련 블로그로 알고 오신 모님에게는... 볼 때마다 뭔가 뜨끔뜨끔)

,



1st 블로그양 - 아야네




Miss.Blog (아야네)...

신에게 무엇인가 질문을 할 수 있다면 어떤 질문을 할건가요?
블로그양은 마음에 든 남자를 사로잡는 방법을 알고 싶은데,
어떤 질문을 할건지 알려주세요
──────────────────────────────────────────────────
세르피(serupy)...

전 일단 기독교인이니 그쪽 관점에서 대답할께요

1. 사람이 죽은 후에는 천국이나 지옥에 간다고 하는데, 무(無)가 되어 완전소멸하는 개념은 없는건가요? (아무리 천국이라도 영원한 삶이란 것은 끔찍할 것 같아요)

2. 다른 여자에게 음탕한 상상만 해도 죄라는 것은 이해하겠는데요, 실제 인간이 아닌 2차원 미소녀에게 하앙하앙하는 것도 죄인가요?

3. 하렘은 죄인가요? 성경에 보면 부인 여럿인 사람들도 있던데...

제대로 묻자면 공룡의 멸종부터 세계의 각종 비밀까지 묻고 싶은 것은 산더미 같지만 일단은 이 정도만?

,



이번 주제는 제목 그대로 선거날 투표할 때 반대표 기능을 추가하자! 는 겁니다

현행 선거 제도 하에서는 찬성표의 기능만 있고, 찬성의 다수결로 결과가 정해지죠

하지만 예를 들어 후보 A, B, C가 있다고 할 때
후보 A를 지지하는 사람이 500명, 반대하는(안티)가 400명 있다고 하고
후보 B를 지지하는 사람이 400명, 안티는 특별히 없다고 합시다
(후보 C는 그냥 남는 표 보내기 위한 듣보잡으로 하겠슴다)
이때 기존 방식으로는 A가 선발되겠지만 저렇게 많은 사람이 반대하는 사람이 아닌, B가 선발되어야 하는 것이 아니냐는게 제 생각입니다.

투표에 찬성표를 +1점, 반대표를 -1점이라고 하고 각각 1표씩 행사할 수 있다고 할 경우
위의 경우에서 A는 +500 -400 = +100점
B는 +400점
C는 알게뭐야
이렇게 해서 B가 선택될 수 있게하면 좋겠다는 생각입니다.

이런 생각을 하게된 계기가...
사실 전 한나라당을 특별히 좋아하거나 하지는 않습니다. (사실 좀 싫기도 합니다)
하지만 열린우리당이 너무나 싫었기에(지금은 통합민주당 쪽에 들어가있기에 통합민주당을 싫어합니다) 어쩔수 없이 한나라당 쪽에 투표를 하곤 했는데요
한나라당은 그런 "어쩔 수 없이 찍어주는 것"을 마치 국민의 선택인양(좋아서 찍는걸로) 착각하는 경우가 있더군요. 이럴때 저런 반대표 기능이 부가되면 국민의 속내를 조금은 더 잘 나타낼 수 있지 않을까하는거죠.

찬성표(+1점)이나 반대표(-1점) 중 하나만 행사할 수 있다고 할 경우 결과가 더 확실히 나타나는대요
A후보 : 찬성 50표 반대 50표
B후보 : 반대 200표
이런식으로 결과가 나왔다고 하면 일단 A가 이기긴 하겠지만 국민들이 B가 싫어서 뽑은거지, A를 압도적으로 좋아했느니 뭐니하는 착각은 덜하게 되지 않을까요?

뭐  이런 경우에는 과연 자기가 좋아하는 후보에게 +1을 행사하는 것과, 자기가 좋아하는 후보의 최대 라이벌에게 -1을 행사하는 것 중 어느게 더 효율적인가는 계산해볼 여지가 있습니다만, 그런 것은 수학자들이 다 알아서 하겠죠 ~.~


(모처럼 진지하고 얌전한 포스팅이 된것 같은 기분)

,