출처 : http://www.ibm.com/developerworks/kr/series/web/index.html
아래 내용은 위 출처의 기사의 일부를 복사 후 편집/수정한 것입니다.
단순히 개인적으로 알고자하는 내용만을 남긴 것이니, 자세한 정보는 위의 출처를 참조하세요.

* HTTP 준비 상태
* HTTP 상태 코드
* 요청 유형들

HTTP 준비 상태
* 0: (open()을 호출하기 전에는) 요청이 초기화 되지 않는다.
* 1: (send()를 호출하기 전에는) 요청은 설정은 되지만 보내지지 않는다.
* 2: 요청이 보내지고 처리 중에 있다. (이 시점에서 응답에서 콘텐트 헤더를 얻을 수 있다.)
* 3: 요청이 처리 중에 있다. 부분적인 데이터를 응답에서 사용할 수 있지만 서버는 이 응답으로는 종료되지 않는다.
* 4: 응답이 완료된다. 서버의 응답을 받고 이를 사용한다.

readyState 0 (readyState == 0)으로 표시되는 첫 번째 준비 상태는 초기화 되지 않은 요청을 나타낸다. 요청 객체에 대해 open()을 호출하면 속성은 1로 설정된다. 대부분 요청을 초기화 하면서 open()을 호출하기 때문에 readyState == 0을 보는 일은 드물다. 더욱이 초기화 되지 않은 준비 상태는 실제 애플리케이션에서는 쓸모 없다.

 function getSalesData() {
   // Create a request object
   createRequest();        
   alert("Ready state is: " + request.readyState);

   // Setup (initialize) the request
   var url = "/boards/servlet/UpdateBoardSales";
   request.open("GET", url, true);
   request.onreadystatechange = updatePage;
   request.send(null);
}
open()이 호출되기 전에 준비 상태를 체크
요청 객체가 새로운 요청을 만들기 전에 초기화 되지 않은 상태(readyState == 0)에 있다는 것을 확인

0이 4와 같을 때
다중 JavaScript 함수들이 같은 요청 객체를 사용하는 경우, 그 요청 객체가 사용되고 있지 않다는 것을 확인하기 위해 준비 상태 0을 확인하면 문제가 많아질 수 있다. readyState == 4는 완료된 요청을 나타내기 때문에, 4로 설정된 준비 상태인 채로 사용되지 않은 요청 객체를 종종 보게 된다. abort()이라고 하는 요청 객체를 리셋하는 함수가 있지만 이는 여기에 사용하는 것이 아니다. 다중 함수들을 사용해야 한다면 다중 함수에 객체를 공유하는 것 보다 각 함수용 요청 객체를 생성 및 사용하는 것이 낫다.

브라우저 차이
Firefox 1.5
    * 1
    * 2
    * 3
    * 4

Safari 2.0.1
    * 2
    * 3
    * 4
Safari는 첫 번째 준비 상태를 배제하고 그 이유에 대해서는 자세히 나와있지 않다. 바로 이것이 Safari 방식이다. 또한 중요한 포인트이기도 하다. 서버에서 데이터를 사용하기 전에 요청의 준비 상태가 4라는 것을 확인하는 것은 좋은 생각인 반면 일시적인 준비 상태에 의존하는 코드를 작성하는 것은 다른 브라우저 마다 다른 결과를 얻을 수 있는 확실한 방법이다.

Opera 8.5를 사용할 때 상황은 더 악화된다.
    * 3
    * 4

Internet Explorer
    * 1
    * 2
    * 3
    * 4

responseText
준비 상태 2에서 responseText 속성은 정의되지 않는다
준비 상태 3에서, 서버는 responseText 속성에 값을 배치한다

준비 상태 3의 응답은 스크립트 마다, 서버 마다, 브라우저 마다 다르다. 애플리케이션을 디버깅 하는데 매우 유용하다.
모든 문서와 스팩들에서는 준비 상태가 4가 되어야지만 데이터를 안전하게 사용할 수 있다고 나와있다. 나를 믿으라. 준비 상태가 3일 때에도 responseText 속성에서 데이터를 얻을 수 있다. 하지만 여러분의 애플리케이션에서 이것에 의존하는 것은 좋지 않은 생각이다. 준비 상태 3에서 완전한 데이터에 의존하는 코드를 작성하는 것은 데이터가 불완전하다는 증거이다.

준비 상태가 변할 때 마다 폼이나 페이지에 대한 필드를 업데이트 할 수 있다. 예를 들어, 프로그레스 인디케이터의 넓이를 준비 상태 1에 25 퍼센트, 준비 상태 2에 50 퍼센트, 준비 상태 3에 75 퍼센트, 준비 상태 4에 100 퍼센트를 설정한다. 물론 알다시피, 이 방식은 좋기는 하지만, 브라우저에 의존적이다. Opera에서는 첫 번째 두 개의 준비 상태를 결코 얻지 못하고 Safari는 처음 1 상태를 누락시킨다.

HTTP 상태 코드

* 401: Unauthorized
* 403: Forbidden
* 404: Not Found
* 200: Everything is OK

리다이렉션과 재 라우팅
에러에 대해 이야기 하기 전에 Ajax를 사용할 때 걱정하지 않아도 될 부분에 대해 말해두겠다. 바로 리다이렉션이다. HTTP 상태 코드에서, 이것은 300 대의 상태 코드이다.
* 301: Moved permanently
* 302: Found (요청이 또 다른 URL/URI로 리다이렉션 된다.)
* 305: Use Proxy (요청은 프록시를 사용하여 요청 받은 리소스에 액세스 해야 한다.)

Ajax 프로그래머가 리다이렉션에 대해 염려 할 필요가 없는 이유가 두 가지 있다.
* Ajax 애플리케이션들은 특정 서버측 스크립트, 서블릿, 애플리케이션을 위해 작성된다. 그 컴포넌트를 없애거나 다른 곳으로 이동하기 위함이다. 리소스는 변경되었다는 것을 (이미 이동했기 때문에)알고, 요청에서 URL을 변경하고 이러한 종류의 결과를 절대 만나지 않게 된다.
* 보다 관련성 있는 이유가 있다. Ajax 애플리케이션과 요청들은 샌드박스화 되어있다. Ajax 요청을 만드는 웹 페이지를 공급하는 도메인은 그러한 요청에 응답해야 하는 도메인이다. 따라서 ebay.com에서 공급 받은 웹 페이지는 Ajax 스타일의 요청을 amazon.com에서 실행되는 스크립트에 할 수 없다. ibm.com 상의 Ajax 애플리케이션은 netbeans.org에서 실행되는 서블릿으로 요청할 수 없다.

결국, 요청은 보안 에러를 만들지 않고서는 또 따른 서버로 리다이렉션 될 수 없다. 그러한 경우에, 상태 코드를 전혀 얻을 수 없다. 디버그 콘솔에 JavaScript 에러를 갖게 된다. 따라서 많은 상태 코드에 대해 생각하는 동안 리다이렉션 코드 정도는 무시할 수 있는 것이다.

HTTP 상태코드 처리
 function updatePage() {
  if (request.readyState == 4) {
     if (request.status == 200) {
        var response = request.responseText.split("|");
        document.getElementById("order").value = response[0];
        document.getElementById("address").innerHTML =
         response[1].replace(/\n/g, "<br />");
     } else if (request.status == 404) {
        alert ("Requested URL is not found.");
     } else if (request.status == 403) {
        alert("Access denied.");
     } else
        alert("status is " + request.status);
  }
}

추가 요청 유형
향상된 에러 핸들링과 정보 수집을 위해 HEAD 요청에 대해 배워야 한다.
 function getSalesData() {
    createRequest();
    var url = "/boards/servlet/UpdateBoardSales";
    request.open("HEAD", url, true);
    request.onreadystatechange = updatePage;
    request.send(null);
}

function updatePage() {
   if (request.readyState == 4) {
      alert(request.getAllResponseHeaders());
   }
}

이러한 헤더들을 개별적으로 사용하여 Ajax 애플리케이션에서 추가 정보나 기능을 제공할 수 있다.

유용한 HEAD 요청
HEAD 요청이 유용한 한 가지 부분은 콘텐트 길이나 콘텐트 유형을 검사할 때이다. 요청을 처리하기 위해 많은 양의 데이터를 보낼 것인지, 서버가 HTML, 텍스트, XML 대신 바이너리 데이터를 리턴해야 할지를 결정할 수 있다. (이 세 가지 모두 바이너리 데이터 보다 JavaScript에서 처리하는 것이 더 쉽다.)

이 경우, 적절한 헤더 이름을 사용하고 이를 XMLHttpRequest 객체의 getResponseHeader() 메소드로 보낸다. 따라서 응답의 길이를 알려면 request.getResponseHeader("Content-Length");를 호출한다. 콘텐트 유형을 알려면 request.getResponseHeader("Content-Type");를 사용한다.

많 은 애플리케이션에서 HEAD 요청을 하면 어떤 기능도 추가하지 않고 요청의 속도를 늦출 수 있다. (HEAD 요청을 실행하여 응답에 대한 데이터를 얻고 후속 GET 또는 POST 요청을 통해 응답을 실제로 받는다.) 하지만 스크립트나 서버측 컴포넌트에 대해 확실하지 않은 경우 HEAD 요청으로 기본적인 데이터를 받을 수 있다.


결론

Ajax 와 웹 프로그래머에게 이 글은 다소 어려울 것이다. HEAD 요청을 하는 것의 가치는 무엇인가? JavaScript에서 리다이렉션 상태 코드를 핸들해야 하는 때는 언제인가? 이 모두 좋은 질문이다. 간단한 애플리케이션의 경우, 이 모든 것은 가치가 별로 없다.

하지만 웹이 단순한 애플리케이션만 수용하는 것은 아니다. 사용자는 점점 고급화 되고 고객들도 강력한 에러 리포팅을 원한다. 관리자 역시 애플리케이션이 조금만 느려져도 해고를 당하게 된다.

간단한 애플리케이션을 넘어 XMLHttpRequest에 대한 이해를 높여야 할 때이다.

    * 다양한 준비 상태를 이해하고 이들이 브라우저 마다 어떻게 다른지를 이해하면 애플리케이션을 빠르게 디버깅 할 수 있다. 준비 상태에 기반하여 창조적인 기능을 만들고 요청자의 상태에 대해 사용자와 고객에게 보고할 수 있다.
    * 상태 코드를 핸들했다면 스크립트 에러, 예기치 못한 응답들, 엣지 케이스들을 다룰 수 있다. 결국, 애플리케이션은 언제나 잘 작동될 것이다.
    * 여기에 더하여 HEAD 요청을 만들고, URL의 존재를 검사하고 파일이 언제 수정되었는지를 파악하고 사용자가 유효 페이지를 얻었는지를 확인할 수 있다면 언제나 최신의 정보와 강력한 기능으로 사용자들을 만족시킬 수 있을 것이다.


사실 HEAD 요청은 뭐에 필요한지 잘 모르겠음.
리다이렉션 상태 코드는 핸들하지 않아도 상관없어 보임.
결론에서도 보듯이 핸들하면 좋다...는 정도일려나?
12장 동적 유효성 검사 프로그래밍도 패스.

13장 XPath 검색 프로그래밍


10장 SAX 기반 문서 처리 프로그래밍

빠르게 순차적으로 처리하기엔 좋으나, 한번 XML을 파싱한 다음 여러번 검색하기엔 안좋다.
순차적으로 검색하므로, 검색때마다 파싱해야함.


11장 XSLT 문서 변환 프로그래밍은 패스.
필요할 때 찾아볼 것
8장 XSL는 읽고 넘겼음. 필요할 때 찾아보면 될 듯.

9장 DOM 기반 문서 처리 프로그래밍

<parent>
  <element>TEXT</element>
</parent>

위의 경우 TEXT 자체도 노드로 취급한다는 점에 주의.
parent <- element <- TEXT 이런 식으로 상위 노드에 종속되어 있다.


<parent attr="ATTR">TEXT1
  <element>TEXT2</element>
</parent>

예를 들다보니 위와 같이 되었지만, 위와 같은 것은 없는듯.
TEXT1과 element의 레벨이 같아지므로, 관리불가!? 어느게 TEXT이고 어느게 element인지 알 수 없다. 전부 NODE이므로..
책이나 웹 찾아봐도 MIXED라는 것이, 문자 데이터 또는! 자식 엘리먼트이지, 문자 데이터와 자식 엘리먼트는 아니었음.


<parent attr="ATTR">
  <element>TEXT2</element>
</parent>

위의 경우도 마찬가지로  TEXT2, ATTR은 전부 하나의 노드로 취급한다. 하지만 속성은 그 값을 얻는 방식이 다르다.
parent <- element <- TEXT2
  <- ATTR

parent에 ATTR, element가 종속되어 있으나, ATTR 과 element는 동일 레벨이 아니다.
속성값(ATTR)을 얻을 때는 parent.getAttribute("attr");
TEXT1을 얻을 때는 eText = element.getFirstChild() 한 후, eText.getData();
1~5장까지는 훑어보면 알만한 내용.
6장 XML 스키마 언어는 조금 보다가 복잡해지고, 이번 프로젝트랑은 크게 상관없을 듯 하여 pass.
나중에 필요하면 찾아보는 걸로 해도 괜찮을 듯.

7장 XPath와 그 뒤의 DOM 기반 문서 처리, SAX 기반 문서 처리 쪽은 중요!

XPath관련

/child::booklist/child::book
루트 노드의 자식 노드인 booklist의 자식 노드인 book을 찾아라

/child::booklist/child::book/attribute::kind
루트 노드의 자식 노드인 booklist의 자식 노드인 book의 속성 kind값을 찾아라

/child::booklist/child::book[attribute::kind="computer"]
루트 노드의 자식 노드인 booklist의 자식 노드인 book 중에서, 속성 kind 값이 "computer"인 book 노드를 찾아라

/child::booklist/child::book[contains(child::title, "전자")]
루트 노드의 자식 노드인 booklist의 자식 노드인 book 중에서, book의 자식인 title 노드의 문자 데이터 값 중에 "전자" 가 포함된 book 노드를 찾아라.
<book>
    <title>전자사전</title>
</book>
뭐 이런거...

//book
XML문서 전체에서 book 노드를 찾아라.    /booklist/book 은 booklist의 자식 노드인 book을 찾는 것이므로 다르다.

/booklist/book[@kind="computer"]
루트 노드의 자식 노드인 booklist의 자식 노드인 book 중에서, book의 속성 kind의 값이 computer인 book 노드를 찾아라

//book[@kind="computer"]
XML문서 전체에서 속성 kind의 값이 computer인 book 노드를 찾아라

/booklist/book/title[../@kind="computer"]
루트 노드의 자식 노드인 booklist의 자식 노드인 book의 자식 노드인 title 중에서, title의 부모인 book 노드의 속성 kind 값이 computer인 title 노드를 찾아라


XPath 함수 사용

/booklist/book[position()=last()] 또는 /booklist/book[last()]
루트 노드의 자식 노드인 booklist의 자식 노드인 book 중에서, 마지막 위치에 있는 book 노드를 찾아라

/booklist/book[position()=2] 또는 /booklist/book[2]
루트 노드의 자식 노드인 booklist의 자식 노드인 book 중에서, 두번째 위치에 있는 book 노드를 찾아라

count(/booklist/book)
booklist 밑의 book 노드의 총 개수를 얻는다

/booklist/book[starts-with(title, '사')]
booklist 밑의 book 노드 밑의 title 노드의 컨텐츠 내용이 '사'로 시작하는 book 노드를 찾아라

/booklist/book[contains(title, 'XML')]
book 노드 중에서 자식 노드인 title 노드의 컨텐츠 내용에 'XML'이 포함되어 있는 book 노드를 찾아라

/booklist/book[not(contains(title, 'XML'))]
book 노드 중에서 자식 노드인 title 노드의 컨텐츠 내용에 'XML'이 포함되어 있지 않은 book 노드를 찾아라

출처 : http://www.ibm.com/developerworks/kr/series/web/index.html
아래 내용은 위 출처의 기사의 일부를 복사 후 편집/수정한 것입니다.
단순히 개인적으로 알고자하는 내용만을 남긴 것이니, 자세한 정보는 위의 출처를 참조하세요.

Part2는 Part1과 상당부분 중복되나, 좀더 자세한 내용임.

XMLHttpRequest

open(): 새로운 요청을 서버에 설정함.
send(): 요청을 서버에 전송함.
abort(): 현 요청에서 벗어남.
readyState: 현 HTML 준비상태를 제공함.
responseText: 요청에 응답하기 위해 서버에서 재전송하는 텍스트.

에러 처리기능으로 XMLHttpRequest 객체 생성
<script language="javascript" type="text/javascript">
var request = false;
try {
  request = new XMLHttpRequest(); // 생성 시도. IE이외의 브라우저라면 생성됨.
} catch (trymicrosoft) {
  try {
    request = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (othermicrosoft) {
    try {
      request = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (failed) {
      request = false;
    }
  }
}

if (!request)
  alert("Error initializing XMLHttpRequest!");
</script>
생성 로직을 별도의 함수로 만들어서 사용하면(위와 같이 정적 자바스크립트가 아닌), 생성 시 문제 발생에 대한 에러 통지기능을 지연시키므로 대부분의 Ajax 프로그래머들은 위의 방법을 활용하지 않는다.
10/15 필드가 있는 복잡한 형태에 선택상자 등등이 있다고 상상해보자. 사용자가 필드 14에 있는 텍스트를 형식에 나온 대로 기입할 때 몇 가지 Ajax 코드를 전송한다고 하면, 이 시점에서 생성 함수를 실행해 XMLHttpRequest 객체를 생성하려 했지만 실패한다. 그러면 사용자에게 이 애플리케이션을 사용할 수 없다는 것을 경고로 알리게 된다 (많은 경우). 하지만 사용자는 이미 형식 상에서 데이터를 기입하느라 시간을 보냈다. 아마도 상당히 짜증을 내게 되면서 사용자는 결국엔 사이트로 관심을 기울이지 않게될 것이다.

XMLHttpRequest로 요청 전송하기

샌드박스
Ajax는 샌드박스 보안 모델이 포함되어 있다. 그 결과 Ajax 코드(특히 XMLHttpRequest 객체)는 실행 중인 동일한 도메인에만 요청을 생성한다.

서버 URL 설정
우선 결정할 것은 연결할 서버의 URL이다. URL은 Ajax에서만 있는 것은 아니다. 분명URL을 구성하는 방법에 대해 알아야 한다. 하지만 URL은 연결 설정 시 여전히 필수적인 것이다. 대부분의 애플리케이션에서 사용자가 다루는 형식에서 나온 데이터와 정적 데이터 세트를 결합해 URL을 구성한다.

function getCustomerInfo() {
   var phone = document.getElementById("phone").value;
   var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
   request.open("GET", url, true);
   request.onreadystatechange = updatePage;
   request.send(null);
}
escape() 메소드는 정확히 명백한 텍스트로 전송될 수 없는 문자를 변환하는데 사용된다. 예를 들어, 전화번호에서의 임의의 공간은 %20 문자로 바뀌며 이로 인해 URL과 같이 문자를 전송할 수 있게 된다.

요청 열기
XMLHttpRequest 객체 상의 open() 메소드를 사용해 요청을 구성한다.
request-type: 전송 요청 형태. GET/POST가 일반적인 값이고 HEAD 요청도 전송함.
url: 연결된 URL.
asynch: 비동기 요청을 설정할 경우 true값, 동기식 요청인 경우에는 false임. 이 매개변수는 옵션이고 기본값이 true값임.
username: 사용인증을 요구할 경우 사용자이름을 지정한다. 옵션 매개변수고 기본값이 없다
password: 사용인증을 요구할 경우 암호를 지정한다, 옵션 매개변수고 기본값이 없다.

비동기성에 대한 문제
동기식은 다시 말하면 클라이언트는 서버로부터의 응답이 올 때까지 대기한다. 버튼을 누르면 트리거된 요청이 응답되기 전까지는 애플리케이션을 사용할 수 없다.
비동기식 요청은 서버가 응답할 때까지 대기하지 않는다. 요청을 전송한 다음에는 애플리케이션을 계속 실행한다.

요청 전송
send() 메소드는 단 하나의 매개변수인 전송 컨텐트만 있으면 된다. 그 메소드에 대해 너무 깊게 생각하기 이전에 이미 URL 자체를 통해 데이터를 전송했음을 기억하라.

콜백 메소드 지정
비동기 식 XMLHttpRequest의 경우, 자바 메소드(예에 나온 getCustomerInfo())는 서버 상에서 대기하지 않는다. 따라서 서버에 XXMLHttpRequest객체에 의해 전송된 요청에 관한 처리과정을 완료할 경우 서버는 몇 가지 형태의 명령어를 포함해야 한다. 없다면 브라우저는 서버가 요청을 처리했는지 안했는지 어떤 상태인지 알 수 없다. 이런 상황에서 바로 onreadystatechange 속성이 작용한다. 이 속성으로 콜백 메소드를 지정한다. 웹 페이지 자체에서 벌어지는 현상에 관계없이 웹 페이지로 다시 호출할 때 서버에서 개시하기 때문에 콜백이라 부르는 것이다. 예를 들어, 사용자가 의자에 앉아 키보드를 사용하지 않는 동안 콜백 메소드를 호출하기도 한다. 하지만 사용자가 입력하고 마우스를 움직이고, 화면 이동시키고 버튼을 클릭하는 동안에도 콜백 메소드를 호출하기도 한다. 사용자가 하는 업무는 그다지 중요하지 않다. 이런 상황에서 비동시성이 작용한다.
특 히 onreadystatechange 속성이 결정된 코드 위치에 주의를 기울인다. 그 위치는 바로 send()가 호출되기 전의 위치다. 요청을 전송하기 전 onreadystatechange 속성을 설정해야 한다. 그래야만, 서버에서 요청 응답을 종료할 때 onreadystatechange 속성을 탐지하게 된다.

서버 응답 처리
요청을 만들면 사용자는 웹 형식에서 여유롭게 작업하며 (서버에서 요청을 처리하는 동안에는) 서버는 요청 처리과정을 완료한다. 서버는 onreadystatechange 속성에서 나타나며 호출방법을 결정한다.

function updatePage() {
  alert("Server is done!");
}
이렇게 하면 간단한 경고가 울리면서 서버가 종료될 때를 알려준다. 하지만 확인을 클릭한 경우에도 경고는 팝업을 연속한다. 브라우저에 ‘따라 웹 형식에서 경고 팝업을 중지할 때까지 경고가 두 번, 세 번, 심지어는 네 번까지 울린다.
그러면 무슨 일이 벌어지고 있는 것인가? 요청/응답 사이클의 중요 구성요소인 HTTP 준비상태에 대해 고려하지 않았다.

HTTP 준비 상태
서버에서 요청이 종료되면 XMLHttpRequest의 onreadystatechange 속성에서 호출되는 메소드를 탐지한다고 했으나 사실, HTTP 준비 상태가 변할 때마다 서버에서는 방금 전에 언급한 메소드를 호출한다.

HTTP 준비상태는 요청의 상태를 나타내며 주로 요청을 시작했는지, 요청에 응답했는지, 요청/응답 모델을 완성했는지 여부를 결정하는 데 활용된다. HTTP 준비상태는 서버에서 공급되는 모든 응답 텍스트/데이터를 읽어 들이는 데 안전한지 여부를 결정하는 데 도움이 되기도 한다. 여기서 Ajax 애플리케이션에서의 5가지 준비상태에 관해 알아야 한다.
0: 요청이 개시되지 않음.(open()을 호출하기 전)
1: 요청을 설정했지만 전송되지는 않았음.(send()를 호출하기 전)
2: 요청을 설정한 다음 처리 중(이 시점에서 일반적으로 응답에서 나온 컨텐트 헤더를 얻는다.)
3: 요청 처리 중; 종종 응답에서 부분적인 데이터를 사용할 수 있다. 하지만 서버는 자체 응답이 완료되지 않았다.
4: 응답 완료. 서버 응답을 얻은 다음 이를 활용한다.

거의 모든 크로스-브라우저 이슈에서도 그렇듯 예상치 못한 방식으로 이와 같은 준비 상태를 이용한다. 준비상태는 항상 0~1, 2, 3, 4로 단계적으로 이동한다고 예상할지도 모른다. 하지만 실지로는 그렇지 않다. 0/1상태를 보고하지 않고 곧바로 2로 건너뛰어 3,4까지 가는 브라우저도 있고 모든 상태를 보고하는 브라우저도 있다.

Ajax 프로그래밍의 경우, 직접 다뤄야 할 상태는 오로지 상태 4다. 이는 서버 응답이 완료되었고 응답 데이터를 점검, 사용하는 데 안전하다는 것을 의미한다.

function updatePage() {
  if (request.readyState == 4)
    alert("Server is done!");
}
이런 변환으로 서버가 정말로 그 과정을 종료했는지 확인한다. Ajax 코드의 이 버전을 실행한다. 그러면 한 번에 경고 메시지만을 얻어야 한다.

HTTP 상태 코드
하지만 여전히 문제는 상존한다. 그러면 서버가 요청에 응답하고 요청 처리과정을 완료했지만 에러를 보고한 경우는 어찌 되는가? Ajax, JSP, 정규 HTML 형식 또는 기타 형태의 코드로 서버측 코드를 호출 중인 경우에 서버측 코드를 관찰해야 한다는 점을 주목한다. 웹 세계에서는 HTTP 코드로 요청에서 발생할지도 모르는 여러 가지 상황을 다룬다.

예를 들어, URL에 관한 요청을 입력했지만, URL을 부정확하게 입력해 404 에러코드가 나와 페이지가 없어졌다고 해보자. 이 코드는 HTTP 요청을 상태로 수신하는 여러 상태 코드 가운데 하나에 지나지 않는다. 403, 401 코드는 둘 다 안전하거나 금지된 데이터 처리를 의미하는 것으로 역시 공통적이다. 각 경우에 있어 이런 코드들은 완전 응답에서 나오는 코드들이다. 즉, 서버는 요청을 수행하지만(HTTP 준비상태는 4임), 클라이언트가 예상한 데이터가 나오지 않을 수도 있다.

여기서 준비 상태에 덧붙여, HTTP 상태를 점검할 필요가 있다. 단순히 확인을 의미하는 상태코드 200을 탐색하는 중에 있다. 준비상태 4와 상태코드 200인 상태에서 서버 데이터를 처리할 준비가 되어 있고 그 데이터는 반드시 요청된 형태여야 한다.

function updatePage() {
  if (request.readyState == 4)
    if (request.status == 200)
      alert("Server is done!");
}
복잡성을 줄이고 더 강력한 에러 처리기능을 추가하려면 기타 상태코드에 관한 점검기능/두 가지 기능을 추가할지도 모른다.
function updatePage() {
  if (request.readyState == 4)
    if (request.status == 200)
      alert("Server is done!");
    else if (request.status == 404)
      alert("Request URL does not exist");
    else
      alert("Error: status code is " + request.status);
}

응답 텍스트 읽기
이제 요청을 준비상태를 통해 완전히 처리하고, 서버로 정상적인 확인 응답을 상태 코드를 통해 받았으므로 서버에서 재전송되는 데이터를 최종적으로 처리한다. 이 데이터는 XMLHttpRequest객체의 responseText 속성에 저장된다.

포맷/길이에 의한 responseText 속성의 텍스트 모양에 관한 상세사항은 이 장에서는 논하지 않기로 한다. 이렇게 되면 서버는 이 텍스트를 실지로 임의로 설정한다. 예를 들어, 한 스크립트로 콤마-분리 값 및 파이프-분리 값이 나오고 또 다른 파이프-분리 값은 텍스트의 긴 문자열로 나올 수도 있다. 이런 현상은 서버에 따라 다르게 된다.

이 글에서 사용된 예의 경우, 서버는 파이프 기호로 분리된 고객의 마지막 순서 및 주소가 나오게 된다.
function updatePage() {
  if (request.readyState == 4) {
    if (request.status == 200) {
      var response = request.responseText.split("|");
      document.getElementById("order").value = response[0];
      document.getElementById("address").innerHTML = response[1].replace(/\n/g, "<br>");
    } else
      alert("status is " + request.status);
  }
}
XMLHttpRequest 객체의 중요한 속성 중 하나인 responseXML 속성에 대해 언급한다. 이 속성은 서버가 XML과의 응답을 선택한 경우, XML 응답을 포함한다. XML 응답 처리는 평범한 텍스트 처리과정과 상당히 다르며, 문장분석 및 문서 객체 모델(DOM)을 포함한다. 많은 단순 Ajax 애플리케이션의 경우, responseText만 있으면 된다.

출처 : http://www.ibm.com/developerworks/kr/series/web/index.html
아래 내용은 위 출처의 기사의 일부를 복사 후 편집/수정한 것입니다.
단순히 개인적으로 알고자하는 내용만을 남긴 것이니, 자세한 정보는 위의 출처를 참조하세요.

XMLHttpRequest 객체

Ajax는 근본적으로 자바 스크립트 기술 및 웹 양식 및 서버 간의 XMLHttpRequest 객체를 결합한다. 사용자가 웹 양식을 기입할 때 데이터는 직접 서버 스크립트에 전송되지 않고 자바 스크립트 코드에 전달된다. 대신 자바 스크립트 코드는 양식 데이터를 포착해 Request를 서버에 전송한다. 이 과정이 일어나는 동안, 사용자 스크린 상의 양식은 순식간에 나타나거나 깜빡이거나 사라지거나 정지하지 않는다. 즉 자바 스크립트 코드는 몰래 Request를 전송하며 사용자는 Request가 만들어졌는지도 알지 못한다. 게다가 Request를 비동기적으로 전송하기 때문에 더 좋은 상황이 된다. 이는 자바 스크립트에서 서버 응답을 그냥 대기하지 않는다는 것을 의미한다. 따라서, 사용자는 데이터를 계속 기입하고 화면이동하고 애플리케이션을 사용한다. 그런 다음 서버는 자바 스크립트 코드(웹 양식에 대해 아직도 대기 중임)에 데이터를 다시 전송한다. 자바 스크립트 코드에서는 데이터와의 상호기능을 결정하며 연속적으로 양식 필드를 업데이트 하면서 애플리케이션에 즉각적인 응답을 준다. 결국 사용자는 양식을 제출/재생하는 작업 없이 새로운 데이터를 얻게 된다. 자바 스크립트 코드는 데이터를 얻고 계산도 수행하며 또 다른 Request를 전송하며 이런 모든 과정은 사용자 개입 없이도 된다! 이것이 바로 XMLHttpRequest 객체의 장점이다. XMLHttpRequest 객체는 서버와 같이 커뮤니케이션을 주고받고 사용자는 그 과정에서 벌어지는 과정을 알지 못한다.

일련의 수행 순서

1. 자바 스크립트 코드로 HTML 양식에서 데이터를 꺼내 이를 XMLHttpRequest 객체를 이용해서 서버에 전송
2. 서버에서 연산을 거친 결과값을 역시 XMLHttpRequest 객체를 이용해서 받아옴(XML/JSON 등으로)
3. 받아온 결과값을 필드 값 설정이나 연속적인 이미지 교체작업 등의 업데이트 작업을 수행

위의 모든 건 자바 스크립트에서 가능. 데이타는 DOM 등으로 처리.

XMLHttpRequest 객체 생성

다중 브라우저 방식으로 XMLHttpRequest 객체 생성하기
/* Create a new XMLHttpRequest object to talk to the Web server */
var xmlHttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e2) {
    xmlHttp = false;
  }
}
@end @*/

if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
  xmlHttp = new XMLHttpRequest();
}

1.  변수 xmlHttp를 생성해 앞으로 생성할 XMLHttpRequest 객체를 참조한다.
2. Microsoft 브라우저에서의 객체를 시도, 생성한다.
     * Msxml2.XMLHTTP 객체를 사용해 XMLHttpRequest 객체를 시도, 생성한다.
     * 과정이 실패할 경우, Microsoft.XMLHTTP 객체를 사용해 XMLHttpRequest 객체를 시도, 생성한다.
3. xmlHttp가 아직도 설정되지 않은 경우 비-Microsoft 방식으로 XMLHttpRequest 객체를 생성한다.

Ajax가 포함된 Request 만들기 & 서버 응답 취급하기
 function callServer() {
  // Get the city and state from the web form
  // 자바스크립트로 폼에서 데이터를 가져온다
  var city = document.getElementById("city").value;
  var state = document.getElementById("state").value;
  // Only go on if there are values for both fields
  if ((city == null) || (city == "")) return;
  if ((state == null) || (state == "")) return;

  // Build the URL to connect to
  // 데이터를 보낼 주소를 설정
  var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state);

  // Open a connection to the server
  // 서버로의 connection 열기 - 데이터 넘기는 방식(GET/POST), 주소, 연결방식(true:비동기/false:동기)
  // 비동기 연결이기 때문에 사용자는 서버의 응답을 기다리지 않고 다른 작업이 가능
  xmlHttp.open("GET", url, true);

  // Setup a function for the server to run when it's done
  // XMLHttpRequest 객체의 상태변경 시마다 호출할 함수. 즉 서버로부터의 응답이 있을 때마다 호출할 함수
  xmlHttp.onreadystatechange = updatePage;

  // Send the request
  // null - request에 추가해 보낼 것이 없다.
  xmlHttp.send(null);
}

// xmlHttp.onreadystatechange = updatePage;에서 설정한 상태변경 시마다 호출되는 함수
// 상태가 바뀔 때마다 호출되지만, 상태에 대한 조건문을 이용해서 전부 OK일 경우에만 결과에 대해 처리한다.
function updatePage() {
  if (xmlHttp.readyState == 4) { // Loaded
//    if(xmlHttp.status == 200) { // OK
    var response = xmlHttp.responseText;
    document.getElementById("zipCode").value = response;
//    }
  }
}

웹 페이지에서 Ajax 프로세스 시작
 <form>
 <p>City: <input type="text" name="city" id="city" size="25" onChange="callServer();" /></p>
 <p>State: <input type="text" name="state" id="state" size="25" onChange="callServer();" /></p>
 <p>Zip Code: <input type="text" name="zipCode" id="zipCode" size="5" /></p>
</form>


[펌] Ajax, jQuery 관련 강의

프로그래밍/Web 2009. 2. 6. 13:23 Posted by galad
직접 WTP 플러그인을 받아서 복사해 넣었더니 안되더니만,
이클립스 가니메데 버전에서 실행 후,
Help -> Software Updates -> Available Software -> Web and Java EE Development를 전부 업뎃했더니 된다.

아마 가니메데를 코어버전?(클래식버전? - SE용?)을 받아서 그랬던 듯?
EE용으로 받았더라면 문제없었을라나...

'프로그래밍 > Library' 카테고리의 다른 글

[MD5] MD5 암호화  (0) 2009.03.13
[BASE64] BASE64 인코딩  (0) 2009.02.27
[Cognos] 기본개념  (0) 2009.01.29
[EXCEL] 셀 범위로 드롭다운 목록 만들기  (0) 2009.01.29
[log4j] 사용례  (0) 2009.01.08

[Cognos] 기본개념

프로그래밍/Library 2009. 1. 29. 17:03 Posted by galad
Query Explorer에서 DB의 정보를 가져오는 객체들을 만든 다음,
Page Explorer에서 Query Explorer가 관리하는 객체들을 가지고 원하는 형태로 리포트를 작성한다.
그밖의 리포트 생성용 조건은 Prompt Page에서, 특정 조건에 따라 리포트 형태변화 등은 Condition을 이용해서.
http://office.microsoft.com/ko-kr/excel/HP100725991042.aspx

1. 드롭다운 목록용 리스트를 한 열/행에 빈 칸 없이 작성
2. 드롭다운에 사용할 셀 선택 -> 메뉴의 데이타 -> 데이타 유효성 -> 설정 탭 -> 목록 선택 후 작성해 논 리스트를 선택

더 자세한 건 위의 링크 참조

[펌] MSSQL 함수모음

프로그래밍/DB 2009. 1. 14. 15:25 Posted by galad
http://cafe.naver.com/q69/37319

숫자함수 

ABS 
ABS함수는 절대값을 나타낸다. 
형식: ABS(숫자값) 

POWER 
POWER함수는 제곱근을 표현해 준다. 
형식: POWER(숫자값, 승수값) 

SQRT 
SQRT는 루트값을 표현해준다. 
형식: SQRT(숫자값) 

RAND 
RAND는 0 에서 1사이의 난수를 발생시킨다. 
형식: RAND(초기값) 

ROUND 
ROUND는 반올림 함수이다. 
형식: ROUND(숫자, 자릿수) 
ROUND는 자릿수만 조심하면 된다. 2번째 결과는 8을 반올림하여 그 앞의 9에 1이 더해진것이고 3번째 결과는 9가 반올림된것이다. 

CEILING, FLOOR 
CEILING은 소수점 첫번째 값을 기준으로 올림을 하고 FLOOR는 소수점 첫번째 값을 기준으로 내림을 한다. 
형식: CEILING(숫자) ... FLOOR도 동일 
CEILING과 FLOOR는 소수 첫번째값이 5 이상이든 이하든간에 무조건 올림, 내림을 수행한다. 

---------------------------------------------------------- 
문자함수 

LEFT, RIGHT 
LEFT는 지정해준 자릿수만큼 왼쪽에서부터 문자열을 반환한다. 
당연히 RIGHT는 반대이다. 
형식 : LEFT(문자, 자릿수) 

LTRIM, RTRIM 
LTRIM은 문자열의 왼쪽 공백을 제거한다. 역시 RTRIM은 반대일 경우 사용된다. 
형식: LTRIM(문자) 

LEN 
LEN함수는 문자열에서 문자의 갯수를 추출한다. 
형식: LEN(문자) 
Len함수는 문자 뒤쪽의 공백은 문자로 계산하지 않는다. 

UPPER, LOWER 
UPPER는 소문자를 대문자로, LOWER는 대문자를 소문자로 바꾼다. 
형식: UPPER(문자) 

REVERSE 
REVERSE는 문자열을 반대로 표시한다. 
형식: REVERSE(문자열) 

REPLACE 
REPLACE함수는 지정한 문자열을 다른 문자열로 바꾸어준다. 
형식: REPLACE(문자, 타겟문자, 바꿀문자) 

REPLICATE 
REPLICATE함수는 문자열을 지정된 횟수만큼 반복한다. 
형식: REPLICATE(문자, 횟수) 

STUFF 
STUFF함수는 문자열에서 특정 시작위치에서 지정된 길이만큼 문자를 바꾸어준다. 
형식: STUFF(문자, 시작위치, 길이, 바꿀문자) 

SUBSTRING 
SUBSTRING은 STUFF와 비슷하지만 문자를 바꾸는 것이 아니라 그 문자를 반환한다. 
형식: SUBSTRING(문자, 시작위치, 길이) 

PATINDEX, CHARINDEX 
PATINDEX와 CHARINDEX는 문자열에서 지정한 패턴이 시작되는 위치를 뽑아준다. 
형식: PATINDEX(문자패턴, 문자) - 문자패턴은 Like 사용과 같다. 
형식: CHARINDEX(문자패턴, 문자) - 문자패턴은 일반형식을 사용한다. 

SPACE 
SPACE함수는 지정한 수 만큼 공백을 추가한다. 
형식: SPACE(횟수) 

시간 및 날짜 함수 
GETDATE() 
GETDATE()는 현재 시간을 표시해준다. 
DATEADD 
DATEADD함수는 날자에 지정한 만큼을 더한다. 
형식: DATEADD(날자형식, 더할 값, 날자) 

DATEDIFF 
DATEDIFF함수는 두 날자사이의 날자형식에 지정된 부분을 돌려준다. 
형식: DATEDIFF(날자형식, 시작 날자, 끝 날자) 

DATENAME 
DATENAME함수는 지정한 날자의 날자형식의 이름을 돌려준다. 
형식: DATENAME(날자형식, 날자) 

DATEPART 
DATEPART함수는 날자에서 지정한 날자형식부분만 추출해줍니다. 
형식: DATEPART(날자형식, 날자) 
주일은 일요일부터 1로 시작해서 토요일날 7로 끝나게 된다. 

--------------------------------------------------------------------- 
NULL 함수 
ISNULL 
ISNULL은 NULL값을 대체값으로 바꾼다. 
형식: ISNULL(NULL값, 대체값) 

NULLIF 
NULLIF함수는 두개의 표현식을 비교하여 같으면 NULL을 반환한다. 
형식: NULLIF(표현식1, 표현식2) 

COALESCE 
COALESCE함수는 NULL이 아닌 첫번째 표현식이 반환된다. 
형식: COALESCE(표현식) 

GETANSINULL 
GETANSINULL은 데이터베이스의 기본 NULL 상태를 표시해준다. 
형식: GETANSINULL(데이터베이스 이름) 


------------------------------------------------------ 
AVG, MAX, MIN, SUM, COUNT 

MAX 
최대값을 구한다. 

MIN 
최소값을 구한다. 

SUM 
값갑의 합을 구한다. 

AVG 
평균을 구한다. 

COUNT 
값의 갯수를 구한다.

[펌] MSSQL 날짜 함수

프로그래밍/DB 2009. 1. 14. 15:21 Posted by galad
http://flashcafe.org/sqlserver_study/4277/page/3






함수(날짜열)
DATE구분 구분약자 DATE구분 구분약자
year yy week wk
quarter qq hour hh
month mm minute mi
day of year dy second ss
day dd millisecond ms

항목 내용
GETDATE() 시스템에서 제공하는 날짜와 시간 값
산술연산 -- date + NUMBER
-- date - NUMBER


--날짜는 계산할 수 있다.
--getdate()
select getdate()'현재날짜 & 시간'
--getdate() -1, +1
select getdate() - 1'어제 이 시간',
   getdate() + 1'내일 이 시간'
--오늘부터 100일 전의 날짜를 검색!
select getdate() - 100
--회원테이블의 생일과 1200일째 되는 날을 검색! (Alias는 회원명, 생일, 12000일째)
select mem_name "회원명", mem_bir "생일",
   getdate() + 1200 "1200일째"
 from member

--**********************************************************************
--   DATEADD 함수(날짜열)
--**********************************************************************
--DATEADD (Part,n,date)/Part부분에 n만큼 더한 date
--      (DATE구분별로 모두 적용)   


select getdate() '현재날짜 & 시간',
   dateadd(year, 1, getdate()) '1년뒤'
--
select getdate() '현재날짜 & 시간',
   dateadd(mm,-1, getdate()) '한달전'
--
select getdate()'현재날짜 & 시간',
   dateadd(dd, -50, getdate()) '50일전'
--
select getdate()'현재날짜 & 시간',
   dateadd(hour, 7, getdate()) '7시간 뒤'
--
select dateadd(yy, 1, '19990228') "1년후",
   dateadd(yy, 2, '19990228') "2년후",
   dateadd(yy, 3, '19990228') "3년후"
--
select dateadd(mm, 12, '19000228') "1년후",
   dateadd(mm, 24, '19000228') "2년후",
   dateadd(mm, 36, '19000228') "3년후"
--오늘부터 6개월 전의 날짜를 검색!
select dateadd(mm, -6, getdate())"6개월전의 날짜"
--회원테이블에서 구길동회원의 생일과 12000일째 되는 날을 검색!
--(DATEADD사용) (Alias는 회원명, 생일, 12000일째)
--1.
select mem_name"회원명", mem_bir"생일", dateadd(dd,1200,mem_bir)"1200일째" from member
   where mem_name like '구길동%'
--2.
select mem_name"회원명", mem_bir"생일", dateadd(dd,1200,mem_bir)"1200일째" from member
   where mem_name like '구길동'
--3.
select mem_name"회원명", mem_bir"생일", dateadd(dd,1200,mem_bir)"1200일째" from member
   where mem_name='구길동'

--********************************************************************
--      YEAR,MONTH,DAY,DATEDIFF함수(날짜열)
--********************************************************************
--year, month, day 해당일의 년월일 값을 돌려준다.
select year(getdate())'year',
   month(getdate())'month',
   day(getdate())'day'
--datediff(part,date1,date2)/두 날짜 사이의 DATE구분 사이 값을 계산함.
--   (part, date1, date2)
select datediff(dd,'1999/02/15','2000/02/15')'day',
   datediff(mm,'1999/02/15','2000/02/15')'month',
   datediff(yy,'1999/02/15','2000/02/15')'year'
--
select datediff(dd,'1999/11/06','2000/02/15')'day',
   datediff(mm,'1999/11/06','2000/02/15')'month',
   datediff(yy,'1999/11/06','2000/02/15')'year'
--회원테이블의 생일과 오늘의 일수 차이를 검색! (Alias는 회원명, 생일, 오늘, 태어난지?)
select mem_name"회원명", mem_bir"생일",
   getdate()"오늘",
   datediff(dd,mem_bir,getdate())"태어난지?"
 from member
--본인의 생년월일과 오늘의 일수 차이를 비교 검색!
select datediff(dd,'1972/08/14',getdate()) "차이는"

--*******************************************************************
--      Datename, Datepart함수(날짜열)
--*******************************************************************
--datename(part,date)/date에서 datepart부분의 ASCII값(구분문자)
--datepart(part,date)/date에서 datepart부분의 정수값(구분숫자)
select convert(char,getdate()), '<==현재날짜'
select datename(yy,getdate()),datepart(yy,getdate()),'<==년도'
select datename(qq,getdate()),datepart(qq,getdate()),'<==분기'
select datename(mm,getdate()),datepart(mm,getdate()),'<==월'
select datename(dy,getdate()),datepart(dy,getdate()),'<==일수'
select datename(dd,getdate()),datepart(dd,getdate()),'<==해당일'
select datename(wk,getdate()),datepart(wk,getdate()),'<==주수'
select datename(dw,getdate()),datepart(dw,getdate()),'<==요일'
select datename(hh,getdate()),datepart(hh,getdate()),'<==시간'
--회원테이블에서 구길동회원의 생일의 DATENAME 과 DATEPART를 검색!
--(Alias 는 회원명, 생일, 기타 上 同)
select mem_name"회원명", mem_bir"생일",
   datename(dw,mem_bir)'기타上同',
   datepart(dw,mem_bir)'기타上同'
 from member
   where mem_name='구길동'
/* 월 (2002년 2월)만 입력받아 해당월의 시작일과 종료일을 검색!
Alias는 해당월, 시작일, 종료일) */
--******************** 1. 2002-02-01의 1달 후 -1....
select '200년02월' 해당월, '200-02-01' 시작일,
   dateadd(mm,1,'2000-02-01')-1 "종료일"
--******************** 2. 2002-03-01의 1일 전....
select '200년02월' 해당월, '200-02-01' "시작일",
   dateadd(dd,-1,'2000-03-01') "종료일"

--*******************************************************************
--      함수(Conversion)
--*******************************************************************
--cast, convert : 문자로 치환/number와 date를 문자로 치환.
--   /간단한 형 변환(CAST)
--   /날짜를 문자로 변환 시 여러가지 형식이 가능하므로 주로 사용하는 함수는(CONVERT)이다.
select convert(char, 123456789) result1,
   cast(123456789 as char) result2
--
select convert(varchar,456789) result1,
   cast(456789 as varchar) result2,
   str(456789, 10) result3
/* 숫자를 바꾸는 convert함수를 썼는데 2번째줄의 경우는 '300567'이라는 6섯자를
'char(4)' 4자로 바꾸라는 것: 이것은 말이 안되므로 * 표시가 프린트됨!(주의 사항) */
select convert(char(7),300567) result1,
   convert(char(4),300567) result2
--
select convert(char,getdate(),0) result1,
cast(getdate() as char) result2
--
select convert(CHAR, GETDATE(), 109) RESULT
select convert(CHAR, GETDATE(), 111) RESUlT
select convert(CHAR(10), GETDATE(), 121) RESULT
select convert(CHAR, GETDATE(), 114) RESULT

--
select convert(char, getdate(),0)
select convert(char, getdate(),1)
select convert(char, getdate(),2)
select convert(char, getdate(),3)
select convert(char, getdate(),4)
select convert(char, getdate(),5)
select convert(char, getdate(),6)
select convert(char, getdate(),7)
select convert(char, getdate(),8)
select convert(char, getdate(),9)
select convert(char, getdate(),10)
select convert(char, getdate(),11)
select convert(char, getdate(),12)
select convert(char, getdate(),13)
select convert(char, getdate(),14)
--다음 아래는 ERR...
select convert(char, getdate(),15)
select convert(char, getdate(),16)
select convert(char, getdate(),17)
select convert(char, getdate(),18)
select convert(char, getdate(),19)
--여기까지 ERR...
select convert(char, getdate(),20)
select convert(char, getdate(),21)
select convert(char, getdate(),22)
select convert(char, getdate(),23)
select convert(char, getdate(),24)
select convert(char, getdate(),25)
--여기서 또 아래는 ERR...
select convert(char, getdate(),26)
select convert(char, getdate(),27)
select convert(char, getdate(),28)
select convert(char, getdate(),29)
select convert(char, getdate(),30)
select convert(char, getdate(),31)
select convert(char, getdate(),32)
select convert(char, getdate(),33)
select convert(char, getdate(),34)
-- .
-- .
-- .
select convert(char, getdate(),99)
--99까지 ERR
--100단위로 위와 똑같은 숫자안에 포함되어 쓰인다.
--120과 121번의 경우는 우리나라에서 많이 쓴다. 그냥 21번을 쓰기도 한다.
select convert(char, getdate(),120)
select convert(char, getdate(),121)
/* 위에서 일반숫자형을 문자로 변환할 때 변환되어지려는 값과 변환하려는 값의
자릿숫자값이 다르면 에러가 났었지만, 날짜형은 그 자릿수만큼 잘라서 출력한다! */
--다음은 그 예이다.
--1. 날짜형 변환의 예)
select convert(char(10), getdate(),121)
--2. 숫자형 변환의 예)
select convert(char(7),300567) result1,
convert(char(4),300567) result2
--3. 문자형를 자르기 예)
select convert(char(10), 'abcdefghijklmnopqrstuvwxyz')

--122~에서부턴 형식이 맞지 않는다 ERR
select convert(char, getdate(),122)
select convert(char, getdate(),123)
select convert(char, getdate(),124)
select convert(char, getdate(),125)
   :
   :

--상품테이블에서 상품코드와 상품명을 연결하여 30자리로 치환하여 검색!
--Alias는 상품코드, 상품명, 치환상품명)
select prod_id 상품코드, prod_name 상품명,
   convert(char(30), prod_id + prod_name) 치환상품명
  from prod

--***********************************************
--      conversion
--***********************************************
--예제1) // datetime, smalldatetime, decimalzero, decimalpoint, numericzero, numericpoint

select convert(char(8), getdate(),112) result
--
select convert(datetime, '2001-01-01') DATETIME
--
select smalldatetime = convert(smalldatetime,'2001-01-01')
--
select decimalzero = convert(decimal(15),12345678912345)
--
select decimalpoint = convert(decimal(17,2),123456789012345.11)
--
select numericzero = convert(numeric,123456789012345)
select numericpoint = convert(numeric(17,2),123456789012345.11)

--예제2) // float, int, smallint, tinyint, money

select convert(float,123456789012345) float
--
select convert(float,10/3.0) float
--
select convert(int,1234567890) int
--
select convert(smallint,12345) smallint
--
select convert(tinyint, 123) tinyint
--
select convert(money,123456789012345) money

--***********************************************************************
--함수(Conversion) : 숫자로 치환
--***********************************************************************
--   숫자로 치환 // 모양만 수치인 문자를 NUMBER로 치환
--   /모양만 수치라면 연산에는 영향이 없다.
select convert(numeric,'123456.9') result1,
   cast('123456.9' as numeric) result2
--
select convert(numeric(10,2),'123456.9') result1,
   cast('123456.9' as numeric(10,2)) result2
--
select convert(float,'123456.9') result1,
   cast('123456.9' as float) result2
--
select convert(decimal,'123456.9') result1,
   cast('123456.9' as decimal) result2
--*****************************************************
/* 회원테이블에서 이쁜이 회원의 회원ID(b001) 2~4문자열을 숫자형으로 치환한 후 10을 더하여
 새로운 회원ID(b011)로 조합(Alias는 회원ID, 조합회원ID) */





    회원ID     조합회원ID
   -------   ------------
     b001          b011
   (1 row(s) affected)
--1. 방법1
select mem_id "회원ID",
   left(mem_id,1) + right(convert(char(4),right(mem_id,3) + 1010),3) "조합회원ID"
   from member
   where mem_name = '이쁜이'
--2. 방법2
select mem_id "회원ID",
   left(mem_id,1) + right(convert(char(4),substring(mem_id,2,4)+1010),3) "조합회원ID"
   from member
   where mem_name = '이쁜이'
--***********************************************************************
--      함수(conversion) : 날짜로 치환
--***********************************************************************
--날짜로 치환/모양만 날짜형인 문자를 DATE로 치환
select'19990101'result1,'1999-01-01'result2,
   '1999-01-01 00:00:00.000'result3
--
select convert(datetime,'20201025',112)" result1",
   convert(datetime,'20201025')" result2",
   convert(datetime,'2020-10-25 10:15:20.000') " result3",
   cast('2020-10-25 10:15:20.000' as datetime) " result4"
--
--회원테이블에서 주민등록번호1을 날짜로 치환한 후 검색!
--(Alias는 회원명, 주민등록번호1, 치환날짜)
select mem_name 회원명, mem_regno1 주민등록번호1,
   convert(datetime,'19'+mem_regno1) 치환날짜
   from member
--1900년대 사람들만 있다고 가정했을 경우 19를 더해서 밀레니엄버그를 없앨 수 가 있다.
--회원테이블에서 주민등록번호1을 날짜로 치환한 후 500일을 더한 날짜를 검색!
--(Alias는 회원명, 주민등록번호1, 치환날짜)
select mem_name 회원명, mem_regno1 주민등록번호1,
   convert(datetime,'19'+mem_regno1) + 500 치환날짜
   from member
--회원테이블에서 주민등록번호1을 날짜로 치환한 후 '1974-01-01'부터 '1975-12-31'사이의 날짜를 검색!
--(Alias 회원명, 주민등록번호1, 치환날짜)
select mem_name 회원명, mem_regno1 주민등록번호1,
   convert(datetime,'19'+mem_regno1) 치환날짜
   from member
   where convert(datetime,'19'+mem_regno1)between'1974-01-01'and'1975-12-31'
--회원테이블에서 생일을 문자로 치환한 후 LIKE '1975%'의 조건을 사용하여 해당회원을 검색!
--Alias는 회원명, 생일)
select mem_name 회원명, mem_bir 생일
   from member
   where convert(char, mem_bir, 121) like '1975%'




--******************************************************************
--      함수(NULL)
--******************************************************************
/* ## 데이터를 처리할 때 NULL값의 사용은 최대한 줄여야 하지만 사용해야 할 경우가 있다.
## 학생에 대한 정보를 입력할 때 '전화번호' 속성은 전화번호가 없는 학생이 있을 수가 있다 .이런 경우에는 NULL값을 사용한다.
## NULL값은 0.1과 같은 특정한 값이 아니고 아무 것도 없는 것을 뜻한다.
## SQL에서 NULL값을 허용하지 않는 속성에 대해 NULL값으로 수정하려 한다면 에러가 발생한다. */

--null값을 찾을 때에는 is null
select buyer_name buyer_charger
   from buyer
   where buyer_charger is null
--null인 값을 찾을 때 '='은 성립되지 않는다.
select buyer_name buyer_charger
   from buyer
   where buyer_charger=null
--
select buyer_name buyer_charger
   from buyer
   where buyer_charger =''
--null값이 아닌 값을 찾으려 할 때 is not null
select buyer_name buyer_charger
   from buyer
   where buyer_charger is not null
--ISNULL(c,d) / c가 NULL값이면 d값으로 치환
--null값일 때 '이름없다' 로 출력!
select buyer_name, buyer_charger, isnull(buyer_charger, '이름없다')
   from buyer
--null에다 100을 더하면 null이다.
select null + 100
--
select isnull(null,0)+100
--
select mem_name, mem_mileage, mem_mileage+100
   from member
--
select mem_name, mem_mileage, mem_mileage + 100
   from member
   where mem_name like '[바-•

[펌] date 타입 변환 함수

프로그래밍/DB 2009. 1. 14. 15:12 Posted by galad
from http://lturn.net/gnuboard4/bbs/board.php?bo_table=mssql&wr_id=11

복사 http://blog.naver.com/promised23/10026740192



Standard Date Formats
Date Format Standard SQL Statement Sample Output
Mon DD YYYY 1
HH:MIAM (or PM)
Default SELECT CONVERT(VARCHAR(20), GETDATE(), 100) Jan 1 2005 1:29PM 1
MM/DD/YY USA SELECT CONVERT(VARCHAR(8), GETDATE(), 1) AS [MM/DD/YY] 11/23/98
MM/DD/YYYY USA SELECT CONVERT(VARCHAR(10), GETDATE(), 101) AS [MM/DD/YYYY] 11/23/1998
YY.MM.DD ANSI SELECT CONVERT(VARCHAR(8), GETDATE(), 2) AS [YY.MM.DD] 72.01.01
YYYY.MM.DD ANSI SELECT CONVERT(VARCHAR(10), GETDATE(), 102) AS [YYYY.MM.DD] 1972.01.01
DD/MM/YY British/French SELECT CONVERT(VARCHAR(8), GETDATE(), 3) AS [DD/MM/YY] 19/02/72
DD/MM/YYYY British/French SELECT CONVERT(VARCHAR(10), GETDATE(), 103) AS [DD/MM/YYYY] 19/02/1972
DD.MM.YY German SELECT CONVERT(VARCHAR(8), GETDATE(), 4) AS [DD.MM.YY] 25.12.05
DD.MM.YYYY German SELECT CONVERT(VARCHAR(10), GETDATE(), 104) AS [DD.MM.YYYY] 25.12.2005
DD-MM-YY Italian SELECT CONVERT(VARCHAR(8), GETDATE(), 5) AS [DD-MM-YY] 24-01-98
DD-MM-YYYY Italian SELECT CONVERT(VARCHAR(10), GETDATE(), 105) AS [DD-MM-YYYY] 24-01-1998
DD Mon YY 1 - SELECT CONVERT(VARCHAR(9), GETDATE(), 6) AS [DD MON YY] 04 Jul 06 1
DD Mon YYYY 1 - SELECT CONVERT(VARCHAR(11), GETDATE(), 106) AS [DD MON YYYY] 04 Jul 2006 1
Mon DD, YY 1 - SELECT CONVERT(VARCHAR(10), GETDATE(), 7) AS [Mon DD, YY] Jan 24, 98 1
Mon DD, YYYY 1 - SELECT CONVERT(VARCHAR(12), GETDATE(), 107) AS [Mon DD, YYYY] Jan 24, 1998 1
HH:MM:SS - SELECT CONVERT(VARCHAR(8), GETDATE(), 108) 03:24:53
Mon DD YYYY HH:MI:SS:MMMAM (or PM) 1 Default +
milliseconds
SELECT CONVERT(VARCHAR(26), GETDATE(), 109) Apr 28 2006 12:32:29:253PM 1
MM-DD-YY USA SELECT CONVERT(VARCHAR(8), GETDATE(), 10) AS [MM-DD-YY] 01-01-06
MM-DD-YYYY USA SELECT CONVERT(VARCHAR(10), GETDATE(), 110) AS [MM-DD-YYYY] 01-01-2006
YY/MM/DD - SELECT CONVERT(VARCHAR(8), GETDATE(), 11) AS [YY/MM/DD] 98/11/23
YYYY/MM/DD - SELECT CONVERT(VARCHAR(10), GETDATE(), 111) AS [YYYY/MM/DD] 1998/11/23
YYMMDD ISO SELECT CONVERT(VARCHAR(6), GETDATE(), 12) AS [YYMMDD] 980124
YYYYMMDD ISO SELECT CONVERT(VARCHAR(8), GETDATE(), 112) AS [YYYYMMDD] 19980124
DD Mon YYYY HH:MM:SS:MMM(24h) 1 Europe default + milliseconds SELECT CONVERT(VARCHAR(24), GETDATE(), 113) 28 Apr 2006 00:34:55:190 1
HH:MI:SS:MMM(24H) - SELECT CONVERT(VARCHAR(12), GETDATE(), 114) AS [HH:MI:SS:MMM(24H)] 11:34:23:013
YYYY-MM-DD HH:MI:SS(24h) ODBC Canonical SELECT CONVERT(VARCHAR(19), GETDATE(), 120) 1972-01-01 13:42:24
YYYY-MM-DD HH:MI:SS.MMM(24h) ODBC Canonical
(with milliseconds)
SELECT CONVERT(VARCHAR(23), GETDATE(), 121) 1972-02-19 06:35:24.489
YYYY-MM-DDTHH:MM:SS:MMM ISO8601 SELECT CONVERT(VARCHAR(23), GETDATE(), 126) 1998-11-23T11:25:43:250
DD Mon YYYY HH:MI:SS:MMMAM 1 Kuwaiti SELECT CONVERT(VARCHAR(26), GETDATE(), 130) 28 Apr 2006 12:39:32:429AM 1
DD/MM/YYYY HH:MI:SS:MMMAM Kuwaiti SELECT CONVERT(VARCHAR(25), GETDATE(), 131) 28/04/2006 12:39:32:429AM
CONVERT function.
Extended Date Formats
Date Format SQL Statement Sample Output
YY-MM-DD SELECT SUBSTRING(CONVERT(VARCHAR(10), GETDATE(), 120), 3, 8) AS [YY-MM-DD] 99-01-24
YYYY-MM-DD SELECT CONVERT(VARCHAR(10), GETDATE(), 120) AS [YYYY-MM-DD] 1999-01-24
MM/YY SELECT RIGHT(CONVERT(VARCHAR(8), GETDATE(), 3), 5) AS [MM/YY]
SELECT SUBSTRING(CONVERT(VARCHAR(8), GETDATE(), 3), 4, 5) AS [MM/YY]
08/99
MM/YYYY SELECT RIGHT(CONVERT(VARCHAR(10), GETDATE(), 103), 7) AS [MM/YYYY] 12/2005
YY/MM SELECT CONVERT(VARCHAR(5), GETDATE(), 11) AS [YY/MM] 99/08
YYYY/MM SELECT CONVERT(VARCHAR(7), GETDATE(), 111) AS [YYYY/MM] 2005/12
Month DD, YYYY 1 SELECT DATENAME(MM, GETDATE()) + RIGHT(CONVERT(VARCHAR(12), GETDATE(), 107), 9) AS [Month DD, YYYY] July 04, 2006 1
Mon YYYY 1 SELECT SUBSTRING(CONVERT(VARCHAR(11), GETDATE(), 113), 4, 8) AS [Mon YYYY] Apr 2006 1
Month YYYY 1 SELECT DATENAME(MM, GETDATE()) + ' ' + CAST(YEAR(GETDATE()) AS VARCHAR(4)) AS [Month YYYY] February 2006 1
DD Month 1 SELECT CAST(DAY(GETDATE()) AS VARCHAR(2)) + ' ' + DATENAME(MM, GETDATE()) AS [DD Month] 11 September 1
Month DD 1 SELECT DATENAME(MM, GETDATE()) + ' ' + CAST(DAY(GETDATE()) AS VARCHAR(2)) AS [Month DD] September 11 1
DD Month YY 1 SELECT CAST(DAY(GETDATE()) AS VARCHAR(2)) + ' ' + DATENAME(MM, GETDATE()) + ' ' + RIGHT(CAST(YEAR(GETDATE()) AS VARCHAR(4)), 2) AS [DD Month YY] 19 February 72 1
DD Month YYYY 1 SELECT CAST(DAY(GETDATE()) AS VARCHAR(2)) + ' ' + DATENAME(MM, GETDATE()) + ' ' + CAST(YEAR(GETDATE()) AS VARCHAR(4)) AS [DD Month YYYY] 11 September 2002 1
MM-YY SELECT RIGHT(CONVERT(VARCHAR(8), GETDATE(), 5), 5) AS [MM-YY]
SELECT SUBSTRING(CONVERT(VARCHAR(8), GETDATE(), 5), 4, 5) AS [MM-YY]
12/92
MM-YYYY SELECT RIGHT(CONVERT(VARCHAR(10), GETDATE(), 105), 7) AS [MM-YYYY] 05-2006
YY-MM SELECT RIGHT(CONVERT(VARCHAR(7), GETDATE(), 120), 5) AS [YY-MM]
SELECT SUBSTRING(CONVERT(VARCHAR(10), GETDATE(), 120), 3, 5) AS [YY-MM]
92/12
YYYY-MM SELECT CONVERT(VARCHAR(7), GETDATE(), 120) AS [YYYY-MM] 2006-05
MMDDYY SELECT REPLACE(CONVERT(VARCHAR(10), GETDATE(), 1), '/', '') AS [MMDDYY] 122506
MMDDYYYY SELECT REPLACE(CONVERT(VARCHAR(10), GETDATE(), 101), '/', '') AS [MMDDYYYY] 12252006
DDMMYY SELECT REPLACE(CONVERT(VARCHAR(10), GETDATE(), 3), '/', '') AS [DDMMYY] 240702
DDMMYYYY SELECT REPLACE(CONVERT(VARCHAR(10), GETDATE(), 103), '/', '') AS [DDMMYYYY] 24072002
Mon-YY 1 SELECT REPLACE(RIGHT(CONVERT(VARCHAR(9), GETDATE(), 6), 6), ' ', '-') AS [Mon-YY] Sep-02 1
Mon-YYYY 1 SELECT REPLACE(RIGHT(CONVERT(VARCHAR(11), GETDATE(), 106), 8), ' ', '-') AS [Mon-YYYY] Sep-2002 1
DD-Mon-YY 1 SELECT REPLACE(CONVERT(VARCHAR(9), GETDATE(), 6), ' ', '-') AS [DD-Mon-YY] 25-Dec-05 1
DD-Mon-YYYY 1 SELECT REPLACE(CONVERT(VARCHAR(11), GETDATE(), 106), ' ', '-') AS [DD-Mon-YYYY] 25-Dec-2005 1

http://database.sarang.net/?inc=read&aid=3192&criteria=mssql&subcrit=&id=30&limit=20&keyword=insert&page=12

DECLARE @s_date smalldatetime
               ,@e_date smalldatetime
               ,@temp_date smalldatetime
               ,@i int
               ,@j int

DECLARE @temp TABLE
(
  date smalldatetime
)

SELECT  @s_date = '20061001' , @e_date='20061003',@i = DATEDIFF(day, @s_date,@e_date),@j=0

SET @temp_date= @s_date

WHILE @i>=@j
BEGIN
      INSERT INTO @temp(date)  values(@temp_date)
      SET @j=@j +1;
      SET @temp_date= DATEADD(dd,@j,@s_date)
END

 SELECT  CONVERT(char(10), date,112) AS date FROM  @temp

-> 20061001
     20061002
     20061003

간략히 살펴보면 변수선언/시작-끝 날짜 차이만큼 루프 돌면서 그 사이의 날짜를 임시테이블에 저장하는 방식.
MSSQL문법은 잘 모르겠으나 찾던 정보임..

시작부터 끝까지 한번에 실행해야되더라.. MS SQL Server Management Studio Express에서.

내 소스. 정보를 통계용 날짜 테이블에 넣었다


/*시스템 날짜 구하듯이, 데이타 없이 특정 기간 내의 날짜를 전부 구하는 방법*/
DECLARE @s_date smalldatetime
               ,@e_date smalldatetime
               ,@temp_date smalldatetime
               ,@i int
               ,@j int

DECLARE @temp TABLE
(
  date smalldatetime
)

SELECT  @s_date = '20010101' , @e_date='20501231', @i = DATEDIFF(day, @s_date,@e_date), @j=0

SET @temp_date= @s_date

WHILE @i>=@j
BEGIN
    INSERT INTO @temp(date)  values(@temp_date)
    SET @j=@j +1;
    SET @temp_date= DATEADD(dd,@j,@s_date)
END

/*SELECT date FROM @temp*/
INSERT INTO DUAL_CALENDAR
    SELECT
        DATENAME(yy, date), DATENAME(mm, date),
        /*DATENAME(dd, date), */
        SUBSTRING(CONVERT(char(10), date,121), 9, 10),
        CONVERT(char(10), date,121) AS date
    FROM  @temp
/*여기까지 한번에 실행할 것. 100년까지는 한번에 안되는듯. 50년은 됨.
50년 마다 한번씩 실행되게 스케줄러에 등록 또는 1년마다 한번씩 되도록 등록*/

'프로그래밍 > DB' 카테고리의 다른 글

[펌] MSSQL 날짜 함수  (0) 2009.01.14
[펌] date 타입 변환 함수  (0) 2009.01.14
ORLCLE->MSSQL  (0) 2009.01.14
[펌/DB관련팁] 일간/월간/연간 통계 시  (0) 2009.01.09
[펌] MySQL 사용하기  (0) 2008.11.25

ORLCLE->MSSQL

프로그래밍/DB 2009. 1. 14. 14:15 Posted by galad

오라클함수 -> MSSQL함수

LENGTH -> LEN
ADD_MONTH -> DATEADD
DECODE -> CASE WHEN THEN
TO_CHAR -> CONVERT
SUBSTR  -> SUBSTRING
NVL -> isNULL
SYSDATE -> GETDATE()
TRUNC -> FLOOR
LIMIT -> TOP
TO_DATE([DATE],'YY-MM-DD') -> CONVERT(VARCHAR(8),[DATE],102)  : CONVERT의 마지막 인수를 잘 설정하면됨.
  • 다소 쌩뚱맞긴 합니다만... ^^;; 
    통계작업에 유용하게 사용할 수 있는 달력테이블을 만들어서 사용하기도 합니다. 
    create table 달력 (년 varchar2(4), 월 varchar2(2), 일 varchar2(2), 년월일 varchar2(8)); 
    요로코롬 말이지요. 
    말씀하시는바와 같이 화면에 임의의 년에대한 모든 월데이터를 보인다던가.. 할때 유용하게 사용할 수 있지요.
    통계화면이 한두개가 아니다보니.. 요로코롬 미리 테이블을 구성한 후 join으로 이용하는것도 꽤 괜찮은 방법입니다. 
    DBA님이나 사수분께 의논해보심은 어떠시련지요. ^^;; 
    아니면.. 제 오래된 기억에 mssql 2000의 경우엔 템프테이블을 만들 수 있는 방법이 있었는데요.. 
    요 템프테이블을 달력테이블처럼 구성하여 사용하셔도 될듯 합니다. 
    그럼 ^^;;
  • dazzilove

from
http://okjsp.pe.kr/seq/117001

통계 시 실제 데이터가 없는 일/월/연을 0건으로 표시하기 위해서 위와 같은 처리가 필요.
아님

  • select 1 as month, 0 as cnt 
    from dual 
    union all 
    select 2 as month, 0 as cnt 
    from dual 
    union all 
    select 3 as month, 0 as cnt 
    from dual 
    union all 
    select 4 as month, 0 as cnt 
    from dual 
    union all 
    select 5 as month, 0 as cnt 
    from dual 
    .... 

    으로 가라로 뷰를 하나 만든다음에 outer join 하면 되지 않을까요?
  • mgcos

이건 넘 쿼리가 길어지는 듯....

/*OUTER JOIN 테스트용.
임시로 월간 캘린더 테이블을 만들어서 실제 데이타와 조인. 그런 다음 갯수를 세면 데이터가 없는 월의 것도 카운트 가능해진다
임시 테이블을 만들어서 데이타를 뽑아내긴 하였으나, 검색기간이 동적으로 변하므로 그것에 대한 처리는 어떻게 하는가?
실제 물리적인 테이블에 모든 데이타를 넣어두어 그것을 가지고 해야하지 않나?
*/
SELECT
    COUNT(EVT_CODE), MONTHLY
FROM
(
    SELECT
        R5E.EVT_CODE,
        /*CASE //이것은 필요없을 듯. MSSQL서 COUNT시 NULL은 자동으로 0으로 인식됨
            WHEN R5E.EVT_CODE IS NULL THEN 0
            WHEN R5E.EVT_CODE IS NOT NULL THEN 1
        END AS CODE_COUNT,*/
        CASE
            WHEN R5E.MON IS NULL THEN TM2.MON
            WHEN R5E.MON IS NOT NULL THEN R5E.MON
        END AS MONTHLY
    FROM
    (
        (
            SELECT EVT_CODE, CONVERT(CHAR(7), EVT_DATE, 121) AS MON FROM R5EVENTS
            WHERE CONVERT(CHAR(7), EVT_DATE, 121) BETWEEN '2008-12' AND '2009-01'
        ) R5E
        FULL OUTER JOIN
        (
            SELECT MON, CNT FROM
            (
                SELECT '2009-01' AS MON, 0 AS CNT FROM DUAL
                UNION ALL
                SELECT '2009-02' AS MON, 0 AS CNT FROM DUAL
                UNION ALL
                SELECT '2009-03' AS MON, 0 AS CNT FROM DUAL
                UNION ALL
                SELECT '2009-04' AS MON, 0 AS CNT FROM DUAL
                UNION ALL
                SELECT '2009-05' AS MON, 0 AS CNT FROM DUAL
                UNION ALL
                SELECT '2009-06' AS MON, 0 AS CNT FROM DUAL
                UNION ALL
                SELECT '2009-07' AS MON, 0 AS CNT FROM DUAL
                UNION ALL
                SELECT '2009-08' AS MON, 0 AS CNT FROM DUAL
                UNION ALL
                SELECT '2009-09' AS MON, 0 AS CNT FROM DUAL
                UNION ALL
                SELECT '2009-10' AS MON, 0 AS CNT FROM DUAL
                UNION ALL
                SELECT '2009-11' AS MON, 0 AS CNT FROM DUAL
                UNION ALL
                SELECT '2009-12' AS MON, 0 AS CNT FROM DUAL
            ) TM
        ) TM2
        ON TM2.MON = R5E.MON
    )
) A
GROUP BY
    MONTHLY

길어졌다...

[log4j] 사용례

프로그래밍/Library 2009. 1. 8. 17:12 Posted by galad
패턴에 따른 로그의 예
1.
log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n

2009-01-08 16:27:37,464 ERROR [main] xml.XMLMain       ( XMLMain.java:165)     - JOURNALREQ03.xml XML 파일 전송 실패

2.
log4j.appender.rolling.layout.ConversionPattern=%d %-5p [%t] %-17c{2} %3x - %m%n

2009-01-08 16:35:14,335 INFO  [main] xml.XMLMain           - ===== 프로그램 종료 =====


로그 레벨 순서

OFF/FATAL/ERROR/WARN/INFO/DEBUG/TRACE/ALL의 순서. 맞나???

CLASSPATH

프로그래밍/Java 2009. 1. 6. 17:44 Posted by galad
http://www.ibm.com/developerworks/kr/library/j-classpath-windows/index.html

E:\workspace\java_run_test>javac -verbose -d bin -sourcepath src src\test\xml\XMLMain.java

jdk설치 디렉\jre\lib\ext에 넣어둔 라이브러리도 참조해버렸다...
dom4j관련 에러가 나야 정상일 듯 싶은데...

역시나 jdk설치 디렉\jre\lib\ext에 넣었던 dom4j 관련 라이브러리 삭제 후 실행했더니 에러 발생.
그래서 다음과 같이 해봤더니,

E:\workspace\java_run_test>javac -verbose -d bin -sourcepath src -classpath E:\workspace\java_run_test\Lib src\test\xml\XMLMain.java

E:\workspace\java_run_test\Lib 여기에 dom4j관련 라이브러리가 있는데도 에러가 난다.
왜 그런가 봤더니
"완전하고, 개별적으로 컴파일 된 서드 파티 라이브러리를 사용하지 않는 경우를 가정했다. 만약 그렇다면, 이들을 classpath에도 추가해야 한다. 라이브러리는 junit.jar 또는 icu4j.jar 같은 JAR 파일로 배포된다. 이 경우, classpath에 추가하는 것은, JAR 파일 그 자체이다. 이것을 포함하고 있는 디렉토리가 아니다." - from IBM(위의 링크 참조)
랜다.

서드 파티 라이브러리 사용시엔 jar파일 자체를 추가해야 된단 말인가라고 생각하여

E:\workspace\java_run_test>javac -verbose -d bin -sourcepath src -classpath E:\workspace\java_run_test\Lib\dom4j-1.6.1.jar src\test\xml\XMLMain.java

로 했더니 깔끔하게 컴파일되었다.
음. 나름 이 업계서 먹고 살아왔는데도 기본을 잘 모르는군... 반성 반성...

이제 남은 건 실행.
bin폴더에 컴파일했으므로 bin폴더로 이동해서 다음과 같이 실행

E:\workspace\java_run_test\bin>java test.xml.XMLMain

당연히 될리 없다. dom4j관련 라이브러리 참조를 위해 classpath 지정

E:\workspace\java_run_test\bin>java -classpath E:\workspace\java_run_test\Lib\dom4j-1.6.1.jar test.xml.XMLMain

왠걸. 에러다.
Exception in thread "main" java.lang.NoClassDefFoundError: test/xml/XMLMain
Caused by: java.lang.ClassNotFoundException: test.xml.XMLMain
        at java.net.URLClassLoader$1.run(Unknown Source)

현재 지정된 클래스패스에서 test.xml.XMLMain를 못찾고 있다. 컴파일 타겟인 bin폴더를 지정안했으니 당연한 것인가라고 생각해서 다시 시도

E:\workspace\java_run_test\bin>java -classpath bin;E:\workspace\java_run_test\Lib\dom4j-1.6.1.jar test.xml.XMLMain

역시 에러. bin폴더에서 bin을 지정하고 있으니 문젠가 싶어서 상위 폴더로 이동 후 재실행

E:\workspace\java_run_test>java -classpath bin;E:\workspace\java_run_test\Lib\dom4j-1.6.1.jar test.xml.XMLMain

옷. 된다. (사실 또다른 라이브러리가 필요해서 에러가 발생했으나 문제는 파악되었으니 무시무시)

이게 완성된 실행문

E:\workspace\java_run_test>java -classpath bin;E:\workspace\java_run_test\Lib\dom4j-1.6.1.jar;E:\workspace\java_run_test\Lib\jaxen-1.1-beta-6.jar test.xml.XMLMain
java.net.ConnectException: Connection refused: connect --> 에러났으나 실행은 되었으니까 무시.

결론

javac -verbose -d bin(타겟 디렉토리) -sourcepath src(소스 디렉토리) -classpath E:\workspace\java_run_test\Lib\dom4j-1.6.1.jar(컴파일에 필요한 서드 파티 라이브러리의 경우 디렉토리path가 아닌 fie path) src\test\xml\XMLMain.java(실제 컴파일할 자바 소스-main()이 있는 클래스만 해도 연관된 것은 자동으로)


java -classpath bin;E:\workspace\java_run_test\Lib\dom4j-1.6.1.jar;E:\workspace\java_run_test\Lib\jaxen-1.1-beta-6.jar(실행 시 필요한 서드 파티 라이브러리&컴파일된 class파일이 있는 디렉토리) test.xml.XMLMain(실행시킬 풀 클래스명)
연결 시 '로컬 리소스' 탭을 누른다. 원격지 PC에서 내 PC로 데이터를 복사하려면 '로컬 서비스' 항목에서 '디스크 드라이브'에 반드시 체크 표시를 해야 한다.

'프로그래밍 > Library' 카테고리의 다른 글

[EXCEL] 셀 범위로 드롭다운 목록 만들기  (0) 2009.01.29
[log4j] 사용례  (0) 2009.01.08
[펌] JExcelApi & POI  (0) 2007.11.28
[펌] 자바로 엑셀 때려잡기!!  (0) 2007.11.28
[펌] 각종 제어  (0) 2007.11.28