Search Results for '전체 분류'


2064 posts related to '전체 분류'

  1. 2009/08/11 DDoS 공격 툴 NetBot Attacker
  2. 2009/08/11 웹기반의 DDoS botnet, BlackEnergy
  3. 2009/08/11 R-Studio v4.5 Build 127456 [데이타 복구유틸] 1
  4. 2009/08/11 Adobe Flex Builder 3 - & - keygen
  5. 2009/08/10 중복되는 URL을 위해 Canonical Link 요소를 넣어주세요.
  6. 2009/08/10 Google 메일서버 이용하기
  7. 2009/08/10 jQuery를 사용한 간단한 플로팅 레이어 (따라다니는 레이어 ) 3
  8. 2009/08/10 Windows 2008 Server, PHP 5.3, MySQL 5.1 설치기
  9. 2009/08/10 [서버운영] 기특한 모니터링 도구 - Monit!!
  10. 2009/08/10 jQuery Form Builder Plugin
  11. 2009/08/10 MS-SQL- Login을 각 Database의 User와 동기화하기
  12. 2009/08/10 MS-SQL 모든 테이블의 데이터 일괄 삭제하기
  13. 2009/08/10 [Sequel Safe] SQL 2008 SERVER Login 권한 정책 및 물리 모델 변경 제약
  14. 2009/08/10 SQL 2008 SERVER - hierarchyid의 method 정리
  15. 2009/08/10 SQL 2008 SERVER - SPARSE 컬럼
  16. 2009/08/10 SQL 2008 Server 로그인 및 사용자 권한 정책
  17. 2009/08/10 SQL 2008 온라인 설명서(2009년 5월)
  18. 2009/08/10 오픈소스 프로그램 Top 10
  19. 2009/08/10 포토샵 팁 - 썸네일 크기를 최소로 줄여서 빠르게 실행하기
  20. 2009/08/07 25가지 SQL작성법
  21. 2009/08/07 파일복사및 리네임
  22. 2009/08/07 asp 전체메일보내기
  23. 2009/08/07 ASP + MS-SQL 사용중인 DB 용량보기
  24. 2009/08/07 [Tips:ASP]ASP-Mysql 연동
  25. 2009/08/07 비주얼 베이직으로 간단하게 만드는 ASP용 COM+
  26. 2009/08/07 [본문스크랩] DLL 등록 쉽게 하기
  27. 2009/08/07 프레임에서 새로고침(F5)를 하더라도 첫 페이지로 이동하지 않습니다.
  28. 2009/08/07 AJAX file upload 2
  29. 2009/08/07 scriptmanager 와 ajax.net
  30. 2009/08/07 원하는 컨트롤만 렌더링 하기

작년에 아이템베이등 국내 아이템 거래 사이트를 초토화 시키고 최근에 웹 사이트를 대상으로 하는 랜섬어택으로 DDoS를 많이 당하고 있는데 사용된 툴이라고 합니다,
아래 사이트에서 공격 데모를 보여주고 있습니다.
데모 화면을 보시면 중국해커 PC에 어떤 프로그램이 설치되어 있는지 그리고 주로 무슨 툴을 사용하는지도 엿볼 수 있습니다.
여기서 해커의 성향을 엿볼 수 있는데 지금 데모를 하는 중국해커는 공격성향이 강한 사람 같습니다. 데모지만 실제 서비스 사이트에 대해 주저하지 않고 공격을 해버립니다.
근데 한가지 의문은 데모에서 단지 5대의 좀비 PC로 웹 서버가 죽는게 이상합니다. 5대 좀비 PC 가지고 대량의 트래픽 발생한다는 것은 불가능한데도 웹 서버가 죽는 것 보면 뭔가 특별한 DoS 공격인 것 같습니다.
잘 보시면 DoS 공격 타입이 CC Attack 타입을 선택하고 있습니다. 이 부분이 핵심입니다.
PC 화면에 보니 syser, MS VC++, GMER, FBFD.EXE, ooBar2000.exe, Samsung PC Studio3(삼성 휴대폰 연결프로그램), 중국어로 된 각종 기능을 알 수 없는 프로그램들...   아래 화면을 보시면 NetBot Attacker에서 아이피 주소와 한국이라는 도메인이 나오는 부분이 있는데 이게 바로 자동으로 좀비 PC가 해커 PC로 리버스 커넥션한 좀비 PC 리스트입니다. 그리고 옆에다 찍으면 그 좀비 PC가 공격하는 형태입니다.

해킹은 확실히 공격하는 측보다는 막는 측이 불리합니다.
DDoS 공격툴은 확실히 가난하지만 사악한 Hacker자들이 선호하는 무기입니다.

http://www.hackeroo.com/move/netbot_attacker.html

(1) NetBot Attacker 1.6 Public 버전(이 프로그램이 필요하다면 돈주고 사라고 합니다)

사용자 삽입 이미지

사용자 삽입 이미지

(2) NetBot Attacker 2.3 VIP 영문버전(이 버전은 구하기 쉬지가 않음)

좌측 상단은 좀비 PC 리스트이고 우측 하단은 원격에서 쉘로 좀비 PC에 들어가 있는 것으로 추정되고 좌축 하단은 FTP로 파일 업로드 다운로드 하는 매니저 프로그램이다.

사용자 삽입 이미지

이 툴만 있으면 반대로 국내에 좀비 PC를 찾아내는 것이 더 쉬울 듯 합니다. 그러나 일부 좀비 PC가 하나의 가치로 평가되어 Botnet정보가 거액으로 거래된다고 합니다.
NetBot Attacker 2.3 VIP 영문 버전을 구하는 사람은 대박입니다.

(3) 국내외에 좀비 PC 리스트를 한눈에 확인할 수 있다.

사용자 삽입 이미지
 
2009/08/11 13:59 2009/08/11 13:59
IRC기반의 botnet이 아닌 웹기반의 botnet으로, 러시아의 해커가 만들었다. C&C(Command & Control) 서버(명령을 내리고, 조종하는 서버. BlackEnergy에서는 웹 페이지가 이에 해당)는 러시아나 말레이지아에 위치에 있으며, 주로 러시아를 공격 대상으로 한다.

BlackEnergy는 크게 2가지로 구성되어 있다.

1. 웹기반의 C&C를 제공한다. (php+MySQL)
2. DDoS공격 bot을 생성하는 툴(builder.exe)을 제공한다.
   builder.exe 툴을 이용하여 웹기반 bot관리 서버로 접속하는 바이너리파일을 생성할 수 있게 된다.
사용자 삽입 이미지

[ 이미지 출처 : 글 끝에 소개한 URL ]

bot 바이너리는 지정한 C&C서버로 접속하게 된다. 그리고, bot과 제어서버간의 명령은 웹을 통해서 이뤄지게 되며, 구조는 대략 이렇다.

1. bot은 C&C 서버의의 URL(예. http://웹서버/경로/stat.php )을 체크하게 된다. 이 때 id, build_id 값을 POST방식으로 넘긴다.
2. 서버에서는 명령 등의 상태 값을 BASE64 인코딩된 값으로 리턴을 한다. 그 값에 따라서 bot은 명령을 수행한다.
   다양한 공격 유형이 있는데, ICMP flood, TCP SYN flood, UDP flood, DNS flood, http 요청 등이 있다.
   'flood http foobar.com a.html' 명령을 내린다면 foobar.com/a.html을 계속 호출하게 되며, 'flood syn foobar.com 80'은 TCP SYN flood를 발생한다.

PC에 설치된 bot에 대한 작년 10월 백신 검사 결과를 보니 V3, clamAV, AVG, McAfee 등은 이 바이너리를 못 찾아내고, F-Secure, F-Prot, Kaspersky는 찾아냈다.

보다 자세한 정보는 'BlackEnergy DDoS Bot Web Based C&C'에서 볼 수 있다.
2009/08/11 13:45 2009/08/11 13:45
사용자 삽입 이미지
R-studio는 윈도우/리눅스 사용자를 위한 융통성 있는 자료 복구(Undelete)를 위한 프로그램 입니다.
지원하는 디스크 파티션은 FAT12/16/32, NTFS, NTFS5, Ext2FS 파티션을 지원합니다.
네트워크 위의 원격 조작 컴퓨터에 붙어 있는 디스크에서도 지워진 파일을 다시 복구하는 작업을 수행할 수 있습니다.
분할 구조가 망가지거나,삭제 되든지 말입니다. FDISK 가동, MBR 파괴, FAT 손해와 바이러스 감염 이후 파일과 분할 회복도 수행할 수 있습니다. 동적인 디스크와 암호화 되었던 파일압축파일)을 회수하기도 하지요.
탐색기와 비슷한 폴더구조로 파일 또는 디스크 내용은 보일 수 있고,16진 기수법을 편집할 수 있는 분들은 편집할 수도 있습니다.
이 기능은 NTFS 파일 속성 편집을 지원합니다. 설정이 당신에게 주는 많은 유일한 기술과 유연한 매개 변수와 함께 R-studio 가 필요하게 되어 생긴 소프트웨어 입니다.
로컬은 물론 네트워크에 이어져있는 하드디스크에 대하여 삭제된 파일을 살리기 위한 가장 최적의 소프트웨어 입니다. 파일정보에 X 표시가 있는 것이 삭제된 파일이며, 복구가 가능한 파일들 입니다.
여타 MS-DOS 나 윈도우용에서는 파일명의 앞자리가 ? 로 와일드 문자로 표기되지만 R-studio 에서는 앞자리도 빠짐 없이 표기를 하여 줍니다. 빠른 Disk Sector 검색으로 빠르게 파일의 복구를 수행할 수 있습니다.
삭제된 파일명에 대한 검색도 됩니다.
2009/08/11 13:30 2009/08/11 13:30
Adobe Flex Builder 3 의 키젠입니다.
 
1. http://www.adobe.com의 Flex Builder 3를 Trial 60일 버전으로 다운로드 합니다.
 
2. 내 컴퓨터에 설치를 합니다.
 
3. 실행하면 제품번호를 입력하라는 메시지가 뜹니다.
 
4. 키젠을 실행하셔서, 제품번호를 생성후 복사하여 입력하시면 됩니다.
 
또는
 
실행 후 help메뉴를 누르셔서   License 메뉴를 클릭후 제품번호를 넣으셔도 됩니다.
속도가 느리면 여기서 직접 받으세요.
2009/08/11 13:20 2009/08/11 13:20

http://example.com/page.html, http://example.com/page.html?param1=1, http://www.example.com/page.html 등 한 문서를 가리키는 여러 URL은 검색엔진에 심각한 중복 문제를 안겨줍니다. 최근 구글, 야후, 마이크로소프트가 이를 해결할 수 있는 방법을 제시하였습니다.

<link rel="canonical" href="http://example.com/page.html" />

위의 코드를 넣어주면 끝입니다. 간단하죠? 단어 그대로 표준 혹은 대표 링크를 선언해주는 것입니다. 이미 많은 발표자료, 동영상 등이 공개되어 있네요. 보시죠~ 참고로 첫 링크만 보시면 정리가 다 됩니다. :)

2009/08/10 12:43 2009/08/10 12:43
메일 서버 구축하기 난감하신분들 사용하시면 편할듯 싶습니다.

클라이언트 4분 셋팅해드렸는데...
클라이언트들도 더이상 메일서버가 말성을 안일으킨다고 감사메일까지 날려줍니다.

링크따라가셔서 가입만하면 됩니다.
링크1 : 학교, 교육단체
링크2 : 비영리기관

기업형, 학교용, 비영리단체 가 있습니다.
기업형은 가입을 안해봐서 모르겠습니다.
(학교용, 비영리단체용으로만 가입을 시켰습니다.)

MX 레코드 설정하시고 CNAME 이나 HTML 로 인증 받으시면 됩니다.
최초설정시 48시간걸리는줄 알았는데 30분정도면 인증되네요

코드값 : google4091bac42bede38c

# MX 레코드 셋팅
                        IN      MX 10  aspmx.l.google.com.
                        IN      MX 20  alt1.aspmx.l.google.com.
                        IN      MX 20  alt2.aspmx.l.google.com.
                        IN      MX 30  aspmx2.googlemail.com.
                        IN      MX 30  aspmx3.googlemail.com.
                        IN      MX 30  aspmx4.googlemail.com.
                        IN      MX 30  aspmx5.googlemail.com.
webmail                IN      CNAME  ghs.google.com

# CNAME 인증방법
# 네임서버에 추가
google4091bac42bede38c  IN      CNAME  google.com

# HTML 인증방법
# 해당 도메인 최상위에 googlehostedservice.html 화일 생성
# 내용은 다음과 같습니다.
google4091bac42bede38c


### 추가사항 2009.06.24
코드값은 밑에 댓글처럼 구글에서 임의로 생성해 줍니다.
적은줄 알았는데 안적어놨었네요 @@

http://www.google.com/a/help/intl/ko/edu/index.html
2009/08/10 12:37 2009/08/10 12:37
현재 서비스되는 사이트에 적용하려고 급하게 만들었습니다;
간단하게 사용하실분만 사용하세요
jQuery 1.3.2 가 필요합니다
문제점이 무진장 많을 수 있습니다!

var top = 120; // Y값입니다 상단에서 얼마나 떨어진 위치에 고정할것인지..
var speed = 100; // 속도 값이 작을수록 빠르게 움직임
var banner = $("#banner"); // 움직이고 싶은 레이어의 ID값입니다 예) <div id = "banner"></div>

banner.css({'top':top}); // 초기 위치 지정

// IE에서는 속도를 빠르게 해줌 (좀 느린경향이 있는듯?)
jQuery.each(jQuery.browser, function(i, val){
    if(i=="msie" && val==true) speed = 10;
});

$(window).scroll(function(){
    var scrolledTop = document.body.scrollTop+top;
    banner.animate({"top":scrolledTop }, speed, "linear");
});
2009/08/10 12:35 2009/08/10 12:35
흠.. 닷넷 만지다가 도피를 위해 PHP와 MySQL을 깔았는데..
요즘 세상 참 좋아졌다는 생각이 들었습니다.
PHP와 MySQL이 마법사식으로 까는건 뭐 일도 아닌데.
이제는 윈도우에 대한 배려(?)도 해주는듯 손쉽게 PHP+MySQL을 깔아줍니다.

그 과정을 여러분께 소개하려고 합니다.
먼저, Windows 2008에 IIS를 깔았습니다. 윈도우 서버를 사용하면 IIS를 쓰지 아파치 쓰는건 이건 좀 사치가 아닌가요?ㅋㅋ
어쨌든 간에 IIS를 깔고, 그리고 필수적으로 깔아야 하는게 CGI입니다.

전에 윈도우 2008 사이트에서 아주 놀고있는 광고를 했습니다.
PHP 사이트에도 강력하다고 홍보하는 윈도우 2008 광고를 보면서.
닷넷은 뒀다 모할거냐는 의문점이 들기도 했습니다........
이거 원..

어쨌든 IIS와 CGI를 깔았으면 그다음 필수적으로 깔아줘야 하는게 있습니다.

MS에서 제공하는 Web Platform Installer입니다.

유의하실 점은 업데이트 도중에 이 프로그램으로 설치하면 설치 안되는 일이 발생할 수 있습니다. 업데이트 싹 하거나 업데이트를 아예 멈추고 하시기 바랍니다.
저같은 업뎃때문에 설치 실패하는 일이 있었습니다.
어쨌든, 설치합시다.
http://www.microsoft.com/web/downloads/platform.aspx

윈도우 XP 이상이면 깔 수 있으며, 윈도우 XP Pro에 딸린 10명짜리 IIS 5.1도 구축이 가능합니다. 동시접속자수 10명 제한 낄낄. 무슨 이거..
윈도우 비스타에 홈서버 버전도 있는데 그거 아시는분 알려주셈,.
(근데 왜 MS에서는 유독 한국에만 홈서버나 서버 OS중 웹서버 기반 에디션을 출시 안하는건지 원..)

다운받고 실행하면 자동적으로 컴퓨터에 나도 모르게 깔리며(...) 설치할 목록들이 아주 쫘악 나옵니다.

여기서 주목할 것은, 워드프레스도 있습니다. 낄낄.

Visual Web Developer로도 충분히 닷넷 웹사이트도 만들고 웹사이트 만들 수 있는 강력한 IDE에다 무료이긴 한데.. 음.. 그건 선택사항이니 쓰실분은 쓰셈.

여기에 보시면 PHP 5.2.10이 있습니다. 설치를 해도 되지만, 5.3을 쓸려면 굳이 체크는 안해도 됩니다.

그리고 IIS 6.0이거나 7.0이면 FastCGI가 보입니다. 꼭 설치하는게 좋습니다.

그리고 IIS7.0 이상일 경우 URL Rewrite가 있습니다. 2.0 베타버전도 보이는데 안써봐서 모르겠고, 1.0 깔아도 됩니다. 심심하면 2.0 깔아보는것도 좋을듯.

어쨌든 설치할 건 뭐 별로 없는 편입니다. 설치하면 다운 "받으면서 설치"합니다.
참 기이한 설치 화면이죠.

이렇게 해서 컹그레츄에이션이라고 뜨면 닫습니다.

자, 이제 PHP와 MySQL을 깔아봅시다.

아참, Zend Platform이 있습니다. PHP와 MySQL을 한번에 설치해주고 최적화까지 해버린 강력한 플랫폼입니다. 무료 버전도 정말 좋긴 한데..
제가 예전에 2008에서 깔았는데 갑자기 서버가 바보가 되버려서 지웠습니다.
근데 저처럼 서버가 바보 안되고 멀쩡하면 그거 쓰는것도 좋을 듯 하군요.

PHP 5.3은 여기서 받고,
http://windows.php.net/download/

MySQL 5.1은 여기서 받습니다.
http://dev.mysql.com/downloads/

그리고 이 환경에 PHPMyAdmin도 빼놓을 수 없죠.
http://www.phpmyadmin.net

자. PHP와 MySQL은 마법사가 뜹니다.
이때, PHP는 IIS FastCGI로 설정하면 지가 알아서 FastCGI와 처리기 매핑에 등록됩니다.
그리고 MySQL은 설치가 끝나면 마법사가 뜨는데, 그다지 만질 건 없습니다.

그냥 다음-> 다음 -> 다음.... 일반으로 사용한다면 그냥 기본값으로 써도 무리없습니다.
그리고 MySQL을 윈도우 서비스에 등록되 실행됩니다.
이때, 처음으로 마법사가 뜨기 때문에 root의 암호를 지정할 수 있습니다.
이럴때 암호를 지정하면 좋겠죠. 그리고 한국어기 때문에 언어 선택시
日本語라고 말풍선으로 재잘되는놈으로 선택하면 기본 언어셋이 유니코드가 됩니다.
아니면 그냥 순수 한국어가 좋다면 한국어 언어셋으로 직접 타이핑으로 등록해도 됩니다.

주저리주저리 설정하면 어느세 PHP와 MySQL 환경 구축은 끝.

자, 이제 사이트를 하나 만들어 만들어봅시다.

시작 -> 실행 -> inetmgr 엔터.

역시 그냥 콘솔식이 빠릅니다.ㅋㅋㅋㅋㅋㅋ
이렇게 IIS 관리에 들어갑니다. 서버를 선택한 다음 사이트로 가서 새 사이트 추가합니다.
IIS 6.0에 비해 IIS 7.0부터는 마법사 형태가 아닌 원샷 형태입니다. 좋아요.ㅋㅋ
그리고 응용 어플은 기본적으로 지가 알아서 새로 만듭니다.
근데 왠만하면 응용 어플을 하나 만들고 하는게 성능 면에서 좋습니다.
응용 풀 추가 -> 이름은 아무거나, 닷넷프레임워크 버전은 관리코드없음, 관리모드는 통합. 확인. 끝.
그런 다음에 이 응용 풀에 PHP 사이트를 만들면 닷넷이 관여하지 않기 때문에 바로 슝 왔다갔다할수 있고, 관리 기능 목록이 간결해집니다.

어쨌든 응용풀 만들고 사이트를 만들었으면, 기본적으로 html,htm은 PHP가 관여하지 않습니다. 만약에 원하면 html과 htm 등을 PHP 스크립트가 돌아가게 할 수 있습니다.
먼저 만든 사이트를 클릭하면 기능 목록이 뜹니다. 처리기 매핑을 누릅니다.
거기서 작업탭에 모듈 매핑을 추가합니다.
요청 경로에 확장자를 입력합니다. *.htm 이런식으로. 복수 확장자는 불가능하니 항상 단 하나의 확장자만 입력하세요. 단점이긴 하지만 어쩔수가 없습니다.
모듈은 FastCgiModule을 선택합니다.
실행 파일은 PHP 실행 파일을 선택합니다. PHP는 기본적으로 깔린 폴더가
C:\Program Files\PHP\php-cgi.exe입니다.
이때, 그냥 쓰고 확인누르면 오류납니다. 따옴표 적으라는 소리죠. 따옴표로 감싸주시고,
요청 제한에서 매핑 탭에 요청이 어쩌구에 체크표시합니다. 그런 다음 파일 또는 폴더로 해주면 나중에 리라이트할때 집나가면 개고생이다 소리 안할 수 있습니다.
이렇게 해서 PHP 사이트 구축은 끝났습니다.
이제 PHP가 돌아가는지 테스트해봅시다.
index.php을 만들고 phpinfo()를 작성합니다.

자 이제 띄워보면 절대 멀쩡하게 뜰리가 없고 에러가 발생합니다.
기본적으로 윈도우2008에 제공되는 IE에서는 PHP 에러메시지조차 안뜨고 페이지를 표시할 수 없다고 뜹니다. 그 문제는 인터넷 옵션에 HTTP 오류 보기를 체크해제하면 해결.
그러면 이제 PHP 오류를 볼 수 있습니다.
아시겠지만 PHP 5대부터는 short_tag가 off 되있습니다. 하지만 웹플랫폼 인스톨러를 통해 깐 PHP는 왠만한 편리한 PHP 설정으로 되있어서 바로 써먹을 수 있습니다. 미리 설정을 하고 깔아주기 때문에 편리함은 그게 더하지만.
어쨌든, 하실분은 하시고 안하실라면 하지 마시고, 그러면 이번엔 길~다란 에러가 뜹니다.
PHP 5.3대 설치시 뜨는 이렇게 기다란 에러는 Timezone을 설정하지 않아서입니다.
귀찮게 하죠 참..
php.ini에서 [date] 검색한다음 그아래 timezone에 주석을 풀고 Asia/Seoul을 입력합니다.

자 이제 실행하면 이제 아주아주아주 잘뜨는 감격스런 phpinfo가 뜹니다.

PHPmyadmin은 새 가상 디렉터리로 잡거나 아니면 IIS7의 경우 새 응용프로그램 풀이 있습니다. 그걸로 하셔도 됩니다. 둘이 뭐 다를 건 없죠. 단지 사이트의 하위 응용 프로그램은 부모에 상속은 되지만, 가상 디렉터리에 비해 부모 설정을 거기서 또 할수 있는 매력이 있습니다.
예를들어 닷넷없는 사이트 하위 디렉터리에 닷넷전용 디렉터리 만들 용도다 할때 쓰면 좋겠죠.
어쨌든 주저리주저리하지만 그다지 어렵지는 않습니다.

몇가지 덧붙이자면, PHP5.3 설치할때 full로 까시거나 custom할때 mbstring은 꼭 깔아야 나중에 한글 가지고 놀때 부담이 줄어들겠죠.
그리고 phpmyadmin에서 mcrypt 때문에 메시지 뜨면
http://files.edin.dk/php/win32/mcrypt/
에서 libmcrypt.dll을 받아서 system32 폴더와 php 폴더에 넣고 서버를 재시작하면 됩니다.
이래도 적용이 안된다면 전과 같은 방법으로 mcrypt를 넣고 다시 PHP를 설치하면 됩니다.

윈도우 2008과 PHP. 쓸만합니다. 리라이트가 있어서 빛이 더해지는군요.
리라이트 모듈은.. 음.. 쩝;; 그냥 아파치 리라이트 만든 다음에 URL Rewrite 기능에 들거가Import Rules 클릭한 다음 스크립트를 넣거나 .htaccess 파일을 첨부하면 지가 알아서 해석해서 넣어줍니다. Filesmatch와 헤더를 넣으신 분은 처리기 매핑을 이용하실수밖에.
IIS 에서는 지원 안합니다.
2009/08/10 12:31 2009/08/10 12:31
웹베이스 모니터링 도구입니다..

다운로드 : http://mmonit.com/monit/dist/monit-5.0.3.tar.gz

메뉴얼 :  http://mmonit.com/monit/documentation/monit.html

데몬별로 상태를 확인해서 특정 조건에 도달할경우 명령수행이 가능합니다..

아래 설정은 웹서버를 예로든것입니다..

메모리사용 3072M, childen 500, CPU 95%, port Fail

위 사항이 체크돼면 재시작입니다..

start, stop 스크립트를 만들면 프로세스 정보나 접근기록을 기록할수 있을듯 하네요..

set daemon 120 # Poll at 2-minute intervals
set mailserver 모니터메일서버주소
set logfile syslog facility log_daemon
set alert email
set httpd port 3000 and use address 도메인주소
    allow localhost
    allow 허용할아이피대역
    allow 관리자아이디:비밀번호

check system domain.tld
    if loadavg (1min) > 4 then alert
    if loadavg (5min) > 2 then alert
    if memory usage > 75% then alert
    if cpu usage (user) > 70% then alert
    if cpu usage (system) > 30% then alert
    if cpu usage (wait) > 20% then alert

check process apache
    with pidfile "/usr/www/apache2/logs/httpd.pid"
    start program = "/usr/www/apache2/bin/apachectl startssl" with timeout 60 seconds
    stop program = "/usr/www/apache2/bin/apachectl stop"
    if 2 restarts within 3 cycles then timeout
    if totalmem > 3072 Mb then alert
    if children > 500 for 5 cycles then stop
    if cpu usage > 95% for 3 cycles then restart
    if failed port 80 protocol http then restart
    group server
    depends on httpd.conf, httpd.bin

check file httpd.conf
    with path /usr/www/apache2/conf/httpd.conf
    if changed checksum
        then exec "/usr/www/apache2/bin/apachectl graceful"

check file httpd.bin
    with path /usr/www/apache2/bin/httpd
2009/08/10 12:29 2009/08/10 12:29

Trellis Development (a parent company of web-based products which I co-founded) has been developing a custom content management system which needed a form creation tool. I adapted a form builder that I created for a previous project as a jQuery 1.3 plugin. It loads in existing form structure data through an XML file (which would be generated on the server) and passes the changes as a serialized array back to the server.

View the Demonstration
Get source from github

I’ve forked the code from the cms to serve as a stand-alone plugin. It’s extremely easy to setup, as all you need to do is to activate it on an un/ordered list item element. Then, write your backend code to handle the incoming array as you need, and output the xml data for when the form loads.

  1.  
  2. <ul id="form-builder"></ul> 
  1.  
  2. $(document).ready(function(){  
  3.     $('#form-builder').formbuilder({  
  4.         'save_url': 'save.php',  
  5.         'load_url': 'form-a.xml' 
  6.     });  
  7. });  

The save_url is the url that the ajax will be sent to when the user saves the form. The form information is serialized so that the backend programming may handle it as an array.

The load_url is the url of an xml file that describes any existing form information, and the system uses it to restore the fields.

This requires jQuery 1.3+ and uses the scrollTo plugin for nice scrolling.

This is the first revision that’s external to our cms so I’ve labeled it 0.1.

2009/08/10 12:26 2009/08/10 12:26
백업 파일로부터 DB를 새로 복원할 때 곤란한 점은 일일이 DB의 User와 SQL서버의 Login을 매핑해 줘야 한다는 점이다.

아래 스크립트를 사용하면 이 작업을 한번에 처리할 수 있다.


1. User와 Login의 Sync가 맞지 않는 내역이 있는지 확인

DECLARE @nvcCollation sysname;

DECLARE @nvcStmt nvarchar(4000);

DECLARE @tblTemp table (

       DBName sysname NOT NULL,

       UserName sysname NOT NULL,

       LoginName sysname NOT NULL

);

 

SET @nvcCollation = CAST(DatabasePropertyEx('master', 'Collation') AS sysname);

SET @nvcStmt = N'

USE [?];

SELECT ''?'', A.name, B.loginname

FROM sys.sysusers A

       INNER JOIN master.dbo.syslogins B ON A.name COLLATE ' + @nvcCollation + N' = B.Name

       INNER JOIN master.dbo.sysdatabases C ON C.name = ''?''

WHERE A.issqluser = 1 AND (A.sid IS NOT NULL AND A.sid <> 0x0)

       AND SUSER_SNAME(A.sid) IS NULL

       AND (C.status & 32) =0 --loading

       AND (C.status & 64) =0 --pre recovery

       AND (C.status & 128) =0 --recovering

       AND (C.status & 256) =0 --not recovered

       AND (C.status & 512) =0 --offline

       AND (C.status & 1024) =0 --read only

ORDER BY A.name';

 

INSERT @tblTemp EXEC sp_msforeachdb @nvcStmt;

 

SELECT * FROM @tblTemp;

 


2. 위 스크립트에서 레코드가 반환된다면 => User와 Login을 Sync해 주기

DECLARE @nvcCollation sysname;

DECLARE @nvcStmt nvarchar(4000);

 

SET @nvcCollation = CAST(DatabasePropertyEx('master', 'Collation') AS sysname);

SET @nvcStmt = N'

USE [?];

DECLARE @nvcUserName sysname;

DECLARE @nvcLoginName sysname;

 

DECLARE SyncDBLogins CURSOR FOR

       SELECT A.name AS userName, B.loginname AS loginName

       FROM sys.sysusers A

             INNER JOIN master.dbo.syslogins B ON A.name COLLATE ' + @nvcCollation + N' = B.Name

             INNER JOIN master.dbo.sysdatabases C ON C.Name = ''?''

       WHERE A.issqluser = 1

             AND (A.sid IS NOT NULL AND A.sid <> 0x0)

             AND suser_sname(A.sid) IS NULL

             AND (C.status & 32) =0 --Loading

             AND (C.status & 64) =0 --pre recovery

             AND (C.status & 128) =0 --recovering

             AND (C.status & 256) =0 --not recovered

             AND (C.status & 512) =0 --offline

             AND (C.status & 1024) =0 --read only

       ORDER BY A.name;

 

OPEN SyncDBLogins;

 

FETCH NEXT FROM SyncDBLogins INTO @nvcUserName, @nvcLoginName;

 

WHILE @@FETCH_STATUS = 0

BEGIN

       EXEC sp_change_users_login ''update_one'', @nvcUserName, @nvcLoginName;

    FETCH NEXT FROM SyncDBLogins INTO @nvcUserName, @nvcLoginName;

END;

 

CLOSE SyncDBLogins;

 

DEALLOCATE SyncDBLogins;'

 

EXEC sp_msforeachdb @nvcStmt;




출처 : http://www.sqlservercentral.com/articles/Log+Shipping/63028/
2009/08/10 12:18 2009/08/10 12:18

프로젝트 초기에 개발 DB에서 자주 사용할 만한 쿼리일 듯 ^^

 

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'

EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'

EXEC sp_MSForEachTable 'DELETE FROM ?'

EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'

EXEC sp_MSForEachTable 'ALTER TABLE ? ENABLE TRIGGER ALL'

 

출처 : http://www.devx.com/dbzone/Article/40967

 

하지만, 그대로 사용하기엔 좀 부족해 보인다.

아래 사항을 추가해서 사용해야겠다.

1.     삭제하지 않을 테이블을 지정할 수 있을 것.

2.     DELETE문 대신 TRUNCATE TABLE문을 사용할 수 있다면… TRUNCATE TABLE문을 쓰도록 분기할 것. (테이블이 VIEWschema binding되어 있다면… DELETE문을 쓸 수 없을 듯)

3.     IDENTITY 속성의 컬럼을 포함한 경우, Reseed 할 것.
이때, 한번도 데이터가 INSERT되지 않았거나 TRUNCATE한 테이블과그렇지 않은 테이블의 Reseed 값을 달리 적용해야 함에 유의!!!



위의 조건 중 1번, 3번 항을 적용한 스크립트. ^^


소스 코드는 아래와 같습니다.

-- SQL Server 2005 이상에서사용할수있습니다.

-- DELETE문을사용하므로대용량테이블이존재한다면이스크립트는부적합할수있습니다.

-- Ctrl-Shift-M을눌러데이터베이스이름과삭제하지않을테이블을설정한후실행합니다.

 

USE <Database Name,sysname,>;

GO

 

SET NOCOUNT ON;

GO

 

DECLARE

    @nvcStmt nvarchar(max),

    @nvcIgnoreTables nvarchar(max);

 

DECLARE @tblTargetTables table (

    [object_id] int NOT NULL PRIMARY KEY,

    schemaName sysname NOT NULL,

    tableName sysname NOT NULL

);

 

DECLARE @tblIdentityTables table (

    tableName sysname NOT NULL,

    seed_value int NOT NULL,

    increment_value int NOT NULL,

    last_value int NULL

);

 

SET @nvcIgnoreTables = N'<삭제제외테이블을comma를구분자로나열,,>';

 

-- 삭제대상테이블정보를수집합니다.

INSERT @tblTargetTables ([object_id], schemaName, tableName)

SELECT T.[object_id], S.name, T.name

FROM sys.tables T

    INNER JOIN sys.schemas S ON T.[schema_id] = S.[schema_id]

WHERE T.type = 'U' AND NOT EXISTS (

    SELECT *

    FROM (

        SELECT LTRIM(RTRIM(SUBSTRING(

              N',' + @nvcIgnoreTables + N','

            , number + 1

            , CHARINDEX(N',', N',' + @nvcIgnoreTables + N',', number + 1) - number - 1

        ))) AS tableName

        FROM master.dbo.spt_values

        WHERE [type] = 'P' AND number < (DATALENGTH(N',' + @nvcIgnoreTables + N',') / 2)

            AND SUBSTRING(N',' + @nvcIgnoreTables + N',', number, 1) = N','

    ) S

    WHERE tableName = T.name

);

 

-- 삭제대상테이블의identity 속성컬럼정보를수집합니다.

INSERT @tblIdentityTables (tableName, seed_value, increment_value, last_value)

SELECT T.tableName, CAST(I.seed_value AS int), CAST(I.increment_value AS int)

    , CAST(I.last_value AS int)

FROM @tblTargetTables T

    INNER JOIN sys.identity_columns I ON T.[object_id] = I.[object_id];

 

-- CONSTRAINTTRIGGER를비활성화하는구문생성

SET @nvcStmt = N'DISABLE TRIGGER ALL ON DATABASE;

EXEC sp_MSForEachTable ''ALTER TABLE ? NOCHECK CONSTRAINT ALL'';

EXEC sp_MSForEachTable ''ALTER TABLE ? DISABLE TRIGGER ALL'';';

 

-- 테이블DELETE 구문생성

SELECT @nvcStmt = @nvcStmt + NCHAR(13) + NCHAR(10) +

    N'DELETE ' + QUOTENAME(schemaName) + N'.' + QUOTENAME(tableName) + N';'

FROM @tblTargetTables;

 

-- identity 속성의컬럼을초기화하는구문생성

SELECT @nvcStmt = @nvcStmt + NCHAR(13) + NCHAR(10) +

    N'DBCC CHECKIDENT(''' + tableName + ''', RESEED, ' +

    CASE

        WHEN last_value IS NULL THEN CAST(seed_value AS nvarchar(10))

        ELSE CAST(seed_value - increment_value AS nvarchar(10))

    END + N');'

FROM @tblIdentityTables;

 

SET @nvcStmt = @nvcStmt + '

EXEC sp_MSForEachTable ''ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL'';

EXEC sp_MSForEachTable ''ALTER TABLE ? ENABLE TRIGGER ALL'';

ENABLE TRIGGER ALL ON DATABASE;';

 

-- PRINT @nvcStmt;

 

EXEC sp_executesql @nvcStmt;

2009/08/10 12:16 2009/08/10 12:16
I. Sequel Safe에서 DBA로 지정된 사용자만이 모델을 수정할 수 있습니다.

먼저 Sequel Safe에 국한하여 다음과 같이 용어를 재 정의합니다.

  1. DBA
    1. SQLSafe.dbo.DBAs 테이블에 등록되어 있는 Login을 말합니다.
    2. 모델러 & SQL개발을 담당하는 sysadmin에 속한 사람을 등록합니다.

  2. SQLDeveloper
    1. 개발 네트워크의 개발 DB에 추가되어 있는 DB Role입니다.
    2. 개발 DB에 대해 db_owner 역할에 속하지만, 테이블과 뷰를 생성할 권한은 없습니다.
    3. SQL개발을 담당하는 사람이 이 Role에 속합니다.

  3. Developer
    1. 개발, 테스트 & QA 네크워크의 DB에 추가되어 있는 DB Role입니다.
    2. db_datareader와 db_datawriter 역할에 속합니다.
    3. 모든 SP, UDF, Trigger에 대한 View definition 권한을 가집니다.
    4. 모든 SP에 대한 Execute 권한을 가집니다.
    5. SPExecutor라는 User로 Impersonate (= 가장) 할 권한을 가집니다.
    6. SQL 서버와 연동하는 프로그램을 작성하는 개발자가 이 Role에 속합니다.

  4. AppServer
    1. 개발, 테스트 & QA, 프로덕트 네트워크의 DB에 추가되어 있는 DB Role입니다.
    2. 모든 SP, UDF, Trigger에 대한 View definition 권한을 가집니다.
    3. 모든 SP에 대한 Execute 권한을 가집니다.
    4. SPExecutor라는 User로 Impersonate (= 가장) 할 권한을 가집니다.
    5. SQL 서버에 접속하는 프로그램이 사용할 계정이 이 Role에 속합니다.

      사용자 삽입 이미지




SQLSafe.dbo.DBAs 테이블에 등록되지 않은 사용자가... 테이블이나 뷰에 대한 DDL문을 실행하면, 그 DDL문은 바로 롤백됩니다.


II. 모델 수정 작업은 DDL 스크립트 실행을 통해서만 가능합니다.

테이블 디자이너를 사용하여 모델을 수정할 수 없습니다.

만약 테이블 디자이너를 통해 테이블 변경이나 생성 작업을 한다면, 아래와 같은 에러 메세지가 출력됩니다.

사용자 삽입 이미지



이런 제약을 둔 가장 큰 이유는... DDL 트리거가 sp_rename을 캐치하지 못하기 때문입니다.

아시다시피 테이블 디자이너를 통해 테이블을 수정할 때 sp_rename이 종종 실행되는데... 이렇게 되면 테이블의 버전을 관리하지 못하게 되기 때문에 부득이 이런 제약을 넣었습니다.

따라서, 실행이 차단되어 있진 않지만 sp_rename을 직접 사용하는 일이 있어서는 안됩니다.



III. NOT NULL 속성의 컬럼을 추가하는 경우, 반드시 DEFAULT 제약 조건 사용

개발 DB에서는 테이블이 비어 있어서 NOT NULL 필드를 추가할 수 있었다해도... 배포하는 과정에서는 상황이 달라질 수 있기 때문입니다.

2009/08/10 12:14 2009/08/10 12:14
알고보면 기존 버전에서 계층형 설계에 사용하던 materialized path 개념과 같지만... 코드 작성은 훨씬 편해졌습니다.

이제 개념은 잡았으니... 메서드 목록만 적어 놓으면 될 듯...
GetAncestor()

현재 항목의 n번째 상위 항목을 나타내는 hierarchyid를 반환합니다.

child.GetAncestor(n)

GetDescendant()

부모의 자식 노드를 반환합니다.

parent.GetDescendant (child1, child2)

parent가 NULL인 경우 NULL을 반환합니다.
parent가 NULL이 아니고 child1과 child2가 모두 NULL인 경우 부모의 자식을 반환합니다.
parent와 child1이 NULL이 아니고 child2가 NULL인 경우 child1보다 큰 부모의 자식을 반환합니다.
parent와 child2가 NULL이 아니고 child1이 NULL인 경우 child2보다 작은 부모의 자식을 반환합니다.
parent, child1 및 child2가 NULL이 아닌 경우 child1보다 크고 child2보다 작은 모의 자식을 반환합니다.
child1이 NULL도 아니고 부모의 자식도 아닌 경우 예외가 발생합니다.
child2가 NULL도 아니고 부모의 자식도 아닌 경우 예외가 발생합니다.
child1이 child2보가 크거나 같으면 예외가 발생합니다.

GetLevel()

트리에서 노드의 깊이를 나타내는 정수를 반환합니다.

node.GetLevel()

GetRoot()

계층 트리의 루트를 반환합니다.

hierarchyid::GetRoot()

IsDescendantOf()  BOL의 설명이 잘 못 되어 있어 수정 (2009년 5월 BOL 기준)

자식이 현재 항목의 하위 항목일 경우 true를 반환합니다.

child.IsDescendantOf(parent)

GetReparentedValue()

oldRoot에서 newRoot 노드로 특정 노드의 부모 노드를 변경했을 때 특정 노드가 가져야야하는 새로운 노드를 반환합니다.

node.GetReparentedValue (oldRoot, newRoot)

hierarchyid <-> string 변환

ToString()
Parse()

T-SQL을 사용하여 호출할 수 없는 method

Read()
Write()

2009/08/10 12:11 2009/08/10 12:11
테이블에서 NULL 값을 허용하는 컬럼에 사용하는 옵션으로 SPARSE 가 있습니다. [SQL Server 2008]

SPARSE 컬럼에 NULL 값이 입력되면 저장 공간을 전혀 차지 하지 않지만, NULL이 아닌 값이 저장될 경우에는 4byte의 추가 공간을 필요로합니다.

BOL에서는 SPARSE 컬럼의 사용으로 인해 20% ~ 40% 정도의 공간이 절약될 수 있다면 SPARSE 컬럼을 사용하라고 권고하는군요.

아래 표는 SPARSE 컬럼을 사용했을 때 40%의 공간을 절약하기 위해 필요한 NULL 값 비율을 데이터 타입 별로 나타내고 있습니다.

데이터 타입

NULL 비율

bit                                                             

  98%  

tinyint

86%

smallint

76%

int

64%

bigint

52%

real

64%

float

52%

smallmoney

64%

money

52%

smalldatetime

64%

datetime

52%

uniqueidentifier

43%

date

69%

datetime2(0)

57%

datetime2(7)

52%

time(0)

69%

time(7)

60%

datetimetoffset(0)

52%

datetimetoffset (7)

49%

decimal / numeric(1,s)

60%

decimal / numeric(38,s)

42%

varchar / char

60%

nvarchar / nchar

60%

varbinary / binary

60%

xml

60%

hierarchyid

60%


※ SPARSE 지정이 불가능한 데이터 타입
 : geography, geometry, image, text, ntext, timestamp, UDT



용법 :

CREATE TABLE dbo.Demo (

        docID int IDENTITY NOT NULL PRIMARY KEY,

        title nvarchar(100) NOT NULL,

        spec nvarchar(10) SPARSE NULL,

        location int SPARSE NULL

);



SPARSE 컬럼은 NULL 이 아닌 값을 검색할 때 오버헤드가 있는데, 아래와 같이 NULL이 아닌 값만 필터링하여 인덱스를 생성하면 좋습니다.

CREATE INDEX IX_NN_Demo_location ON dbo.Demo (location) WHERE location IS NOT NULL;

2009/08/10 12:10 2009/08/10 12:10
오늘은 SQL Server 사용자 권한 정책에 대해 얘기 해 보겠습니다.

이하의 내용은 저희 회사에서 제가 사용하는 방법으로... 당연한 얘기지만 이 방법이 모든 경우에 적합하다고 볼 수는 없습니다.


첫번째 고민 : Windows 인증을 사용할까? SQL Server 인증을 사용할까?

일반적인 권고는 Windows 인증입니다.
아무래도 여러사람에 의해 공유되는 SQL Server 인증은 관리면이나 보안면에서 좋지 않을테니까요.
하지만 SQL Server 인증을 아예 사용하지 않는 것도... 현실적으론 어렵더군요.

- Windows 도메인 로그인을 가지고 있는 사람들... DBA, 개발자와 같은 이들에게는 Windows 인증을 사용합니다.
- 웹 서버, 미들웨어 서버 등의 어플리케이션 서버는 SQL Server 인증을 사용합니다.



두번째 고민 : 개발 DB에서 개발자의 권한은 어느 정도가 적당하지?

저는 데이터베이스에 접속해서 개발하는 사람을 세 부류로 나눴습니다.

- 개발 DBA : sysadmin입니다. 해당 데이터베이스에서 작업의 제약을 받지 않습니다.
- SQL 개발자 : db_owner이지만 SP, Function, Trigger를 제외한 다른 개체에대한 DDL문 사용 권한이 없습니다.
- 개발자 : data_reader & data_writer이고, 모든 SP에 대한 Execute와 View Definition 권한이 있습니다.

SQL 개발자와 개발자는 Database Role 개체로 생성한 후, 각 사람의 도메인 로그인을 해당 Role에 매핑하여 관리합니다.

IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE [name]=N'Developer' AND [type]='R')

    CREATE ROLE [Developer] AUTHORIZATION [dbo];

 

IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE [name]=N'SQLDeveloper' AND [type]='R')

    CREATE ROLE [SQLDeveloper] AUTHORIZATION [dbo];

GO

 

EXEC sp_addrolemember N'db_datareader', N'Developer';

EXEC sp_addrolemember N'db_datawriter', N'Developer';

EXEC sp_addrolemember N'db_owner', N'SQLDeveloper';

GO



[Developer] Role이 모든 SP에 대한 Execute 및 View Definition 권한을 갖도록 하기 위해... DDL 트리거를 만들고 아래 구문을 포함시킵니다. 즉, SP가 Create 될 때마다 아래 구문이 실행되도록 합니다.

GRANT VIEW DEFINITION ON OBJECT::[SP이름] TO [Devolper];

GRANT EXECUTE ON OBJECT::[SP이름] TO [Devolper];




세번째 고민 : 어플리케이션 서버용 SQL Server 로그인의 권한은?

사실 권한 정책 자체는 심플합니다. 특정 계정에 필요 이상의 권한을 주지 않는다.

그렇다면 어플리케이션 서버가 가져야하는 권한은 어느 정도일까요?

SP를 Execute할 수 있는 권한 이것 하나만 주고 싶군요.

저는 어플리케이션 서버의 로그인을 [AppServer]라는 Database Role에 속하도록 설정하고, [AppServer] Role은 모든 SP에 대해 Execute 권한을 가지도록 하고 있습니다.

[AppServer] Role이 모든 SP에 대한 Execute 권한을 갖도록 하기 위해... DDL 트리거를 만들고 아래 구문을 포함시킵니다.
 즉, SP가 Create 될 때마다 아래 구문이 실행되도록 합니다.

GRANT EXECUTE ON OBJECT::[SP이름] TO [AppServer];




네번째 고민 : SP를 Execute할 권한이 있는데도 SP 실행이 실패한다.

동적 쿼리를 사용하는 경우입니다.

SP에 대한 실행 권한이 있다해도 동적 쿼리에 포함된 개체에 대해 충분한 권한이 없다면 해당 SP는 실행이 안됩니다.

이런 경우 Execute AS 절을 사용하면 SP를 실행할 때만 충분한 권한이 있는 User로 가장 (impersonate) 시킬 수 있습니다.

SP를 실행할 때 사용할 로그인 및 사용자를 만들어 충분한 권한을 가지도록 하고 각 DB Role이 해당 사용자를 가장할 수 있는 권한을 줍니다.

이 때 생성한 로그인의 패스워드는 GUID를 생성하여 셋팅하는데...
이유는... 누구도 이 계정으로 로그인할 일이 없기 때문입니다.

오로지 SP 실행을 위한 계정일 뿐입니다.

DECLARE @vchPW varchar(50);

 

SET @vchPW = NEWID();

 

IF NOT EXISTS (SELECT * FROM sys.sql_logins WHERE [name] = N'SPExecutor')

    EXEC ('CREATE LOGIN [SPExecutor] WITH PASSWORD=''' + @vchPW + ''', DEFAULT_DATABASE=master;');

GO

 

IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE [name]=N'SPExecutor' AND [type]='S')

    CREATE USER [SPExecutor] FOR LOGIN SPExecutor WITH DEFAULT_SCHEMA=[dbo];

GO

 

EXEC sp_addrolemember 'db_owner', N'SPExecutor';

GO

 

GRANT IMPERSONATE ON USER::SPExecutor TO AppServer;

GRANT IMPERSONATE ON USER::SPExecutor TO Developer;

GRANT IMPERSONATE ON USER::SPExecutor TO SQLDeveloper;

GO




다섯번째 고민 : Execute AS 절을 사용했더니, 데이터베이스 간의 개체 참조가 되지 않는다.

모듈 안에서 Execute AS 절을 사용하는 경우, 다른 데이터베이스에 있는 개체를 참조할 수 없게 되는 문제가 생깁니다.
보안 상의 이슈로 데이터베이스간의 소유권 체인을 불허하는 것이 Default이기 때문이죠.

데이터베이스간 소유권 체인을 허용하는 것은... 상황에 따라 문제가 될 수도 있고 그렇지 않을 수도 있습니다.

문제가 되지 않는다면 TRUSTWORTHY 옵션을 설정하여 데이터베이스간의 소유권 체인을 허용할 수 있는데... 이렇게 하면 Execute AS 절을 사용하더라도 다른 데이터베이스의 개체를 참조할 수 있습니다.
(물론 다른 데이터베이스에도 SPExecutor가 User로 등록되어 있어야 합니다.)

ALTER DATABASE [DB이름] SET TRUSTWORTHY ON;




Sequel Safe에서는 이상의 셋팅이 포함되어 있습니다.
2009/08/10 12:08 2009/08/10 12:08
SQL Server 2008 온라인 설명서가 업데이트 되었습니다.

아래의 경로에서 다운받으실 수 있습니다.

Microsoft SQL Server 2008 온라인 설명서(2009년 5월)
http://www.microsoft.com/downloads/details.aspx?displaylang=ko&FamilyID=765433f7-0983-4d7a-b628-
0a98145bcb97

좋은 하루 되세요.
2009/08/10 10:26 2009/08/10 10:26

어떤 기준으로 선정했는지는 모르겠습니다.
The Blog Joint.com list of the Top 10 open source programs. I guarantee that most of you used some of these programs in the past, and if you haven’t you probably will use it in the future and if you know any programming you can make it even better. Thanks to all those people working hard in the open source community.
10. eMule
emule.gif
eMule is a filesharing client which is based on the eDonkey2000 network but offers more features than the standard client. The most downloaded program on sourceforge.net.
9. Audacity
audacity.jpg
Audacity is a free cross platform digital audio editor. Audacity is extremely popular in the podcasting world due to its wide availability, its multiplatform support, and free pricing.

8. Creative Commons

cc.jpg
The Creative Commons (CC) is a non-profit organization devoted to expanding the range of creative work available for others legally to build upon and share.

7. Ogg
ogg.jpg
Ogg is a patent-free, fully open multimedia bitstream container format designed for efficient streaming and file compression. The term “ogg” often refers to the audio file format Ogg Vorbis, that is, Vorbis-encoded audio in an Ogg container. Other prominent components of Ogg are its video codec Theora, and the human speech audio compression format, Speex.

6. PHP
php-logo.jpg
PHP is an open-source, reflective programming language. Originally designed as a high-level tool for producing dynamic web content, PHP is used mainly in server-side applications.

5. Wiki
wiki_logo.jpg
The wiki software is a type of website that allows users to add, remove, or otherwise edit and change all content very quickly and easily, sometimes without the need for registration. This ease of interaction and operation makes a wiki an effective tool for collaborative writing.

4. Azureus
real_azureus.jpg
Azureus is a Java based BitTorrent client. It currently supports Windows, Mac OS X, Linux and Unix. It is one of the most popular bit-torrent clients

3. Open Office
logonew.gif
OpenOffice.org is a free and open source office suite, including word processor, spreadsheet, presentation, vector drawing and database components. It is available for many different platforms, including Microsoft Windows, Unix-like systems with the X Window System including GNU/Linux, BSD, Solaris and Mac OS X. It is intended to be compatible with, and compete with, Microsoft Office. It supports the OpenDocument standard for data interchange, and can be used at no cost.

2. Linux
Linux-logo.jpg
Linux (also known as GNU/Linux) is a computer operating system. It is one of the most prominent examples of open source development and free software; unlike proprietary operating systems such as Windows or Mac OS, all of its underlying source code is available to the public for anyone to freely use, modify, and redistribute. Some of the most popular distributions are Ubuntu, Mandriva, Red Hat, and Suse.

1. Firefox
firefox.jpg
Mozilla Firefox is a free, open source, cross-platform, graphical web browser developed by the Mozilla Corporation and hundreds of volunteers. Firefox includes an integrated pop-up blocker, tabbed browsing, live bookmarks, support for open standards, and an extension mechanism for adding functionality. Although other browsers have some of these features, Firefox became the first such browser to include them all and achieve wide adoption. PCWorld reviewed Firefox as the best product of 2005.

Some that didn’t make the list but worth mentioning.

Apache Server

Apache HTTP Server is a free software/open source HTTP web server for Unix-like systems (BSD, Linux, and UNIX systems), Microsoft Windows, Novell NetWare and other platforms.

MySQL

MySQL is popular for web applications such as MediaWiki or PHP-Nuke and acts as the database component of the LAMP and WAMP platforms (Linux/Windows-Apache-MySQL-PHP/Perl/Python). Its popularity as a web application is closely tied to the popularity of PHP, which is often combined with MySQL and nicknamed the Dynamic Duo.

출처 : http://theblogjoint.com/2006/06/12/top-10-open-source-programs/

2009/08/10 09:57 2009/08/10 09:57
포토샵을 빠르게 실행하기 위해서는 불필요하게 메모리를 잡아먹는 것을 최소화 하는 것이 도움이 된다. 잘 사용하지 않는 플러그인이나 프리셋을 제외하고 실행을 시키고 폰트도 정리해서 사용할 필요가 있다. 이번에는 레이어 팔레트에 보이는 썸네일의 크기를 최소로 줄여서 사용하는 방법을 소개하고자 한다.

사용자 삽입 이미지
레이어 팔레트의 썸네일 크기를 최소로 줄여서 사용

레이어 팔레트 제일 오른쪽 메뉴를 클릭하면 Panel Option 이란 메뉴가 있다. 이것을 선택하면 아래와 같이 팔레트의 썸네일 크기를 선택할 수 있는데 가장 작은 썸네일을 선택하고 사용하면 메모리를 절약하는 방법이 된다. 메모리가 정말 부족할 경우에는 None을 선택하고 사용을 하는 것도 괜찮다.

폰트 관리하기

잘 사용하지 않는 폰트를 시스템 폰트 폴더에서 제외하는 방법을 사용하는 것도 괜찮다. 유료 프로그램으로는 Suitcase for Windows 란 윈도우용 폰트 관리 프로그램이 있다. 그 외에도 폰트 관리 프로그램을 이용하여 잘 사용하지 않는 폰트를 비활성화 시키면 포토샵을 조금 더 가볍게 사용할 수 있다.
2009/08/10 09:54 2009/08/10 09:54

1.데이터와 비즈니스 어플리케이션을 잘 알아야 한다.

동일한 정보는 다른 비즈니스 데이터 원천으로부터 검색될 수 있다. 이러한 원천에 익숙해야 한다. 당신은 당신의 데이터베이스 안의 데이터의 크기와 분포를 반드시 알아야 한다. 또한 SQL을 작성하기 전에 비즈니스 개체 안의 관계와 같은 데이터 모델을 전체적으로 이해해야 한다. 이러한 이해는 당신이 여러 테이블에 서 정보를 검색하는데 있어서 보다 좋은 쿼리를 작성할 수 있다. DESIGNER/2000 과 같은 CASE TOOLS은 다른 비즈니스와 데이터베이스 객체사이의 관계를 문서화 하는데 좋은 역할을 한다.

2.실제 데이터를 가지고 당신의 쿼리를 검사하라.

대부분의 조직은 개발, 검사, 제품의 3가지 데이터베이스 환경을 가진다. 프로그래머는 어플리케이션을 만들고 검사하는데 개발 데이터베이스 환경을 사용하는데, 이 어플리케이션이 제품 환경으로 전환되기 전에 프로그래머와 사용자에 의해 검사 환경하에서 보다 엄격하게 검토되어야 한다.



SQL이 검사 환경하에서 테스트될 때, 검사 데이터베이스가 가지고 있는 데이터는 제품 데이터베이스를 반영해야 한다. 비실제적인 데이터를 가지고 테스트된 SQL문은 제품 안에서는 다르게 작동할 수 있다. 엄격한 테스트를 보장하기 위해서는, 검사 환경하에서의 데이터 분포는 반드시 제품 환경에서의 분포와 밀접하게 닮아야 한다.

3.동일한 SQL을 사용하라.

가능한한 BIND VARIABLE, STORED PROCEDURE, PACKAGE의 이점을 활용하라.


IDENTICAL SQL문의 이점은 PARSING이 불필요하기에 데이터베이스 서버안에서 메모리 사용의 축소와 빠른 수행을 포함한다. 예로서 아래의 SQL 문은 IDENTICAL하지 않다.

SELECT * FROM EMPLOYEE WHERE EMPID = 10;
SELECT * FROM EMPLOYEE WHERE EMPID = 10;
SELECT * FROM EMPLOYEE WHERE EMPID = 20;


그러나 I_EMPID라고 이름 주어진 BIND VARIABLE을 사용하면 SQL 문은 이렇게 된다.



SELECT * FROM EMPLOYEE WHERE EMPID = :I_EMPID;

4.주의 깊게 인덱스를 사용하라.

테이블상에 모든 필요한 인덱스는 생성되어야 한다. 하지만 너무 많은 인덱스는 성능을 떨어뜨릴 수 있다. 그러면 어떻게 인덱스를 만들 칼럼을 선택해야 하는가?

*최종 사용자에 의해 사용되는 어플리케이션 SQL과 쿼리의 WHERE 절에서 빈번하게 사용되는 칼럼에 인덱스를 만들어야 한다.

*SQL 문에서 자주 테이블을 JOIN하는데 사용되는 칼럼은 인덱스되어야 한다.

*같은 값을 가지는 ROW가 적은 비율을 가지는 칼럼에 인덱스를 사용하라.

*쿼리의 WHERE 절에서 오직 함수와 OPERATOR로 사용되는 칼럼에는 인덱스를 만들면 안된다.

*자주 변경되거나 인덱스를 만들때 얻는 효율성보다 삽입, 갱신, 삭제로 인해 잃는 효율성이 더 큰 칼럼에는 인덱스를 만들면 안된다. 이러한 OPERATION은 인덱스를 유지하기 위한 필요 때문에 느려진다.

*UNIQUE 인덱스는 더 나은 선택성 때문에 NONUNIQUE 인덱스보다 좋다. PRIMARY KEY 칼럼에 UNIQUE 인덱스를 사용한다. 그리고 FOREIGN KEY 칼럼과 WHERE 절 에서 자주 사용되는 칼럼에는 NONUNIQUE 인덱스를 사용한다.

5.가용한 인덱스 PATH를 만들어라.

인덱스를 사용하기 위해서는 기술한 SQL문을 이용할 수 있는 식으로 SQL을 작성하라. OPTIMIZER는 인덱스가 존재하기 때문에 인덱스를 사용하는 ACESS PATH 를 사용할 수 없다. 따라서 ACCESS PATH는 반드시 SQL이 사용할 수 있게 만들어 져야 한다. SQL HINT를 사용하는 것은 인덱스 사용을 보증해주는 방법중 하나이다. 특정 ACCESS PATH를 선택하기 위한 다음의 힌트를 참고 하라

6.가능하면 EXPLAIN과 TKPROF를 사용하라.

만약 SQL문이 잘 다듬어지지 않았다면 비록 오라클 데이터베이스가 잘 짜여져 있어도 효율성이 떨어질 것이다. 이럴 경우 EXPLAIN TKPROF에 능숙해져야 한다. EXPALIN PLAN은 SQL이 사용하는 ACCESS PATH를 발견할 수 있게 해주고 TKPROF는 실제 PERFORMANEC의 통계치를 보여준다. 이 TOOL은 오라클 서버 소프트웨어에 포함되어 있고 SQL의 성능을 향상시켜 준다.

7.OPTIMIZER를 이해하라.

SQL은 RULE-BASED나 COST-BASED중 하나를 이용해서 기동된다.기존의 소프트웨어는 RULE BASED 방식을 채택하고 있다. 그리고 많은 오라클 소프트웨어가 이러한 방식을 오랫동안 사용해 왔다. 그러나 새로 출시된 소프트웨어에 대해서는 COST BASED 방식의 OPTIMIZER를 고려해야 한다. 오라클은 새로 출시되는 프로그램을 COST BASED방식으로 업그레이드 시켜왔으며 이러한 방식은 시스템을 훨씬 더 안정적으로 만들었다. 만약 COST BASED방식의 OPTIMIZER를 사용한다면 반드시 ANALYZE 스키마를 정기적으로 사용해야 한다. ANALYZE스키마는 데이터베이스 통계를 데이터 사전 테이블에 기록하는 역할을 수행하며 그렇게 되면 COST BASED OPTIMIZER가 그것을 사용하게 된다. SQL은 COST BASED OPTIMIZER를 사용할 때만 잘 조정될 수 있다. 만약
RULE BASED에서 COST BASED로 바꾸고 싶다면 데이터베이스를 사용하는 모든 소프트웨어의 모든 SQL문의 성능을 평가해 보아야 한다.

8.지엽적으로 동작하더라도 전역적으로 생각하라

항상 주의할 것은 하나의 SQL문을 조정하기 위해 생긴 데이터베이스안의 변화는 다른 응용프로그램이나 다른 사용자가 이용하는 다른 명령문에 영향을 미친다는 사실이다.

9.WHERE절은 매우 중요하다.

비록 인덱스가 가용하다고 해도 다음의 WHERE 절은 그 인덱스 ACCESS PATH 를 사용하지 않는다.(즉 COL1 과 COL2는 같은 테이블에 있으며 인덱스는 COL1에 만들어진다.)

COL1 > COL2
COL1 < COL2
COL1 > = COL2
COL1 <= COL2
COL1 IS NULL
COL1 IS NOT NULL.


인덱스는 NULL값을 갖는 칼럼에는 ROWID를 저장하지 않는다. 따라서 NULL값을 갖는 ROW를 검색할 때는 인덱스를 사용하지 못한다.

COL1 NOT IN (VALUE1, VALUE2 )
COL1 != EXPRESSION
COL1 LIKE ''%PATTERN''.

이럴 경우 THE LEADING EDGE OF THE INDEX(?) 는 작동되지 않고 인덱스가 사용되지 못하게 한다. 한편 COL1 LIKE ''PATTERN %''이나 COL1 LIKE ''PATTERN % PATTERN%'' 는 한정된 인덱스 스캔을 수행하기 때문에 인덱스를 사용할 수 있다.

NOT EXISTS SUBQUERY
EXPRESSION1 = EXPRESSION2.


인덱스된 컬럼을 포함하는 표현(EXPRESSION), 함수, 계산(CALCULATIONS)은 인덱스를 사용하지 못한다. 다음의 예에서 보면 UPPER SQL 함수를 사용하면 인덱스 스캔을 사용할 수 없고 FULL TABLE SCAN으로 끝나고 만다.

SELECT DEPT_NAME
FROM DEPARTMENT
WHERE UPPER(DEPT_NAME) LIKE ''SALES%'';


10.레코드 필터링을 위해서는 HAVING보다는 WHERE를 사용하라.

인덱스가 걸려있는 칼럼에는 GROUP BY와 같이 HAVING절을 사용하지 마라. 이 경우 인덱스는 사용되지 않는다. 또한 WHERE절로 된 ROW를 사용하지 마라. 만약 EMP테이블이 DEPTID컬럼에 인덱스를 가지고 있다면 다음 질의는 HAVING 절을 이용하지 못한다.

SELECT DEPTID,
SUM(SALARY)
FROM EMP
GROUP BY DEPTID
HAVING DEPTID = 100;

그러나 같은 질의가 인덱스를 사용하기 위해 다시 씌여질 수 있다.

SELECT DEPTID,
SUM(SALARY)
FROM EMP
WHERE DEPTID = 100
GROUP BY DEPTID;


11. WHERE 절에 선행 INDEX 칼럼을 명시하라.

복합 인덱스의 경우, 선행 인덱스가 WHERE절에 명시되어 있다면 쿼리는 그 인덱스 를 사용할 것이다. 다음의 질의는 PART_NUM과 PRODUCT_ID 칼럼 에 있는 PRIMARY KEY CONSTRAINT에 기초한 복합 인덱스를 이용할 것이다.

SELECT * FROM PARTS WHERE PART_NUM = 100;

반면, 다음의 쿼리는 복합인덱스를 사용하지 않는다.

SELECT * FROM PARTS WHERE PRODUCT_ID = 5555;

같은 요청(REQUEST)이 인덱스를 이용하기 위해 다시 씌어 질 수 있다. 다음 질의의 경우, PART_NUM컬럼은 항상 0 보다 큰 값을 가질것이다.

SELECT * FROM PARTS WHERE PART_NUM > 0 AND PRODUCT_ID = 5555;

12.인덱스 SCAN과 FULL TABLE SCAN을 평가하라.

한 행(ROW)의 15% 이상을 검색하는 경우에는 FULL TABLE SCAN이 INDEX ACESS PATH보다 빠르다. 이런 경우, SQL이 FULL TABLE SCAN을 이용할 수 있도록 여러분 스스로 SQL을 작성하라. 다음의 명령문은 비록 인덱스가 SALARY COLUMN에 만들어져 있어도 인덱스 SCAN을 사용하지 않을 것이다. 첫 번째 SQL 에서, FULL HINT를 사용한다면 오라클은 FULL TABLE SCAN을 수행할 것이다. 인덱 스의 사용이 나쁜 점이 더 많다면 아래의 기술을 이용해서 인덱스 수행을 막을
수 있다.

SELECT * --+FULL FROM EMP WHERE SALARY = 50000;
SELECT * FROM EMP WHERE SALARY+0 = 50000;

다음의 명령문은 비록 인덱스가 SS# COLUMN에 있어도 인덱스 SCAN을 사용하지 않을 것이다.

SELECT * FROM EMP WHERE SS# || '' '' = ''111-22-333'';

오라클이 불분명한 데이터 변환을 수행해야 하는 경우 인덱스가 항상 사용되지 않는 것은 아니다. 다음의 예를 보면, EMP 칼럼에 있는 SALARY는 숫자형 칼럼이고 문자형이 숫자값으로 변환된다.

SELECT * FROM EMP WHERE SALARY = ''50000'';

테이블의 행이 15%이거나 그보다 작을 경우 인덱스 스캔은 보다 잘 수행 될 것이다. 왜냐 하면 인덱스 스캔은 검색된 행(ROW)하나 하나 마다 다중의 논리적인 읽기 검색(READ)을 할 것이기 때문이다. 그러나 FULL TABLE SCAN은 하나의 논리적인 읽기 검색 영역 안의 BLOCK에 있는 모든 행들을 읽을 수 있다. 그래서 테이블의 많은 행들에 접근해야 하는 경우에는 FULL TABLE SCAN이 낫다. 예로 다음의 경우를 보자. 만약 EMP TABLE과 그 테이블의 모든 인덱스에 대해 ANALYZE라
는 명령어가 수행된다면, 오라클은 데이터 사전인 USER_TABLES와 USER_INDEXES에 다음과 같은 통계치를 산출해 낸다.

TABLE STATISTICS:
NUM_ROWS = 1000
BLOCKS = 100

INDEX STATISTICS:

BLEVEL = 2
AVG_LEAF_BLOCKS_PER_KEY = 1
AVG_DATA_BLOCKS_PER_KEY = 1


이러한 통계치 에 근거해서, 아래에 보이는 것이 각각의 다른 SCAN에 대한 논리
적인 읽기(READ)-즉 ACESS된 BLOCK이 될 것이다.

USE OF INDEX TO RETURN ONE ROW = 3

(BLEVEL+(AVG_LEAF_BLOCKS_PER_KEY - 1) + AVG_DATA_PER_KEY

FULL TABLE SCAN = 100
(BLOCKS)


USE OF INDEX TO RETURN ALL ROWS = 3000
(NUM_ROWS * BLOCKS ACCESSED TO RETURN ONE ROW USING INDEX)


13. 인덱스 스캔에 ORDER BY를 사용하라.

오라클의 OPTIMIZER는 , 만약 ORDER BY라는 절이 인덱스된 칼럼에 있다면 인덱스 스캔을 사용할 것이다. 아래의 질의는 이러한 점을 보여 주는 것인데 이 질의는 비록 그 칼럼이 WHERE 절에 명시되어 있지 않다고 해도 EMPID컬럼에 있는 가용한 인덱스를 사용할 것이다. 이 질의는 인덱스로부터 각각의 ROWID를 검색하고 그 ROWID를 사용하는 테이블에 접근한다.

SELECT SALARY FROM EMP ORDER BY EMPID;

만약 이 질의가 제대로 작동하지 않는다면, 당신은 위에서 명시되었던 FULL HINT 를 사용하는 같은 질의를 다시 작성함으로써 다른 대안들을 이용해 볼 수 있다.

14. 자신의 데이터를 알아라

내가 이미 설명한 것처럼, 당신은 당신의 데이터를 상세하게 알고 있어야 한다.
예를 들어 당신이 BOXER라는 테이블을 가지고 있고 그 테이블이 유일하지 않은 인덱스를 가진 SEX라는 컬럼과 BOXER_NAME이라는 두 개의 테이블을 가지고 있다고 가정해 보자. 만약 그 테이블에 같은 수의 남자, 여자 복서가 있다면 오라클이 FULL TABLE SCAN을 수행하는 경우 다음의 질의가 훨씬 빠를 것이다.

SELECT BOXER_NAME FROM BOXER WHERE SEX = ''F'';

당신은 다음과 같이 기술함으로써 질의가 FULL TABLE SCAN을 수행하는지를 확실 하게 해 둘 수 있다.

SELECT BOXER_NAME --+ FULL FROM BOXER WHERE SEX = ''F'';

만약 테이블에 980 명의 남성 복서 데이터가 있다면, 질의는 인덱스 SCAN으로 끝나기 때문에 아래형식의 질의가 더 빠를 것이다.

SELECT BOXER_NAME --+ INDEX (BOXER BOXER_SEX) FROM BOXER


WHERE SEX = ''F'';

이 예는 데이터의 분포에 대해 잘 알고 있는 것이 얼마나 중요한 가를 예시해 준다. 데이터가 많아지고(GROW) 데이터 분포가 변화하는 것처럼 SQL 도 매우 다양할 것이다. 오라클은 OPTIMIZER 가 테이블에 있는 데이터의 분포를 잘 인식하고 적절한 실행 계획을 선택하도록 하기 위해 오라클 7.3 에 HISTOGRAMS라는 기능을 추가했다.

15. KNOW WHEN TO USE LARGE-TABLE SCANS.

작거나 큰 테이블에서 행들을 추출할 때, 전체 테이블의 검색은 인텍스를 사용한 검색보다 성능이 더 좋을 수도 있다. 매우 큰 테이블의 인덱스 검색은 수많은 인덱스와 테이블 블록의 검색이 필요할수도 있다. 이러한 블록들이 데이터베이스 버퍼 캐쉬에 이동되면 가능한한 오래도록 그곳에 머무른다. 그래서 이러한 블록들이 다른 질의등에 필요하지 않을 수도 있기 때문에, 데이터베이스 버퍼 히
트 비율이 감소하며 다중 사용자 시스템의 성능도 저하되기도 한다. 그러나 전체 테이블 검색에 의해서 읽혀진 블록들은 데이터베이스 버퍼 캐쉬에서 일찍 제 거가 되므로 데이터베이스 버퍼 캐쉬 히트 비율은 영향을 받지 않게 된다.

16. MINIMIZE TABLE PASSES.

보통, SQL질의시 참조하는 테이블의 숫자를 줄임으로 성능을 향상시킨다. 참조
되는 테이블의 숫자가 적을수록 질의는 빨라진다. 예를 들면 NAME, STATUS,
PARENT_INCOME, SELF_INCOME의 네개의 컬럼으로 이루어진 학생 테이블
에서 부모님에 의존하는 학생과 독립한 학생의 이름과 수입에 대해서 질의시, 이
학생 테이블을 두번 참조하여 질의하게 된다.



SELECT NAME, PARENT_INCOME FROM STUDENT WHERE STATUS = 1
UNION


SELECT NAME, SELF_INCOME FROM STUDENT WHERE STATUS = 0;



( NAME이 프라이머리 키이며, STATUS는 독립한 학생의 경우는 1, 부모님에
의존적인 학생은 0으로 표시한다)
위의 같은 결과를 테이블을 두번 참조하지 않고도 질의 할 수 있다.

SELECT NAME,PARENT_INCOME*STATUS + SELF_INCOME(1-STATUS)
FROM STUDENT;


17. JOIN TABLES IN THE PROPER ORDER.

다수의 테이블 조인시 테이블들의 조인되는 순서는 매우 중요하다. 전반적으로, 올바른 순서로 테이블이 조인되었다면 적은 수의 행들이 질의시 참조된다. 언제나 다수의 조인된 테이블들을 질의시 우선 엄격하게 조사하여 행들의 숫자를 최대한으로 줄인다. 이러한 방법으로 옵티마이저는 조인의 차후 단계에서 적은 행들을 조사하게 된다. 뿐만 아니라, 여러 조인을 포함하는 LOOP JOIN에서는 가장 먼저 참조되는 테이블(DRIVING TABLE)이 행들을 최소한으로 리턴하도록 해야 한다. 그리고, 마스터와 상세 테이블 조인시에는(예를 들면 ORDER & ORDER LINE ITEM TABLES) 마스터 테이블을 먼저 연결 시켜야 한다.



규칙에 근거한 옵티마이저의 경우에는 FROM CLAUSE의 마지막 테이블이 NESTED LOOP JOIN의 DRIVING TABLE이 된다. NESTED LOOP JOIN이 필요한 경우에는 LOOP의 안쪽의 테이블에는 인텍스를 이용하는 것을 고려할 만하다. EXPLAIN PLAN과 TKPROF는 조인 타입, 조인 테이블 순서, 조인의 단계별 처리된 행들 의 숫자들을 나타낸다.



비용에 근거한 옵티마이저의 경우에는 WHERE CLAUSE에 보여지는 테이블의 순서는 옵티마이저가 가장 최적의 실행 계획을 찾으려고 하는 것과 상관 없다. 조인되는 테이블의 순서를 통제하기 위해서 ORDERED HINT를 사용하는 것이 낫다.

SELECT ORDERS.CUSTID, ORDERS.ORDERNO,
ORDER_LINE_ITEMS.PRODUCTNO --+ORDERED
FROM ORDERS, ORDER_LINE_ITEMS
WHERE ORDERS.ORDERNO = ORDER_LINE_ITEMS.ORDERNO;


18. USE INDEX-ONLY SEARCHES WHEN POSSIBLE.

가능하다면, 인덱스만을 이용하여 질의를 사용하라. 옵티마이저는 오직 인덱스만을 찾을 것이다. 옵티마이저는 SQL을 만족시키는 모든 정보를 인덱스에서 찾을 수 있을 때, 인덱스만을 이용할 것이다. 예를들면, EMP테이블이 LANME과 FNAME의 열에 복합 인덱스를 가지고 있다면 다음의 질의는 인덱스만은 이용할 것이다.

SELECT FNAME FROM EMP WHERE LNAME = ''SMITH'';

반면에 다음의 질의는 인덱스와 테이블을 모두 참조한다.

SELECT FNAME , SALARY FROM EMP WHERE LNAME = ''SMITH'';

19. REDUNDANCY IS GOOD.

WHERE CLAUSE에 가능한한 많은 정보를 제공하라. 예를 들면 WHERE COL1 = COL2 AND COL1 = 10이라면 옵티마이저는 COL2=10이라고 추론하지만, WHERE COL1 = COL2 AND COL2 = COL3이면 COL1=COL3이라고 초론하지는 않는다.

20. KEEP IT SIMPLE, STUPID.

가능하면 SQL문을 간단하게 만들라. 매우 복잡한 SQL문은 옵티마이저를 무력화시킬 수도 있다. 때로는 다수의 간단한 SQL문이 단일의 복잡한 SQL문보다 성능이 좋을 수도 있다. 오라클의 비용에 근거한 옵티마이저는 아직은 완벽하지 않다. 그래서 EXPLAIN PLAN에 주의를 기울여야 한다. 여기서 비용이란 상대적인 개념이기에 정확히 그것이 무엇을 의미하는지 알지 목한다. 하지만 분명한 것은 적은 비용이 보다 좋은 성능을 의미한다는 것이다.



종종 임시 테이블을 사용하여 많은 테이블들을 포함하는 복잡한 SQL 조인을 쪼개는 것이 효율적일 수도 있다. 예를 들면, 조인이 대량의 데이터가 있는 8개의 테이블을 포함할 때, 복잡한 SQL을 두 세개의 SQL로 쪼개는 것이 낫을 수 있다. 각각의 질의는 많아야 네개정도의 테이블들을 포함하며 그 중간 값을 저장 하는 것이 낫을 수 있다.

21. YOU CAN REACH THE SAME DESTINATION IN DIFFERENT WAYS.

많은 경우에, 하나 이상의 SQL문은 의도한 같은 결과를 줄 수 있다. 각각의 SQL은 다른 접근 경로를 사용하며 다르게 수행한다. 예를들면, MINUS(-) 산술자는 WHERE NOT IN (SELECT ) OR WHERE NOT EXISTS 보다 더 빠르다.


예를들면, STATE와 AREA_CODE에 각각 다른 인덱스가 걸려 있다. 인덱스에도 불구하고 다음의 질의는 NOT IN의 사용으로 인해 테이블 전체를 조사하게 된다.



SELECT CUSTOMER_ID FROM CUSTOMERS WHERE STATE IN (''VA'', ''DC'', ''MD'')
AND AREA_CODE NOT IN (804, 410);


그러나 같은 질의가 다음 처럼 쓰여진다면 인덱스를 사용하게 된다.



SELECT CUSTOMER_ID FROM CUSTOMERS WHERE STATE IN (''VA'', ''DC'', ''MD'')
MINUS SELECT CUSTOMER_ID FROM CUSTOMERS WHERE AREA_CODE IN (804, 410);

WHERE절에 OR을 포함한다면 OR대신에 UNION을 사용할 수 있다. 그래서, SQL 질의를 수행하기 전에 먼저 실행계획을 조심스럽게 평가해야 한다. 이러한 평가는 EXPLAIN PLAN AND TKPROF를 이용하여 할 수 있다.

22. USE THE SPECIAL COLUMNS.

ROWID AND ROWNUM 열을 이용하라. ROWID를 이용하는 것이 가장 빠르다.
예를들면, ROWID를 이용한 UPDATE는 다음과 같다.

SELECT ROWID, SALARY INTO TEMP_ROWID, TEMP_SALARY FROM EMPLOYEE;

UPDATE EMPLOYEE SET SALARY = TEMP_SALARY * 1.5


WHERE ROWID = TEMP_ROWID;

ROWID값은 데이터베이스에서 언제나 같지는 않다. 그래서, SQL이나 응용 프로그램이용시 ROWID값을 절대화 시키지 말라. 리턴되는 행들의 숫자를 제한시키기위해 ROWNUM을 이용하라. 만약에 리턴되는 행들을 정확히 모른다면 리턴되는 행들의 숫자를 제한하기위해 ROWNUM을 사용하라
다음의 질의는 100개 이상의 행들을 리턴하지는 않는다.



SELECT EMPLOYE.SS#, DEPARTMENT.DEPT_NAME
FROM EMPLOYEE, DEPENDENT
WHERE EMPLOYEE.DEPT_ID = DEPARTMENT.DEPT_ID
AND ROWNUM < 100;


23.함축적인 커서대신 명시적인 커서를 사용하라.

함축적 커서는 여분의 FETCH를 발생시킨다. 명시적 커서는 DECLARE, OPEN, FETCH와 CLOSE CURSOR문을 사용하여 개발자에 의해서 생성된다. 함축 커서는 DELETE, UPDATE, INSERT와 SELECT문을 사용하면 오라클에 의해서 생성된다.

24.오라클 병렬 쿼리 옵션을 찾아서 이용하라.

병렬 쿼리 옵션을 사용하면, 보다 빠른 성능으로 SQL을 병렬로 실행할 수 있다.
오라클 7에서는, 오직 FULL TABLE SCAN에 기반한 쿼리만이 병렬로 수행될 수 있다.
오라클 8에서는, 인덱스가 분할되어있다면 INDEXED RANGE SCANS에 기반한 쿼리도 병렬로 처리될 수 있다. 병렬 쿼리 옵션은 다수의 디스크 드라이버를 포함하는 SMP와 MPP SYSTEM에서만 사용될 수 있다.

오라클 서버는 많은 우수한 특성을 가지고 있지만, 이러한 특성의 존재만으로는 빠른 성능을 보장하지 않는다. 이러한 특성을 위해서 데이터베이스를 조정해야하며 특성을 이용하기 위해 특별하게 SQL을 작성해야 한다. 예를 들면, 다음의 SQL은 병렬로 수행될 수 있다.

SELECT * --+PARALLEL(ORDERS,6) FROM ORDERS;

25. 네트웍 소통량을 줄이고 한번에 처리되는 작업량을 늘려라.

ARRAY PROCESSING과 PL/SQL BLOCK을 사용하면 보다 나은 성능을 얻을 수 있고 네트웍 소통량을 줄인다. ARRAY PROCESSING은 하나의 SQL문으로 많은 ROW를 처리할 수 있게 한다. 예를 들면, INSERT문에서 배열을 사용하면 테이블내의 1,000 ROW를 삽입할 수 있다. 이러한 기술을 사용하면 주요한 성능 향상을 클라이언트/서버와 배치시스템에서 얻어질 수 있다.

복합 SQL문은 과도한 네트웍 소통을 유발할 수 있다. 그러나 만일 SQL문이 단일 PL/SQL 블록안에 있다면, 전체 블록은 오라클 서버에 보내져서 그곳에서 수행되고, 결과는 클라이언트의 APPLICATION에게 돌아온다.

개발자와 사용자는 종종 SQL을 데이터베이스에서 데이터를 검색하고 전송하는 간단한 방법으로 사용한다. 때때로 직접적으로 SQL을 작성하지 않고 코드 발생기를 사용하여 작성한 APPLICATION은 심각한 성능 문제를 일으킨다. 이러한 성능감퇴는 데이터베이스가 커지면서 증가한다.

SQL은 유연하기 때문에, 다양한 SQL문으로 같은 결과를 얻을 수 있다. 그러나 어떤 문은 다른 것보다 더 효율적이다. 여기에 기술된 팁과 기법을 사용하면 빠르게 사용자에게 정보를 제공할 수 있는 APPLICATION과 리포트를 얻을 수 있다.

2009/08/07 21:56 2009/08/07 21:56
<%
With Dbcon
.CommandTimeout = 0
End With
Server.ScriptTimeOut = 3600*10*10
'Set fs = Server.CreateObject("Scripting.FileSystemObject")
'Set folders = fs.GetFolder("d:폴더명uploadfilesbank")
'Set folder_files = folders.Files

'For Each f in folder_files
's = s & f.name
' s = s &   "<BR>"
'Set objFile = fs.OpenTextFile("d:폴더명uploadfilesbank"&f.name,1)
'Do While objFile.AtEndOfStream <> True
'   Response.write objFile.readLine & "<br>"
'loop
' 이런 방법도 같은 결과를 출력한다.(ReadAll 사용)
'content = objFile.readall
'str = replace(content,chr(13)&chr(10),"<br>")
'str = replace(str,"'","''")
'Response.write str


'strSQL="update bbs_data set bbs_content='"& str &"' , bbs_html='' where  bbs_htmlfile='"&f.name&"' and bbs_code='14' and bbs_html ='1'"
'strSQL="insert into  filefile (test_data) values ('"&str&"')
'response.write strSQL
'DBCon.Execute(strSQL)
'Set objFile=Nothing


'Next
'response.write "파일갯수 : " & folders.Files.count & "<BR>"


'folder Creating...
'Function CreateFolder(NewFolder As String)
'Dim fso, f, templen, Temp, tempDel
'Set fso = CreateObject("Scripting.FileSystemObject")
'Set f = fso.CreateFolder(NewFolder)
'CreateFolder = f.Path
'End Function


'============================================================================================================

If true Then
 strSQL="select top 1 * From E_BBS_CONT where  APPEND_FILE_NM2 is not null and use_yn='Y' "
 'strSQL=strSQL&" APPEND_FILE_NM2 is not null or "
 'strSQL=strSQL&" APPEND_FILE_NM3 is not null ) "
 response.write strSQL
'APPEND_FILE_NM1
'APPEND_FILE_REG_NM1
'APPEND_FILE_NM2
'APPEND_FILE_REG_NM2
'APPEND_FILE_NM3
'APPEND_FILE_REG_NM3
'APPEND_FILE_NM4
'APPEND_FILE_REG_NM4


 Set rs = DBCon.Execute(strSQL)
 If Not rs.eof Then
  i=1
  Set fso = CreateObject("Scripting.FileSystemObject")
 
   
    bbs_cd  =rs("bbs_cd")
    data_no  =rs("data_no")
    newf=bbs_cd & "0" & data_no
    'APPEND_FILE_NM1=rs("APPEND_FILE_NM1")   
    'APPEND_FILE_REG_NM1=rs("APPEND_FILE_REG_NM1")
    APPEND_FILE_NM2=rs("APPEND_FILE_NM2")
    APPEND_FILE_REG_NM2=rs("APPEND_FILE_REG_NM2")
    'APPEND_FILE_NM3=rs("APPEND_FILE_NM3")
    'APPEND_FILE_REG_NM3=rs("APPEND_FILE_REG_NM3")
    'APPEND_FILE_NM4=rs("APPEND_FILE_NM4")
    'APPEND_FILE_REG_NM4=rs("APPEND_FILE_REG_NM4")   
   
    '== 새로운 파일명 함수사용=============================
    'new_bbs_htmlfile1=fn_Change(APPEND_FILE_NM1,newf,"01")
    new_bbs_htmlfile2=fn_Change(APPEND_FILE_NM2,newf,"02")
    'new_bbs_htmlfile1=fn_Change(APPEND_FILE_NM3,newf,"03")
    '== 새로운 파일명 함수사용=============================
   
    'response.write APPEND_FILE_NM1 & " ///// 총 ===" & i &"건<br>"
   
     if fso.FileExists("d:폴더명uploadfiles"&APPEND_FILE_NM2) Then
    
     Else
      response.write APPEND_FILE_NM2 & " ///// 총 ===" & i &"건<br>"
     End if
    'Call CopyFile("기본파일경로및파일명", "복사할경로및파일명")
    Call CopyFile("d:폴더명uploadfiles"&APPEND_FILE_NM2, "d:폴더명intr_file"&new_bbs_htmlfile2)
   
    '== 기존 파일명을 새로운 파일명으로 변경함 ==================
    strSQL="update E_BBS_CONT set use_yn='N' where bbs_cd='" & bbs_cd & "' and data_no='" & data_no & "'"
    'response.write strSQL
    DBCon.Execute(strSQL)

    strSQL="update E_BBS_CONT set APPEND_FILE_REG_NM2='"&new_bbs_htmlfile2&"' where bbs_cd='" & bbs_cd & "' and data_no='" & data_no & "'"
    'response.write strSQL
    DBCon.Execute(strSQL)
   
    i=i+1   
  Set fso=Nothing
 End If
End If

Function fn_Change(wefile,new1,idx)
 arrFname="": lenFname="": endFname=""

 arrFname=Split(wefile,".")     '== 파일명분리
 lenFname=ubound(arrFname)   '== 파일길이
 endFname=arrFname(lenFname)  '== 확장자
 fn_Change=new1 & idx & "." &endFname
End Function

'file Copying...
Sub CopyFile(source, destination)
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFile(source)
f.Copy destination
End Sub

%>
<SCRIPT LANGUAGE="JavaScript">
<!--
location.reload();
//-->
</SCRIPT>
<%
'====== 복사할 원본 파일 , 복사될 파일.. ====
'Call CopyFile("d:폴더명ebs_workebs_db.asp", "d:폴더명ebs_workebs_db111.asp")
'============================================================================================================
'folder Deleting...
'Sub DeleteFolder(filespec)
'Dim fso
'Set fso = CreateObject("Scripting.FileSystemObject")
'fso.DeleteFolder (filespec)
'End Sub

'아래 코드는 For Each...Next 문을 사용해서 Folders 컬렉션을 가져오는 방법과 컬렉션을 반  '.복하는 방법을 설명합니다.
'Sub ShowFolderList(folderspec)
'Dim fs, f, f1, fc, s, i
'Set fs = CreateObject("Scripting.FileSystemObject")
'Set f = fs.GetFolder(folderspec)
'Set fc = f.SubFolders
'For Each f1 In fc
's = s & f1.Name
's = s & vbCrLf
'Next
'MsgBox s
'End Sub


'숨겨진 파일 특성과 시스템 파일 특성이 설정된 것을 포함하여, 지정된 파일에 포함된


'. 모든 File 개체로 구성되는 Files 컬렉션을 반환합니다
'Sub ShowFileList(folderspec)
'Dim fs, f, f1, fc, s
'Set fs = CreateObject("Scripting.FileSystemObject")
'Set f = fs.GetFolder(folderspec)
'Set fc = f.Files
'For Each f1 In fc
's = s & f1.Name
's = s & vbCrLf
'Next
'MsgBox s
'End Sub



'아래 코드는 Folder 개체를 얻는 방법과 이 개체의 속성 중 하나를 반환하는 방법을


'.설명합니다.
'Sub ShowFolderInfo(folderspec)
'Dim fs, f, s
'Set fs = CreateObject("Scripting.FileSystemObject")
'Set f = fs.GetFolder(folderspec)
's = f.DateCreated
'MsgBox s
'End Sub


'.상기와 같이 모듈파일에 정의해 놓고, 골라서 적용하세요.

'.Example.


'저장할 폴더검색 및 Creat


'tmpFolder = "저장할 폴더 경로"   '. D:Data2004-10-19"
'If Dir(tmpFolder, vbDirectory) = "" Then  '. 폴더가 존재하지 않는다면
'CreateFolder tmpFolder                            '.폴더를 맹글어라.
'End If


'파일에 Data 기록


'LogDataFile = "저장할 파일 경로"   '. D:Data2004-10-192004-10-19.dat"


'LogData = "아침 식사는 했수?"   '.저장할 Data


'FileNumber = FreeFile
'Open LogDataFile For Append As FileNumber
'Print #1, LogData
'Close #1


'.Copy 를 한다.


'SourceFile = "복사할 파일 경로"     '. D:Data2004-10-192004-10-19.dat"


'tmpCopyFile = "복사될 파일 경로"   '. D:BackUp2004-10-192004-10-19.dat"


'CopyFile SourceFile, tmpCopyFile       '.복사 실행


'.지워버릴 폴더검색 및 Creat


'tmpFolder = "저장할 폴더 경로"   '. D:Data2004-10-19"


'DeleteFolder(tmpFolder)                  '.가차 없이 지워버려라.


%>

2009/08/07 21:50 2009/08/07 21:50

<%@LANGUAGE="VBSCRIPT" CODEPAGE="949"%>
<!--#include file="opendb.asp" -->
<%
Server.ScriptTimeout = 10000
Response.Buffer = False


send_type = request("s_member")
send_name = request("send_name")
send_subject = request("mail_subject")
send_content = request("mail_content")



if request("page") = "" then
page = 1
else
page = request("page")
end if



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 전체 메일 보내기 일때'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'sql = "select email from userdbml where gjg =1 and email !='' order by number desc"
sql = "select email from userdbml where id='bj0806'"
Set rs = Server.CreateObject("ADODB.Recordset")


rs.pagesize = 500
rs.open sql,Db,3


if Rs.eof or Rs.bof then
%>
<script language="javascript">
<!--
alert('전체메일을 모두 발송 하였습니다.nn메일링 페이지로 이동 합니다');
location.href='mailling.asp';
//-->
</script>
<%
Else
totalpage = rs.pagecount
R_count = rs.recordcount - rs.pagesize * page
R_count1 = rs.recordcount - R_count
rs.AbsolutePage = page


i = 1


Do until rs.eof or rs.bof
'Do until rs.eof or i > rs.pagesize '이메일 갯수만큼 돌면서 메일 보내기
Set M = Server.CreateObject("CDONTS.NewMail")
M.To = rs("email")
M.From = send_name
M.Subject = send_subject
M.BodyFormat = 0
M.MailFormat = 0
M.Body = send_content
M.Send
Set M = Nothing


rs.movenext
i= i +1
Loop
%>
<html>
<head>
<script language="javascript">
<!--
function L_mail()
{
alert("<%=R_count1%>통 발송 하였습니다.nn<%=page%>페이지/전체<%=totalpage%>페이지");
document.emailing.submit();
}
//-->
</script>
</head>
<body onLoad="L_mail();">
<form name="emailing" action="maillingOk.asp" method="post">
<input type="hidden" name="page" value="<%=cint(page)+1%>">
<input type="hidden" name="s_member" value="<%=send_type%>">
<input type="hidden" name="send_name" value="<%=send_name%>">
<input type="hidden" name="mail_subject" value="<%=send_subject%>">
<textarea name="mail_content" rows="20" cols="75"><%=send_content%></textarea>
</form>
</body>
</html>
<%
end If
rs.close
Set rs = Nothing
%>

2009/08/07 21:46 2009/08/07 21:46

ASP + MS-SQL 사용중인 DB 용량보기

'사용중인 DB 용량 Free/Used/Total
Function getDBSize()   
     Dim strSql, sizeRs, freeSize

     strSql = "sp_spaceused" '내장프로시져명
     set sizeRs = conn.execute(strSql)
    freeSize =  replace(sizeRs(1),"MB","") - replace(sizeRs(2),"MB","")
     getDBSize = "<span style='color:red;'> Free : " & freeSize & " MB</span> / "&_

     "<span style='color:green;'>Used : " & sizeRs(2) & "</span> / " &_

     "<span style='color:#ff6600;'>Total : " & sizeRs(1) & "</span>"
     SizeRs.close


     Set SizeRs = nothing


End Function

'사용법

Response.write getDBSize()

2009/08/07 21:46 2009/08/07 21:46
ASP하면 MS-SQL, PHP하면 mysql이 생각납니다. 이에 대해서는 여러가지 이유가 있겠지만, 궁합(?)이 가장 잘 맞기 때문이겠죠~

하지만, 실무현장에는 여러가지 이유로 이러한 궁합이 깨지곤 하는데요. PHP + Oracle, ASP + MySQL등이 이러한 경우입니다. 연동하는데 그다지 어려운 점은 없지만, 도움이 필요하신 분들을 위해 간략하게 작성해봅니다.


* IIS 설정 방법과 MySQL, MyODBC 설치방법은 생략합니다.


다운로드

MySQL 4.1
http://dev.mysql.com/downloads/mysql/4.1.html

MySQL Connector/ODBC 3.51
http://dev.mysql.com/downloads/connector/odbc/3.51.html

MySQL Query Browser
http://dev.mysql.com/downloads/query-browser/1.1.html


설치

MySQL과 MyODBC, Query Brower를 설치합니다.


database와 table 생성

MySQL Query Browser를 이용하여 아래와 같이 address와 contacts를 생성합니다.

  1) address 생성

create database address;

  2) assress 사용

use address;

  3) contacts 생성

create table contacts
(

   contactId int auto_increment not null,

   firstName varchar(50),

   lastName varchar(50),

   address1 varchar(100),

   address2 varchar(100),

   phone varchar(20),

   primary key(contactId),

   unique id(contactId)

);


:: dns_test.asp 작성

생성한 DB에 접근할 수 있는지 확인하기 위해 아래와 같이 작성합니다.

<%

   dim adoConn

   set adoConn = Server.CreateObject("ADODB.Connection")

   adoConn.Open "Driver={MySQL ODBC 3.51 driver}; Server=localhost; Database=address; Uid=root;Pwd=121212;"

   if adoConn.errors.count = 0 then

      response.write "Connected Successfully!"

   end if

   adoConn.close
   set adoConn = nothing

%>

브라우저를 통해 http://localhost/dns_test.asp 를 입력해 Connected Successfully 라는 글이 나타난다면 ASP에서 MySQL를 사용할 준비가 된 것입니다.

꼭 알아두기

adoConn.Open "Driver={MySQL ODBC 3.51 driver}; Server=localhost; Database=address; Uid=root;Pwd=121212;"

이 내용이 가장 중요합니다. Driver를 MySQL ODBC 3.51 driver로 지정해주었다는 것을 기억하세요.

참조

http://dev.mysql.com/doc/refman/5.0/en/odbc-connector.html

http://www.devarticles.com/c/a/ASP/Using-MyODBC-To-Access-Your-MySQL-Database-Via-ASP/
2009/08/07 21:43 2009/08/07 21:43

ASP용 COM+를 제작하기 위해서 VB를 많이 사용합니다.  ASP의 기본 스크립트가 VBScript이기 때문에 문법적으로도 가까운 편이고, VB로 COM+를 작성하는 것 자체가 쉬워서 생산성 향상에 도움이 되기 때문에 많이 애용되고 있습니다.
 
여기서는 VB를 사용하여 COM+를 제작하는 방법을 간단하게 설명합니다. 이 부분을 이해하시려면 ASP와 VB의 기본 문법등은 알고 계셔야 합니다. (아래 예에서는 VB 6을 사용합니다.)
 
1. 먼저 VB를 실행하고 ActiveX DLL 을 선택하여 프로젝트를 생성합니다.



 
2. 프로젝트 / Project1 속성 메뉴를 클릭하여 프로젝트 속성창을 엽니다.
 
3. 아래와 같이 프로젝트 이름 부분을 입력합니다. (자신이 원하는 것 아무거나 입력하셔도 되지만, 예제 설명을 위해 적당히 지정을 하겠습니다.



 
4. 위 입력창을 닫고, 화면 우측의 프로젝트 속성창에서 클래스 모듈의 이름을 변경합니다.



 
5. 프로젝트 / 참조 메뉴를 선택하여 다음 요소를 체크합니다.
Microsoft ActiveX Data Objects 2.8 Library : DB 접근을 위한 모듈입니다. 사용하시는 시스템에 다른 버전이 있을 경우 해당 버전을 선택하시면 됩니다.
Microsoft Active Server Pages Object Library / Microsoft Active Server Pages ObjectContext Object Library : ASP 객체 접근을 위한 모듈입니다.
COM+ Services Type Library : COM+ 자료형을 선언해둔 모듈입니다.



 
6. 화면 중앙의 코드부로 와서 다음 코드를 입력합니다.
Option Explicit
 
Private objContext As ObjectContext
Private objRequest As Request
Private objResponse As Response
 
Public Function Show()
    ' IIS 객체
    Set objContext = GetObjectContext()
    Set objRequest = objContext("Request")
    Set objResponse = objContext("Response")
   
    objResponse.write objRequest("id")
End Function



7. 파일 / 프로젝트 저장 메뉴를 선택하여 현재 프로젝트를 적당한 폴더에 저장합니다.
 
8. 파일 / Board.dll 만들기 메뉴를 선택하고 확인을 눌려 Board.dll 을 생성합니다.
 
9. VB를 닫고, 관리 도구의 구성 요소 서비스를 실행합니다.
 
10. 구성 요소 서비스 창에서 내 컴퓨터의 COM+ 응용 프로그램에 마우스 우클릭을 하고 새로 만들기 / 응용 프로그램을 선택합니다.



 
11. 다음을 누르고 빈 응용 프로그램을 선택한 다음, 응용 프로그램 이름을 적당히 입력하고, 활성화 유형을 라이브러리 응용 프로그램으로 선택합니다.



 
12. 마법사를 닫고 COM+ 응용 프로그램을 보면 방금 입력한 응용 프로그램이 있습니다. 이 응용 프로그램 하위의 구성 요소에서  마우스 우클릭을 하고 새로 만들기 / 구성 요소를 선택합니다.
 
13. 구성 요소 설치 마법사에서 새 구성 요소 버튼을 클릭하고 위에서 만든 Board.dll 을 찾아 선택합니다. 그리고 다음 / 마침을 눌러 마법사를 닫습니다.
 
14. ASP 페이지를 하나 만들어 다음을 입력합니다.
 dim obj
 
 Set obj = Server.CreateObject("Board.List")
 
 obj.Show


 set obj = Nothing



15. ?id=abcd 를 붙여서 위 ASP 페이지를 엽니다. (예를 들자면 http://localhost/test/test.asp?id=abcd 정도가 됩니다.)  COM+ 를 만들때 입력했던 VB 코드에서 id 로 넘어온 값을 출력하도록 하였기 때문에, 위의 모든 과정이 정상이라면 화면에 abcd 가 찍혀야 합니다.
 


--------------------------------------------------------------------------------



IIS에서 작성된 COM+를 사용하게 되면 해당 dll 파일에 Lock이 걸려 수정, 삭제가 안됩니다. COM+ 작업을 할때 수시로 dll 을 수정하게 되는데 이런 경우 Lock이 걸려 있다면 작업 진행이 안되겠죠.
 
현재 돌아가고 있는 웹서버일 경우, 등록된 COM+의 Lock을 해제 하기 위해서는 구성 요소 서비스에서 해당 COM+를 사용 안함으로 선택하였다가 IIS의 해당 dll 사용이 타임아웃 되면 그때 새로운 dll을 올리시고 다시 사용 한다고 바꿔주시면 됩니다.
 
현재 돌아가지 않는 작업 전용 서버일 경우는 IIS를 리셋하는 것이 빨라서 편합니다. 윈도우의 실행 입력창에 iisreset /restart 를 입력하시면 5~20초 정도에 IIS가 재시작됩니다.

2009/08/07 21:41 2009/08/07 21:41

DLL 등록 쉽게 하기

[개요]
탐색기에서 Component를 쉽게 레지스트리에 등록하는 팁입니다. 탐색기 파일연결에 한번 등록해 놓으면, 나중에 dll 파일 선택후 등록및삭제을 쉽게 할수 있습니다.
자료출처: devpia.com 게시판



[방법]
먼저, 탐색기에서 도구 -> 폴더옵션 하면 "폴더옵션" 창이 나타납니다. 여기서 파일형식
을 선택하면, 각종 파일에 대한 프로그램 연결등을 할 수 있죠...

무조건 "새로 만들기" 버튼을 누릅니다.

그러면 "새 확장명 만들기" 창이 나오는데, "파일 확장명(F):" 란에 DLL 이라고 적어두
고 "고급(V) >>" 버튼을 누릅니다.

접힌 창이 펼처지면서 시간이 조금 걸립니다. 네~ "응용 프로그램 확장" 이라고 뜨는 군
요...

"확인" 버튼을 누릅니다.

다시, "폴더 옵션" 창으로 돌아오면, 맨 위에 "DLL 응용프로그램 확장" 이라고 생겼습니
다.

그리고는, "고급" 버튼을 눌러줍니다.

이제는, "파일 형식 편집" 창이 생기는데, "응용 프로그램 확장" 이라는 스트링은 건드
리지 말고, "명령(A):" 란을 봅니다. 그러면 시스템에 따라서 아무것도 없을 수도 있
고, 뭔가 있을 수도 있습니다.

오른쪽에 "새로 만들기(N)..." 버튼을 누릅니다. 새로이 창이 하나 더 뜨는데, "새 명
령" 이라는 창입니다. 여기에서 "작업(A):" 에는 "Register" 라고 해 주시고, 그 밑에
는 "Regsvr32.Exe %1" 라고 입력한 후 "확인" 버튼을 누릅니다.

그러면, "파일 형식 편집" 창으로 돌아오는데, 명령에 Register 가 추가되었군요...

한 번 더 "새로 만들기"를 합니다.

이번에는 Unregister / regsvr32.exe /u %1 라고 입력합니다.

모두 다 "확인" 을 하고 닫은 후 탐색기에서 *.DLL에서 오른 클릭하면 팝업 메뉴의 맨
윗 부분에 Register / Unregister 메뉴가 나오는것을 볼 수 있습니다.

OCX 도 똑 같이 작업을 하시면 됩니다.

그러면 매번 콤포넌트를 시스템에 등록하느라 시작 -> 실행 -> rewgsvr32 ~~~ 하지 않아
도 됩니다.

그런데, 이게 훨씬 편리한 이유는 탐색기에서 여러개의 파일을 선택하고서는 실행하면
한꺼번에 등록이 된다는 점 입니다.
2009/08/07 21:39 2009/08/07 21:39

아래의 코드를 프레임셋으로 나눈 페이지에 넣으면 새로고침(F5)를 하더라도 첫 페이지로 이동하지 않습니다.



Dim LastModified


LastModified = getGmt(DateAdd("h", -9, ShowFileAccessInfo(Server.MapPath("/test/test.asp"))))
Response.AddHeader "Last-Modified", "" &LastModified& ""
Response.AddHeader "ETag", "" &LastModified& ""


'===================================================================
'        func        : getGmt(sDate)
'        param        : sDate - 파일수정시간
'        memo        : 시간을 받아 GMT 포맷으로 리턴
'===================================================================
function getGmt(sDate)
       dim weekT(6), monT(11)
       weekT(0) = "Sun"
       weekT(1) = "Mon"
       weekT(2) = "The"
       weekT(3) = "Wed"
       weekT(4) = "Thu"
       weekT(5) = "Fri"
       weekT(6) = "Sat"


       monT(0) = "Jan"
       monT(1) = "Feb"
       monT(2) = "Mar"
       monT(3) = "Apr"
       monT(4) = "May"
       monT(5) = "Jun"
       monT(6) = "Jul"
       monT(7) = "Aug"
       monT(8) = "Sep"
       monT(9) = "Oct"
       monT(10) = "Nov"
       monT(11) = "Dec"


       getGmt = weekT(DatePart("w", sDate)-1) & " " &_
                        day(sDate)& " " &_
                        monT(DatePart("m", sDate)-1)& " " &_
                        year(sDate)& " " &_
                        mid(sDate, InstrRev(sDate, " ")) & " GMT"
end function


'===================================================================
'        func        : ShowFileAccessInfo(filespec)
'        param        : filespec - 파일
'        memo        : 파일의 마지막 수정 시간을 리턴
'===================================================================
function ShowFileAccessInfo(filespec)
       Dim fso, f


       Set fso = CreateObject("Scripting.FileSystemObject")
       Set f = fso.GetFile(filespec)
       ShowFileAccessInfo = f.DateLastModified
end function

2009/08/07 21:38 2009/08/07 21:38

First include this library at the top of your code (you can find the library in the source code section of this page). Do it in <head> tag. After loading the library you can write your code. You can find demo page here: demo page

Source code for index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Iframe Ajax</title>
    <script type="text/javascript" src="webtoolkit.aim.js"></script>
    <script type="text/javascript">
        function startCallback() {
            // make something useful before submit (onStart)
            return true;
        }

        function completeCallback(response) {
            // make something useful after (onComplete)
            document.getElementById('nr').innerHTML = parseInt(document.getElementById('nr').innerHTML) + 1;
            document.getElementById('r').innerHTML = response;
        }
    </script>
</head>

<body>

    <form action="index.php" method="post" onsubmit="return AIM.submit(this, {'onStart' : startCallback, 'onComplete' : completeCallback})">
        <div><label>Name:</label> <input type="text" name="form[name]" /></div>
        <div><label>File:</label> <input type="file" name="form[file]" /></div>
        <div><input type="submit" value="SUBMIT" /></div>
    </form>

    <hr/>

    <div># of submited forms: <span id="nr">0</span></div>
    <div>last submit response (generated by form action - index.php file): <pre id="r"></pre></div>

</body>
</html>

Source code for webtoolkit.aim.js

/**
*
*  AJAX IFRAME METHOD (AIM)
*  http://www.webtoolkit.info/
*
**/


AIM = {

    frame : function(c) {

        var n = 'f' + Math.floor(Math.random() * 99999);
        var d = document.createElement('DIV');
        d.innerHTML = '<iframe style="display:none" src="about:blank" id="'+n+'" name="'+n+'" onload="AIM.loaded(\''+n+'\')"></iframe>';
        document.body.appendChild(d);

        var i = document.getElementById(n);
        if (c && typeof(c.onComplete) == 'function') {
            i.onComplete = c.onComplete;
        }

        return n;
    },

    form : function(f, name) {
        f.setAttribute('target', name);
    },

    submit : function(f, c) {
        AIM.form(f, AIM.frame(c));
        if (c && typeof(c.onStart) == 'function') {
            return c.onStart();
        } else {
            return true;
        }
    },

    loaded : function(id) {
        var i = document.getElementById(id);
        if (i.contentDocument) {
            var d = i.contentDocument;
        } else if (i.contentWindow) {
            var d = i.contentWindow.document;
        } else {
            var d = window.frames[id].document;
        }
        if (d.location.href == "about:blank") {
            return;
        }

        if (typeof(i.onComplete) == 'function') {
            i.onComplete(d.body.innerHTML);
        }
    }

}



출처 : http://www.webtoolkit.info/ajax-file-upload.html

 

2009/08/07 21:35 2009/08/07 21:35

scriptmanager 를 사용하기 위해서 읽어 보아야 할것..


첫째. msdn 에서 scriptmanager에 대한 내용을 읽어 본다!

http://msdn.microsoft.com/msdnmag/issues/07/09/ScriptManager/default.aspx?loc=ko#S1

 

둘째. 페이지의 클라이언트측 라이프 사이클을 관장하는 역할을 가진 PageRequestManager 에 대해서 알아본다.

http://choong.tistory.com/42


셋째. 기타 팁에대해서 검색해 본다

http://blog.naver.com/kdllee?Redirect=Log&logNo=70017296323

http://blog.naver.com/withu21?Redirect=Log&logNo=120044334700  <--mgr.get_isInAsyncPostBack() 가 핵심!




시간이 나시는 분들은 microsoftajax.js 와 microsoftajaxwebforms.js 에 대해서 추가적으로 공부해 보는것도 좋을 듯 합니당~

* MicrosoftAjax.js : ASP.NET AJAX 가 제공하는 기본 스크립트엔진

   MicrosoftAjaxWebForms.js : ASP.NET AJAX 의 스크립트측 프레임워그카 웹 폼 페이지와 함께 동작하기 위한 코드 구현

위의 두 파일은 (C:\Program Files\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025\MicrosoftAjaxLibrary\System.Web.Extensions\1.0.61025.0) 에 있습니다. 다른 곳에 설치하신분은 알아서 찾아보시길....



FrameWork 2.0을 사용하여 프로젝트 진행시에 Aajx 사용을 위해 UpdatePanel을 사용할 경우가 많으며, 화려함 또는 사용자의 편의성을 위하여 다양한 Ajax 기법들을 사용하게 될것이라는 점은 분명한 사실이며, 이제는 웹프로그램의 기본사양이 되었습니다.

그중 ScriptManager는 .net AJax 프로젝트의 기본이 되는 부분이며 가장 핵심이 되는 사항인듯합니다.


ajax 보면 볼수록 매력적인듯 하지만 언제나 그렇듯이 과함은 모자람만 못한듯 합니다..

UpdataPanel의 경우에는 View State를 유지하기 위한 오버헤드가 발생한다는 사실을 언제나 주지하고 있어야 할듯 합니다.

Application의 경우 세세한 곳까지 성능을 고려치 않아도 하드웨어의 발전으로 말미암아 큰 차이점이 없겠지만. 아직 네트워크트래픽은 웹프로램을 하는 사람으로써 무시할 수 없는 큰 요소임에는 분명하니깐요.

updatepanel을 사용하고 .net 에서 제공하는 편리한 도구를 사용하여 표준적이며 유지보수가 용이한 코드를 작성을 할 것인지. 아니면 개별적으로 코딩을 하여 쫌더 좋은 성능과 자유로운 구현을 할 것인지에 대한 고민은 계속 될듯 합니다.

microsoftAjax.js와 microsoftAjaxWebForms.js를 분석하여 ms의 ajax javascript 에 대한 더 깊은 이해를 하게 된다면 둘다 만족하는 결과를 낼수 있다고 생각은 하지만 보유한 스킬의 부족과 귀차니즘으로 말미암아.. 먼 훗날이 될듯합니다.(오지 않을지도 모르는 -.-;;)


가면 갈수록 스킬에 대한 자신감이 떨어지고 있는듯합니다만.. 다시 한번 외쳐 봅니다

할수있다!! 가자 가보는거다!

 http://msdn.microsoft.com/ko-kr/magazine/cc163354.aspx 추천

2009/08/07 21:34 2009/08/07 21:34
이번 홈페이지에서 많은걸 해보기 위해 다음과 같은 뻘짓 테스트를 진행해 보았다.

1. 파일(htm or txt )로 되어 있는 컨텐츠를 form의 순서에 맞게 입력하기
순서에 맞게 입력 될 컨트롤을 생성한후 form에 입력한다. aspx 페이지에서 코딩된 페이지의 컨텐츠보다 앞에 들어가야 하는 경우가 있기 때문에 AddAt을 사용하였다.
Literal top = new Literal();
top.Text = "<div>top</div>";
form1.Controls.AddAt(0, top);
다음은 원하는 컨트롤만 렌더링 하기

    protected override void Render(HtmlTextWriter writer)
    {
        if (false)
        {
            Panel1.RenderControl(writer);
            writer.Flush();
        }
        else
        {
            base.Render(writer);
        }
    }

음.. 두가지를 한 이유는 컨텐츠의 상단메뉴와 좌측 메뉴를 자동으로 입력하여 해당 페이지에서는 컨텐츠만 코딩하기 위해서 였다.
곰곰히 생각해 보니 마스터페이지를 사용하는 것과 어떠한 차이점을 모르겠다.
그래서 지금은 고민중.. 마스터 페이지를 사용할 것이냐. 아니면 순수하게 모두 구현을 할것이냐!!!
생각하기 전에 구현을 해버리는 성격이었는데 이제야 생각하는 개발자가 되어 가는가 보다.

아!! 또하나의 이유.. 좌측 메뉴에서 선택했을때 페이지가 리로드 되면서 항상 컨텐츠가 바뀔 필요는 없지 않을까? 하는 생각에서 Render 이벤트에서 하나의 판넬만 렌더링을 시켰다. ajax 요청시 panel의 내용만 랜더링 된것으로 받아서 특정 위치에 add 시켜 볼까 하는 마음에... 근데.. 이것도 updatepanel을 사용하면 해결된다.. 어떤게 좋을지는 고민쫌 해보자. 
2009/08/07 21:34 2009/08/07 21:34