'IT'에 해당되는 글 43건

  1. 2011.12.27 SAP .NET Connector 3.0(3.0.3.0) 버전 사용시 오류 문제
  2. 2010.03.12 DDL, DML, DCL
  3. 2010.02.26 Oracle과 MSSQL함수 비교
  4. 2010.02.26 유용한 윈도우 기본 실행 명령어
  5. 2010.02.26 이 세상에 간단한 프로젝트는 없다.
  6. 2010.02.26 [C#]DataGridView Data를 Excel 파일로 저장(Export)
  7. 2010.02.26 [C#] Ping Test Code
  8. 2010.02.23 [MFC] 활성화 창 한/영 체크 및 변환
  9. 2010.01.08 IME 메시지를 hooking 하는 방법
  10. 2009.12.28 XP 모드 - 1. 가상화를 사용하기 위한 Bios 설정
  11. 2009.12.08 [MSSQL / Version] 현재 사용하는 MSSQL 버전 확인방법
  12. 2009.10.22 프록시 서버(proxy server) 구축 - freeproxy
  13. 2009.10.22 Microsoft Windows 2003 Server 설치 및 최적화 설정
  14. 2009.10.07 C#2.0 Iterators,Partial 클래스,Nullable 타입
  15. 2009.10.07 모니터 제어, 미니팝업창, 트레이 아이콘
  16. 2009.10.06 Serialize
  17. 2009.09.30 값, 참조 타입
  18. 2009.09.30 닷넷 트랜잭션 정리
  19. 2009.09.30 #2784A Microsoft SQL Server 2005 튜닝 및 쿼리 최적화
  20. 2009.09.30 데이터 결합 방법 정리
  21. 2009.09.30 MS-SQL 조인 내부 처리 방식 정리
  22. 2009.09.30 한 테이블에 존재하는 인덱스의 종류에 따른 차이
  23. 2009.09.30 인덱스 정리
  24. 2009.09.30 인덱스가 있지만 인덱스를 안 타는 경우
  25. 2009.09.30 MS-SQL 실행 계획 확인
  26. 2009.09.30 Inline 쿼리 VS 저장 프로시저
  27. 2009.09.30 SUBQUERY와 INLINE-VIEW의 차이 1
  28. 2009.09.29 닷넷에서 native dll 사용하기
  29. 2009.09.28 [MS SQL] ldf 파일 사이즈 줄이기 또는 삭제하기
  30. 2009.09.15 C#2.0 , C# 3.0 New Features
posted by 방랑군 2011. 12. 27. 22:59

출처 : http://cafe.naver.com/sharedtalk.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=281&
 


SAP Rfc Function 
호출을 위한 SAP .NET Connector3.0 오류 Trouble Shooting

 

2011-11-11

 

상태

ASP.NET 프로그램에서 SAP 의 로그인 체크 function 을 호출하여 현재 해당 클라이언트의 로그인 정보를 리턴 받는 로직을 구현하였습니다.

SAP .NET Connector3.0 이 나온지 얼마 되지 않았고로직 구현 방법도 크게 바뀌었다고 들었습니다최대한 간단하고 쉽게 말이죠.  .NET Connector 2.0 의 많은 한계를 극복한 버전이라고 하여 영문으로 된 매뉴얼을 열심히 읽어가며 구현하게 되었습니다.

 개발환경은 아래와 같습니다.

OS :

Windows Server 2008 (x64)

IIS :

IIS 7 (Version 6)

.NET Framework :

3.5

.NET Connector :

Nco 3.0

development tool :

VisualStudio 2005

SAP :

SAP GUI 7.20

 

 

Figure 1 어플리케이션 단 프로그램

 

l  Figure 1 :

n  Tutorial.cs  à main() 로직

n  AbapConnectorClient.cs à SAP Rfc Function 호출하여 로그인 정보 체크 로직

n  App.config à Rfc Function 호출할 SAP 클라이언트 정보

 

콘솔 응용프로그래밍 입니다. Rfc 호출 잘 됩니다^^

 

Figure 2 웹 사이트 프로젝트

l  Figure 2 :

n  MultiLoginTest.cs  à SAP Rfc Function 호출하여 로그인 정보 체크 로직(어플리케이션 단 로직과 거의 같음), 결과 정보MultiLoginTest.aspx 로 넘겨줌

n  MultiLoginTest.aspx à 파라미터 정보 받아서 웹 화면에 띄어줌

n  web.config à Rfc Function 호출할 SAP 클라이언트 정보 및 Web configuration 정보

 

 

Figure 3 운영서버에 적용할 때 Bin폴더 안에 라이브러리 파일 삽입

 

현상

응용프로그래밍 프로젝트즉 어플리케이션 단 RFC 프로그래밍 시 정상

그러나.......

웹 사이트 프로젝트 프로그래밍으로 RFC 호출 시 에러à 아래와 같은 오류

 

Figure 4 오류 화면

 

-       Invoke() 부분에서 오류 발생.

-       바인딩 오류라 생각하여 이놈이 필요한 dll파일들을 못찾아서 나는건가 싶어서 --> Web.config 설정 여러 번 변경 해봄…. 그래도 오류 발생

-       구글링 해본 결과 .NET Framework4.0 으로 업그레이드 하라고 함 à 운영상 리스크때문에 보류

 

결국…SAP 에 Customer Message 보내어 해결책 얻음.

 

원인

.NET Connector3.0 (3.0.3.0) release 버전의 버그 문제

 

솔루션

 

119일 Release 된 .NET Connector3.0 버그 패치 버전 (3.0.5.0) 으로 다시 설치 및 dll 파일 복사 후 적용

 

 

 

 

 

한달간의 삽질이 버그 문제로 판명이 되었습니다^.^

 

이전 버전으로 고생하고 계신 분들이 있을 까봐 공유합니다.

장원철님 도움주셔서 감사합니다.

앞으로도 도움 주고받으면서 지냈으면 좋겠습니다.

 

 

여기에 올려도 되는지 모르겠습니다.

원하시는데 옮겨주시면 감사하겠습니다^^

 

posted by 방랑군 2010. 3. 12. 13:01

DDL(Data Definition Language) 은 데이터베이스의 스키마 객체를 생성(CREATE),

 

변경(ALTER), 제거(DROP) 하거나 권한의 부여나 박탈(GRANT, REVOKE), 주석(COMMENT),

 

자료의 버림(TRUNCATE) 등을 수행하는 문장의 집단을 의미한다.

 

각 문장은 CREATE, ALTER, DROP, TRUNCATE, GRANT, REVOKE, COMMENT 등으로 시작한다.

 

이 밖에도 많은 종류의 DDL이 존재한다. 그러나 PL/SQL 블록에서는 DDL을 사용할 수 없다.

 

 

DML(Data Manipulation Language)은 스키마 객체의 데이터를 입력(INSERT), 수정(UPDATE),

[Manipulation=교묘한처리,조종]

 

조회(SELECT), 삭제(DELETE)하거나 테이블에 잠금을 설정하거나 (LOCK TABLE), SQL문의

 

처리의 절차에 대한 정보를 얻거나 (EXPLAIN PLAN), PL/SQL 모듈을 호출하는 작업(CALL)의 집단이다.

 

각 문장은 INSERT, UPDATE, DELETE, SELECT, LOCK TABLE, EXPLAIN PLAN, CALL 등으로 시작된다.

 

PL/SQL의 모듈에서 사용할 수 없는 DML로서는 EXPLAIN PLAN과 CALL이 있다.

 

DCL(Data Control Language)은 트랜잭션의 성격을 제어하는 것으로서 SET TRANSACTION,

 

COMMIT, ROLLBACK, SAVEPOINT와 같은 종류가 있다.

 

PL/SQL 모듈에서는 DCL을 사용할 수 있고 DCL을 이용하여 모듈의 트랜잭션을 제어 할 수 있다.

 

 

발췌 about Oracle 9i PL/SQL  p156   저자 이태윤

posted by 방랑군 2010. 2. 26. 16:09

문자열 함수

Function

Oracle

SQL Server

Convert character to ASCII

ASCII

ASCII

String concatenate

CONCAT

(expression + expression)

Convert ASCII to character

CHR

CHAR

Return starting point of character in character string (from left)

INSTR

CHARINDEX

Convert characters to lowercase

LOWER

LOWER

Convert characters to uppercase

UPPER

UPPER

Pad left side of character string

LPAD

N/A

Remove leading blank spaces

LTRIM

LTRIM

Remove trailing blank spaces

RTRIM

RTRIM

Starting point of pattern in character string

INSTR

PATINDEX

Repeat character string multiple times

RPAD

REPLICATE

Phonetic representation of character string

SOUNDEX

SOUNDEX

String of repeated spaces

RPAD

SPACE

Character data converted from numeric data

TO_CHAR

STR

Substring

SUBSTR

SUBSTRING

Replace characters

REPLACE

STUFF

Capitalize first letter of each word in string

INITCAP

N/A

Translate character string

TRANSLATE

N/A

Length of character string

LENGTH

DATALENGTH or LEN

Greatest character string in list

GREATEST

N/A

Least character string in list

LEAST

N/A

Convert string if NULL

NVL

ISNULL

 

Date 함수

Function

Oracle

SQL Server

Date addition

(use +)

DATEADD

Date subtraction

(use -)

DATEDIFF

Last day of month

LAST_DAY

N/A

Time zone conversion

NEW_TIME

N/A

First weekday after date

NEXT_DAY

N/A

Convert date to string

TO_CHAR

DATENAME

Convert date to number

TO_NUMBER(TO_CHAR())

DATEPART

Convert string to date

TO_DATE

CAST

Get current date and time

SYSDATE

GETDATE()

 

posted by 방랑군 2010. 2. 26. 15:44
윈도우 기본 애플리케이션

명령어

실행하는 프로그램

mspaint

그림판

wordpad

워드패드

calc

계산기

notepad

메모장

sndvol32

볼륨 조절기

regedit

레지스트리 편집기

iexplore

인터넷 익스플로러

wmplayer

윈도 미디어 플레이어

msmsgs

윈도 메신저

cmd

명령 프롬프트

msconfig

시스템 구성 (시작 프로그램 관리자)

moviemk

윈도 무비 메이커

snippingtool

캡처 도구 (윈도우 7만 기본적으로 지원)

explorer

탐색기

msinfo32

시스템 정보

chkdsk

디스크 검사 도구

cleanmgr

디스크 정리

taskmgr

작업 관리자

perfmon

성능 모니터

mrt

악성 소프트웨어 제거 도구

sfc

시스템 검색 유틸리티 (시스템 파일 유효성 확인)

sfc /scannow

즉시 스캔

sfc /scanonce

다음 부팅 때 한번 실행

mstsc

원격 데스크톱 연결

msra

윈도 원격 지원

osk

화상 키보드

wab

연락처

logoff

로그오프

shutdown

시스템 종료

shutdown –r

시스템 다시 시작


제어판

명령어

실행하는 프로그램

control

제어판

appwiz.cpl

프로그램 추가/삭제

desk.cpl 또는 control desktop

디스플레이

mmsys.cpl

소리

sysdm.cpl

시스템 속성

control mouse

마우스 속성

ncpa.cpl 또는 control netconnections

네트워크 연결

inetcpl.cpl

인터넷 속성

wscui.cpl

보안 센터

fsmgmt.msc

공유 폴더

powercfg.cpl

전원 옵션

control admintools

관리 도구

services.msc

서비스

devmgmt.msc

장치 관리자

control printers

프린터

gpedit.msc

그룹 정책 편집기

control fonts

폰트 (fonts만 입력하면 폰트 폴더 열림)

control schedtasks

작업 스케줄러

 

IT
posted by 방랑군 2010. 2. 26. 15:41

'IT' 카테고리의 다른 글

Windows Server 2008 Setting Tip  (0) 2009.07.30
posted by 방랑군 2010. 2. 26. 15:40
C# 윈폼에서 DataGridView Data를 Excel 파일로 저장하는 소스를 알려 드리겠습니다. 순수하게 제가 만든건 아니고 여러 사이트에서 소스를 참조해서 제 상황에 맞게끔 응용을 했습니다.

제가 MS 오피스 2007 에 Visual Studio 2008 을 쓰기 때문에 이를 기준으로 소개를 하겠습니다.

먼저 솔루션 탐색기에서 참조추가를 합니다.

솔루션탐색기->참조추가->COM->Microsoft Excel 12.0 Object Libary 선택



이후 아래 소스를 적용하시면 됩니다.

using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;

private void ExportExcel(bool captions)
{
    this.saveFileDialog.FileName = "TempName";
    this.saveFileDialog1.DefaultExt = "xls";
    this.saveFileDialog1.Filter = "Excel files (*.xls)|*.xls";
    this.saveFileDialog1.InitialDirectory = "c:\\";

    DialogResult result = saveFileDialog.ShowDialog();

    if (result == DialogResult.OK)
    {
        int num = 0;
        object missingType = Type.Missing;

        Excel.Application objApp;
        Excel._Workbook objBook;
        Excel.Workbooks objBooks;
        Excel.Sheets objSheets;
        Excel._Worksheet objSheet;
        Excel.Range range;

        string[] headers = new string[dataGridView.ColumnCount];
        string[] columns = new string[dataGridView.ColumnCount];

        for (int c = 0; c < dataGridView.ColumnCount; c++)
        {
            headers[c]=dataGridView.Rows[0].Cells[c].OwningColumn.HeaderText.ToString();
            num = c + 65;
            columns[c] = Convert.ToString((char)num);
        }

        try
        {
            objApp = new Excel.Application();
            objBooks = objApp.Workbooks;
            objBook = objBooks.Add(Missing.Value);
            objSheets = objBook.Worksheets;
            objSheet = (Excel._Worksheet)objSheets.get_Item(1);

            if (captions)
            {
                for (int c = 0; c < dataGridView.ColumnCount; c++)
                {
                    range = objSheet.get_Range(columns[c] + "1"Missing.Value);
                    range.set_Value(Missing.Value, headers[c]);
                }
            }

            for (int i = 0; i < dataGridView.RowCount - 1; i++)
            {
                for (int j = 0; j < dataGridView.ColumnCount; j++)
                {
                    range = objSheet.get_Range(columns[j] + Convert.ToString(i + 2),
                                                           Missing.Value);

                    range.set_Value(Missing.Value,
                                          dataGridView.Rows[i].Cells[j].Value.ToString());

                }
            }

            objApp.Visible = false;
            objApp.UserControl = false;

            objBook.SaveAs(@saveFileDialog.FileName,
                      Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal,
                      missingType, missingType, missingType, missingType,
                      Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
                      missingType, missingType, missingType, missingType, missingType);
            objBook.Close(false, missingType, missingType);

            Cursor.Current = Cursors.Default;

            MessageBox.Show("Save Success!!!");
        }
        catch (Exception theException)
        {
            String errorMessage;
            errorMessage = "Error: ";
            errorMessage = String.Concat(errorMessage, theException.Message);
            errorMessage = String.Concat(errorMessage, " Line: ");
            errorMessage = String.Concat(errorMessage, theException.Source);

            MessageBox.Show(errorMessage, "Error");
        }
    }


posted by 방랑군 2010. 2. 26. 15:39
네트웍 프로그램을 개발할시 Connect 로 접속할때 IP가 살아 있지 않으면 딜레이가 많이 생깁니다. 하나의 IP에 단발성으로 Connect 를 할거면 딜레이가 생겨도 상관이 없지만 여러 IP에 Connect 를 시도 해야할때는 이 딜레이 때문에 프로그램이 꼭 다운된듯한 느낌이 들어 사용자에게 오해를 불러 일으킬수 있는 요지가 있어 이 딜레이를 없애는게 좋은거 같습니다. 

C# 내부 함수로는 이 딜레이를 없애는 방법은 없는거 같습니다. 그럼 방법은 ping 을 날려 보고 살아 있으면 Connect를 하고 죽어있으면 다른 IP로 넘어 가는 방법을 택해야 하는거 같습니다.

C#에서 Ping Test Code 입니다.

public bool Connect(string ip, int port)
{
    try
    {
        //IP Address 할당 
        this.ipAddress = IPAddress.Parse(ip);

        //TCP Client 선언
        this.tcpClient = new TcpClient(AddressFamily.InterNetwork);

        Ping pingSender = new Ping();
        PingOptions options = new PingOptions();

        // Use the default Ttl value which is 128,
        // but change the fragmentation behavior.
        options.DontFragment = true;

        // Create a buffer of 32 bytes of data to be transmitted.
        string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        byte[] buffer = Encoding.ASCII.GetBytes(data);
        int timeout = 120;
        PingReply reply = pingSender.Send(this.ipAddress, timeout, buffer, options);
        
        if (reply.Status == IPStatus.Success)
        {
            // Ping 성공시 Connect 연결 시도
            this.tcpClient.NoDelay = true;
            this.tcpClient.Connect(ipAddress, port);

            this.ntwStream = tcpClient.GetStream();               
        }
        else
        {
            // Ping 실패시 강제 Exception
            throw new Exception();
        }

        return true;
    }
    catch (Exception ex)
    {
        //MessageBox.Show("Connect Fail... : " + ex);
        return false;
    }
}

참고한자료 : 
msdn - Ping 클래스(System.Net.NetworkInformation)
posted by 방랑군 2010. 2. 23. 17:03
  if( !(hIMC = ImmGetContext( GetActiveWindow() ) ) )                    // 핸들을 얻어오고,
   break;


  ImmGetConversionStatus( hIMC, &dwConversion, &dwSentence);    // 현재 IME의 상태를 얻어서
  if(dwConversion & IME_CMODE_HANGEUL)                                    // 만약 한글 모드라면
   dwConversion -= IME_CMODE_HANGEUL;                                    // 한글 모드 안되게...
  
  ImmSetConversionStatus( hIMC, IME_CMODE_ALPHANUMERIC, IME_SMODE_NONE);    // 한글모드아니게 설정
  ImmReleaseContext( GetActiveWindow(), hIMC );                            //얻은 핸들 풀어주고


이런식...
IME_CMODE_HANGEUL 
IME_CMODE_JAPANESE
.. 등등<


Imm32.lib와 
Imm.h를 사용한다.

'IT > 후킹' 카테고리의 다른 글

IME 메시지를 hooking 하는 방법  (0) 2010.01.08
posted by 방랑군 2010. 1. 8. 16:23

http://support.microsoft.com/kb/601978/ko


IME message들은 OS가 Application의 message queue 로 posting하는 message가 아니라, 각 application의 WinProc를 직접 call하는 message이므로, CallWndProc hook procedure를 이용하여 hooking해야 합니다. 
다음은 WM_IME_NOTIFY message를 hooking하는 DLL 의 예제코드입니다.

## Hooking Procedure에서 추가되는 함수들은 user의 input를 기다리는 API는 사용하지 마십시오. 이것은 system의 performance를 떨어뜨리거나 심지어는 dead-lock 발생의 원인이 됩니다.


HHOOK hHook = NULL;
HINSTANCE hHookDll;
LRESULT CALLBACK GetMsgProc(int code,  WPARAM wParam,  LPARAM lParam);

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
)
{
hHookDll = (HINSTANCE )hModule;
     return TRUE;
}

BOOL APIENTRY  SetHookProc()
{
hHook =  SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hHookDll,0);
if (hHook)
return true;
else
return false;
}

void APIENTRY UnsetHookProc()
{
UnhookWindowsHookEx(hHook);
}

LRESULT CALLBACK GetMsgProc(int code,  WPARAM wParam,  LPARAM lParam)
{
   MSG *msg = (MSG *)lParam;
   if ( msg->message == WM_IME_NOTIFY)
   {
   // TODO : Add to code what you want to act
  
   // Always call next hook in chain 
   return CallNextHookEx(hHook, code,  wParam, lParam);
}



'IT > 후킹' 카테고리의 다른 글

[MFC] 활성화 창 한/영 체크 및 변환  (0) 2010.02.23
posted by 방랑군 2009. 12. 28. 09:39

XP모드라는 것이 가상화를 이용한 기술이므로, CPU가 가상화를 지원해야 하고, Bios에서 Enable이 되어 있어야 합니다.

세가지 정도의 바이오스 화면을 찾아 보았는데요. 나머지 시스템들도 별반 다를 것이 없으니 아래 화면을 참고해서 Virtualization을 Enable로 설정 하시기 바랍니다.

 

[DELL Bios 화면]

 

※ 표시된 Disabled 설정을 Enabled로 변경 하시기 바랍니다.

 

※ 마찬가지로 Enabled로 변경 하세요.

posted by 방랑군 2009. 12. 8. 12:55
1) 단순 버전 확인
SELECT @@VERSION;

@@VERSION : 현재 설치되어 있는 MS SQL Server의 날짜, 버전, 프로세스 유형을 반환 

2) 서비스 팩 확인

select SERVERPROPERTY('productlevel')

3) 버전, 서비스팩, 설치 Edition 확인 

SELECT 'SQL Server ' 
+ CAST(SERVERPROPERTY('productversion') AS VARCHAR) + ' - ' 
+ CAST(SERVERPROPERTY('productlevel') AS VARCHAR) + ' (' 
+ CAST(SERVERPROPERTY('edition') AS VARCHAR) + ')'

그 외,

USE MASTER

GO

 

EXEC XP_MSVER 

 

EXEC XP_MSVER 'PRODUCTNAME', 'PRODUCTVERSION', 'LANGUAGE', 'PLATFORM', 'WINDOWSVERSION', 'PHYSICALMEMORY', 'PROCESSORCOUNT'

'IT > DB' 카테고리의 다른 글

DDL, DML, DCL  (0) 2010.03.12
Oracle과 MSSQL함수 비교  (0) 2010.02.26
#2784A Microsoft SQL Server 2005 튜닝 및 쿼리 최적화  (0) 2009.09.30
데이터 결합 방법 정리  (0) 2009.09.30
MS-SQL 조인 내부 처리 방식 정리  (0) 2009.09.30
posted by 방랑군 2009. 10. 22. 13:19

참조 :  http://cciijj.tistory.com/86


프록시 서버를 간단히 구축할 수 있습니다.

프록시 서버는 요즈음에는 보통 아이피를 바꾸기 위한 용도로 많이 이용됩니다. 나의 컴퓨터가 A 라고 하고 프록시 서버가 설치된 컴퓨터를 B 라고 하면 내가 B 컴퓨터에 접속을 하여 google.com 에 접속할 수 있습니다. 이 경우 google.com 에는 프록시 서버를 구축할 때 설정에 따라 프록시를 경유했는지 여부를 알 수도 모를 수도 있고 또 A 컴퓨터의 아이피가 노출될 수도 노출되지 않을 수도 있습니다.

http://www.linksmile.com/anon-proxy-checker.php
에 보시면 다음 항목에서 검출되지 않으면 완벽히 B 컴퓨터에서 접속한 것으로 인식됩니다.

BASIC anonymous proxy test variables (both must be "Not Detected" or "127.0.0.1")
HTTP_FORWARDED
HTTP_X_FORWARDED_FOR

HIGH anonymous proxy test variables (all must be "Not Detected")
HTTP_VIA
HTTP_XROXY_CONNECTION
HTTP_PROXY_CONNECTION
또 나의 컴퓨터가 A 라고 하고 감시를 원하는 컴퓨터를 C 라고 하면 내 컴퓨터에 프록시 서버를 설치하고 'transparent', '로그남김'으로 설정 후, C 컴퓨터 브라우저 설정을 내 컴퓨터 아이피주소로 하면 C 컴퓨터의 서핑 내역 로그를 A 컴퓨터에 남길 수 있습니다.

프록시 서버를 제공하는 곳이 여럿 있지만 속도는 매우 느리고 서버 제공자를 신뢰할 수 없으므로 사용이 꺼려집니다. 아이피를 바꾸고 싶다면 또는 프라이버시를 지키고 싶다면 합법적 범위 안에서 프록시 서버를 구축해서 인터넷을 이용할 수 있습니다. 좀 무책임한 말인지도 모르겠지만 '살인은 칼을 사용하는 사람의 책임이지 칼을 만들 사람의 책임은 아니다'라고 기어들어가는 목소리로 말하고 싶군요. 선택은 열려 있고 판단은 각자 해야 한다는 생각합니다.

외국의 모회사와 국내의 모 회사는 프록시 서버를 구축하고 완전한 프라이버시를 유료로 제공합니다. 그 회사들이 로그를 남기는지 안 남기는지는 모르겠지만, 완전한 프라이버시를 원하는 수요자 있음을 말해줍니다. 저 또한 요즘 추진 중인 통신법 개정에 반대합니다. 진보넷의 경우 접속자의 로그를 남기지 않는 걸로 압니다. 제 경우 테러를 대비한 로그를 남기기는 하지만 며칠 후면 삭제되게 해 두고 있습니다.

freeproxy는 http://www.handcraftedsoftware.org에서 다운로드 할 수 있습니다.


자세한 설정법은 열정의 부족으로 설명을 생략하겠습니다. 설정에서 인증을 거칠 것인지, 완벽한 익명성을 보장할 것인지, 로그를 남길 것인지 등을 설정할 수 있습니다.

(ver 3.81 기준 - 요즈음 바뀐지는 확인하지 않았습니다.)
default.cfg는 모든 설정이 다 들어있습니다. 그림의 창에서 모든 설정을 마무리했다면 default.cfg, freeproxy.exe, freeproxyftp.tem 을 확보한 후 다음의 명령으로 다른 컴퓨터에 간단히 설치할 수 있습니다. 3개의 파일만 있으면 동작하고 윈도의 서비스로 기동하게 됩니다.
freeproxy.exe -install default.cfg
posted by 방랑군 2009. 10. 22. 12:46

Microsoft Windows 2003 Server 설치 및 최적화 설정

 

Microsoft Windows 2003 Server을 안정성 > 사용상 편의 / 속도 > 시각적 효과적으로 최적화 설정을 정리.
주관성에 집중되어 있으므로 차이에 따라 본인의 사용 용도에 따라 설정도 가능하다. 
Microsoft Windows 2003 Server은 서버용 운영체제이므로 기본적인 음성, 그래픽 혹은 자바등의 구성이 제외 되어 있거나 비활성화 되어있다.
- 음성/테마 적용 및 자바 설치등을 설정하면 XP와 비슷한 환경으로 설정 가능.

* 기본적으로 Microsoft Windows 2003 Server는 저사양에서도 Microsoft Windows 2000 Server나 Microsoft Windows XP 제품군보다 훨씬 빠른 속도와 확장성 보여준다.

운영체제 설치 개략

* 운영체제를 설치 할 때에는 반드시 인터넷이 연결되지 않은 상태에서 설치하며 웜패치 및 보안패치를 반드시 설치.

* 하드웨어 칩셋 패치를 반드시 설치. 시스템의 성능의 향상.
* 설치 후 백신 프로그램을 설치. Microsoft Windows XP 제품군과는 다르게 서버용 백신을 설치.
* 드라이버는 최신 사양으로 설치. 하지만 드라이버와 운영체제간의 호환성 문제로 인해 윈도우즈 업데이트를 통한 드라이버 설치를 권장.
* DirecX 설치 후 여러가지 소프트웨어를 설치.
* 비활성화 목록을 활성화.

 

Step 01. Microsoft(R) Windows 2003 설치 버전 확인
시작 > 실행 > winver을 입력.
(예) Microsoft(R) Windows 버전 5.2(빌드 3790.srv03_rtm.030324-2048)

 

Step 02. 멀티 부팅시 유의 및 부팅순서/운영체제 목록 표시시간 설정
-자신의 주로 사용할 운영체제를 기본으로 설정하고 운영 체제 목록을 표시할 시간을 설정 변경.
컴퓨터 > 속성 > 고급 > 시작 및 복구 > 설정 > 시스템 시작 에서 설정.
※ 멀티 부팅 유의사항은 반드시 C Drive(마스터)는 Microsoft(R) Windows 2003보다 하위 버젼 설치 후 D drive(슬레이브) Microsoft(R) Windows 2003설치.
상하위 버전을 바꾼 상태로 설치 시 상위버전이 실행되지 않음.

 

Step 03. 시스템 설정
-DirectX 활성화
시작 > 실행 > dxdiag > 확인하여 DirectX 진단 도구를 실행하고 디스플레이 탭을 선택하고 
DirectX 기능이라는 항목에 DirectDraw 가속, Direct3D 가속, AGP 질감 가속 기능을 모두 사용 선택하고 
소리 탭에서 DirectX 기능 항목에 하드웨어 소리 가속 수준을 최대로 변경.

-시스템의 설정 변경
내 컴퓨터 > 속성 > 고급 > 시작 및 복구 항목에 설정(T) 선택 한 후 디버깅 정보 쓰기 항목에 작은메모리덤프(64KB)로 변경.
내 컴퓨터 > 속성 > 고급 > 성능 항목에 설정(S) 선택 한 후 고급탭에 프로세서 사용 계획, 메모리 사용 계획 항목을 모두 프로그램.

-서비스 항목설정
시작 > 실행 > services.msc > 확인 > 서비스를 실행하고 서비스(로컬)에서 아래 항목들을 변경.
(o):자동 (*):수동 (x):사용안함
Alerter(x) : 선택된 사용자와 컴퓨터에 관리 경고를 알립니다.
Automatic Updates(x) : 중요한 windows업데이트를 자동으로 다운로드하고 설치할 수 있도록 합니다.
Error Reporting Service(x) : 예상치 못한 응용프로그램 오류를 모으고 저장하거나 microsoft에 보고합니다.
Help and Support(*) : 도움말 및 지원센터를 실행 할 수 있도록 합니다.
IMAPI CD-Burning COM Service(*) : IMAPI를 이용하여 CD굽기를 관리합니다.
Messenger(x) : 클라이언트와 서버 사이에 net send및 경고 서비스 메시지를 전송합니다.
Portable Media Serial Number(x) : 이 컴퓨터에 연결된 어떠한 Portable Media Player의 일련번호를 검색합니다.
Protected Storage(x) : 개인키와 같은 중요한 정보를 보호하고 허가되지 않은 서비스, 프로세스, 사용자 액세스를 방지합니다.
Remote Registry(x) : 원격사용자가 이 컴퓨터에서 레지스트리 설정을 수정할 수 있도록 설정합니다.
Secondary Logon(x) : 다른 자격 증명에서 프로세스를 시작할 수 있도록 합니다.
Windows Image Acquisition(WIA) : 스캐너 및 카메라에 대한 이미지 인식 서비스를 제공합니다.
Windows Time(x) : 네트워크 상에서 모든 클라이언트 및 서버의 날짜 및 시간 동기화를 유지합니다.

-Theme 서비스 및 Audio 서비스 활성화
시작 > 실행 > services.msc > 확인 > 서비스 > 서비스로컬에서 themes > 자동으로 설정.
시작 > 실행 > services.msc > 확인 > 서비스 > 서비스로컬에서 windows audio > 자동으로 설정.

-디스플레이 설정
자신의 최신 그래픽 드라이버를 설치.
시작 > 제어판 > 디스플레이 > 디스플레이 등록정보 > 설정 > 고급(V)를 선택 한 후 문제해결 탭에서 하드웨어 가속 항목에 
하드웨어 가속(H)를 최대로 변경.
※ DirectX가 설치가 되어있어야 함.

-사운드 설정
자신의 최신 사운드 드라이버를 설치.
시작 > 제어판 > 사운드 및 오디오장치 > 볼륨 > 스피커 설정 항목에서 고급(D)...를 선택 한 후 성능 탭에서 오디오 재생 항목에
하드웨어 가속을 최대로 변경.
※ DirectX가 설치가 되어있어야 함.

-자바가 실행 불가능 할 시(예:다음카페에서 cafe on이 되지않는 경우)
자바의 저작권 문제로 제외 되었던 마이크로 소프트 버추얼머신을 설치.
※ 인터넷 공개자료실같은 사이트에서 쉽게 다운로드 가능.

 

Step 04. 최적화 팁 (윈도우 부분)
- 1차 가상메모리 설정
제어판 > 시스템 > 고급 > 성능탭에서 설정(S) 선택 한 후 성능 옵션을 실행하고 고급탭에 가상 메모리항목을 1GB를 기준으로 1536MB / 1536MB의 스와핑드라이브를 지정.

-오류 보고 설정 해제
제어판 > 시스템 > 고급 > 오류보고(R) 선택 한 후 오류 보고를 실행하고 오류 보고 사용 안 함 선택.

-자동 시스템 재부팅 설정 해제
제어판 > 시스템 > 고급 > 시작 및 복구항목에서 설정을 선택 한 후 시스템 오류 항목에서 자동으로 다시 시작을 선택 해제.

-시각 효과 설정
제어판 > 시스템 > 고급 > 성능항목에서 설정을 선택 한 후 성능옵션을 실행하고 시각 효과탭에서 최적 성능으로 조정(P)을 선택.
제어판 > 디스플레이 설정 > 화면배색 > 효과를 선택 하여 효과를 실행하고 모두 선택 해제.

-시스템 시작 시 ctrl+alt+del 설정 해제 
시작 > 실행 > gpedit.msc 입력 > 그룹정책개체편집기 > 컴퓨터구성 > windows설정 > 보안설정 > 로컬정책 > 보안옵션 > 대화형로그온 : [ctrl+alt+del]을 사용할필요없음 > 더블클릭 > 사용으로 선택 합니다.

-시스템 종료 시 이벤트 추적기 표시 설정 해제
시작 > 실행 > gpedit.msc입력 > 그룹정책개체편집기 > 컴퓨터구성 > 관리 템플릿 > 시스템 > 우측창에서 시스템 종료이벤트 추적표시 더블클릭 > 사용 안함으로 변경합니다.

-로그온 시 암호 설정 해제
시작 > 실행 > control userpasswords2 > 확인 > 사용자계정 > 사용자이름과 암호를 입력해야 이 컴퓨터를 사용할수 있슴에 선택를 해제함 > 확인 > 창이 하나 나오면 여기에 설치시 설정한 암호를 적고 확인 합니다.

-Internet Explorer 세팅 및 인터넷 최적화 
* 도구 > 인터넷 옵션 > 일반 > 임시 인터넷 파일항목에서 설정 > 임시 인터넷 파일 폴더항목에서 사용할 디스크 공간을 자신의 하드디스크 용량에 맞춰 폴더 변경 및 적당한 공간  설정.
* 도구 > 인터넷 옵션 > 일반 > 열어본 페이지 목록항목에서 페이지 보관 일수를 적당히 설정.
* 도구 > 인터넷옵션 > 보안 > 인터넷 보안을 보통으로 변경.
※ 제어판 > 프로그램 추가/제거 > windows 구성요소 추가/제거 > windows구성요소 마법사 > Internet Exporer 보안 강화 구성을 선택 해제하고 자세히를 선택하여 관리자 그룹용과 기타사용자 그룹용 선택 해제 한 후 다음을 선택하면 인터넷옵션 보안에는 보통으로 변경 가능.
* 도구 > 인터넷 옵션 > 개인정보탭에서 설정항목을 낮음으로 설정.
* 도구 > 인터넷 옵션 > 연결 > LAN설정항목에서 자동 구성, 프록시 서버 모든 선택를 해제.
* 도구 > 인터넷 옵션 > 프로그램 > 시작할때 기본 브라우저 확인에 선택 해제.
* 도구 > 인터넷 옵션 > 고급 에서
> 멀티미디어 > 이미지 크기 자동조정가능에 선택 해제.
> 보안 > 브라우저 닫을때 임시 인터넷 파일 폴더 비우기에 선택. (시스템을 항상 유지시킬 분만 추천)
> 탐색 > 예약시 동기화할 오프라인 항목 사용에 선택해제.
> 탐색 > 웹페이지 단추 및 컨트롤 시각 스타일 사용에 선택해제.
> 탐색 > 인라인 자동 완성사용에 선택해제.
> 탐색 > 주소표시줄에 [이동] 단추 표시에 선택 해제.
> 탐색 > 타사브라우저 확장 사용에 선택 해제.(다시 시작해야 함)
> 탐색 > URL을 항상 UTF-8로 보냄에 선택 해제.

-작업표시줄의 인터넷 익스플로러창 합쳐지는것 막기
시작 > 제어판 > 작업표시줄 및 시작메뉴 > 같은 종류의 작업 표시줄 단추를 그룹(G)으로에 선택 표시 해제.

-미리 보기 캐쉬로 인한 메모리 사용량 과대 방지
윈도우탐색기 > 도구 > 폴더 옵션을 실행 한 후 미리 보기 캐쉬 안 함 선택.

-내 문서 폴더 저장위치 변경하기
내 문서 > 속성 > 대상 폴더 위치에서 변경.

-탐색기의 폴더 옵션 설정 
탐색기 > 도구 > 폴더옵션 > 보기 > 고급옵션 >
보호된 운영체제 파일 숨기기에 선택 해제,
숨김 파일 및 폴더 표시에 선택,
시스템 폴더 내용 표시에 선택,
알려진 파일 형식의 확장명 숨기기에 선택 해제,
암호화 되거나 압축된 NTFS 파일을 컬러로 표시에 선택 해제,
폴더 및 바탕 화면 항목에 팝업설명표시에 선택 해제,
폴더팁에 파일 크기 정보 표시에 선택 해제.
폴더 보기 항목에 모든 폴더에 적용을 선택.

-휴지통 설정
휴지통 > 속성 > 일반설정 > 휴지통의 최대 크기를 5%로 삭제 확인 대화상자 표시에 선택를 해제 합니다.

-XP 처럼 디스플레이 사용하기
내컴퓨터 > 속성 > 고급 > 성능 > 설정 > 시각효과 > 두번째 최적모양으로설정 > 선택 > 확인합니다.

-윈2003 작업중단방지
* 제어판 > 디스플레이 > 디스플레이 등록정보 > 화면보호기 > 다시 시작할 때 암호로 보호에 선택를 해제 합니다. 
* 제어판 > 디스플레이 > 디스플레이 등록정보 > 화면보호기 > 전원 > 고급 > 컴퓨터가 대기 모드에서 나올 때 암호로 묻기에 선택 해제 합니다.

-내문서나 미디어플레이어 사용후에 흔적 지우기.
시작 > 실행 > gpedit.msc > 그룹정책개체편집기 > 사용자구성 > 관리템플릿 > 작업표시줄및시작메뉴
* 종료시 최근에 사용한문서 기록지우기를 더블클릭 > 사용선택후 확인
* 최근에 사용한 문서 기록을 보관안함을 더블클릭 > 사용선택후 확인

-종료 속도 빠르게 하기
시작 > 실행 > gpedit.msc > 그룹정책개체편집기 > 컴퓨터구성 > 관리템플릿 > 시스템 > 사용자프로필 > 프로필 언로드 및 
업데이트의 재시도 최대횟수를 더블클릭 > 사용을 선택후 재시도횟수를 0 으로 수정합니다.

 

Step 05. 최적화 팁 (레지스트리 부분)

[1] 메뉴 팝업속도 향상하기
HKEY_CURRENT_USER\ControlPanel\desktop - MenuShowDelay → 0

[2] MSIE 로딩속도(DNS 캐쉬수정) 향상하기
* HKEY_LOCAL_MACHINE\System\CurrentControlset\Services\Dnscache\Parameters
새로만들기(DWORD - 10진수) 
CachehHashTableBucketSize---->1 
CachehHashTableSize---------->384 
MaxCacheEntryTtlLimit-------->64000 
MaxSOACacheEntryTtlLimit----->301 
* HKEY_USER\.Default\Software\Microsoft\Windows\CurrentVersion\InterSettings
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\InterSettings
새로만들기(DWORD - 16진수) 
MaxConnectionsPerSever------>20 
MaxConnectionsPer1_0Sever--->20 
* HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RemoteComputer\
NameSpace에서 {D6277990-4C6A-11CF-8D87-00AA0060F5BF} 폴더 자체를 삭제

[3] 폴더창 팝업속도 향상하기
HKEY_CURRENT_USER\Control Panel\desktop\windowmetrics 
새로만들기(문자열 값) 
MinAnimate ----> 0

[4] 아이콘의 화면출력(Refrash rate) 속도향상하기
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Update 
UpdateMode ----> 0

[5] L2캐쉬 지정으로 속도향상하기
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\MemoryManagement 
SecondLevelDataCache ----> L2 캐쉬값 입력 (예:512)

[6] 디스크 캐쉬 세부 설정 - 하드속도 향상하기
별도의 하드 캐쉬 램이 있는 사용자(레이드 카드에 램이 장착된 경우)는 필요없습니다.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management 
IoPageLockLimit ----> 40000(512MB기준)

[7] 로그온 메시지
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Winlogon
새로만들기(문자열 값) 
LegalNoticeText ----> 더블클릭후 편집상자에 메시지 입력

[8] 공유문서 삭제/감추기
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\DelegateFolders
59031a47-3f72-44a7-89c5-5595fe6b30ee ----> 삭제

[9] 도움말메뉴 삭제하기
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer
새로만들기(DWORD - 10진수) 
NoSMHelp ----> 1 (0으로 하면 복원됨)

[10] 최근문서메뉴 삭제하기
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer
새로만들기(DWORD - 10진수) 
NoRecentDocsMenu ----> 1

[11] 입력도구모음/고급텍스트 삭제
* 시작 메뉴바에서 입력도구모음 언선택 
* cmd>%SystemRoot%\System32\Regsvr32.exe /u %SystemRoot%\System32\msimtf.dll 
%SystemRoot%\System32\Regsvr32.exe /u %SystemRoot%\System32\msctf.dll 
* RegSvr32 확인 
* Ctrl-Alt-Del(작업관리자) - 프로세스 - ctfmon.exe - 끝내기 - 확인 
* HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run - ctfmon.exe 삭제

[12] 윈도즈 메신져 삭제메뉴 추가
windows/inf/sysoc.inf 
msmsgs=msgrocm.dll,OcEntry,msmsgs.inf,hide,7 `hide` 제거 
msmsgs=msgrocm.dll,OcEntry,msmsgs.inf,7

[13] 종료 빠르게 하기
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitTokillServiceTimeout : 20000 → 2000 로 수정

[14] 무응답 응용프로그램 타임아웃 시간줄이기
HKEY_CURRENT_USER\Control Panel\Desktop에서 HungAppTimeout 값 5000(5초) → 1000 (1000 = 1초) 로 수정 

posted by 방랑군 2009. 10. 7. 11:24

참조 : http://dalbong2.net/entry/C-20-iterators
         http://www.hoons.kr/board.aspx?Name=cshaptip&BoardIdx=1021&Page=1&Mode=2

1. Iterators

using System; 
using System.Collections.Generic; 
class Test 

  public static void Main() 
  { 
       foreach (string s in GetItems()) 
           Console.WriteLine(s); 
  }

  private static IEnumerable GetItems() 
  { 
       yield return "Hello yield 1"; 
       yield return "Hello yield 2"; 
       yield return "Hello yield 3"; 
       yield return "Hello yield 4"; 
       yield return "Hello yield 5"; 
  } 


"yield return" 문이 있는데, iteration의 다음 값을 반환한다고 한다. 
"yield break" 문도 있단다. 

『The yield return statement produces the next value of the iteration. 
  The yield break statement indicates that the iteration is complete.』 

GetItems() 메소드의 리턴 타입이 IEnumerable 이라는 것도 주목할 부분이다. 


참조 문서 
c# 2.0 iterators - 
http://community.bartdesmet.net/blogs/bart/archive/2006/07/06/4121.aspx

2. Partial

// MyForms1.cs
partial public class MyForms
{
  public BusinessLogic(){}

// MyForms2.cs
partial public class MyForms
{
  public PresentationLogic(){}
}

Partial 클래스는 하나의 클래스를 여러 개의 파일로 나누어 작성할 수 있는 기능이다. 이 기능은 Windows Forms이나 Web 응용 프로그램을 협업으로 개발해 왔다면 가장 크게 매력을 느낄 것이다. Partial 클래스를 이용하면 한 클래스를 여러 가지 로직(비즈니스 로직과 프리젠테이션 로직)으로 나누어 개발할 수 있다. 물론 각 로직을 각각의 클래스로 구현하는 것이 바람직했지만, Forms 클래스는 어쩔 수 없이 여러 로직이 공존할 수 밖에 없는 경우가 많았다(특히 프리젠테이션 로직은 자동으로 생성되는 코드가 대부분이다). 비단 그러한 문제가 아니더라도 여러 명의 개발자가 자신이 맡은 메쏘드를 나누어서 개발할 수 있다면, 이보다 더 좋은 협업 방법이 없을 것이다. 이는 형상 관리 측면에서도 큰 이점을 제공한다.

Partial 클래스는 기존의 클래스 앞에 partial 키워드를 추가하여 작성할 수 있다. 물론, partial 키워드를 사용한 클래스는 여러 파일에 나뉘어 존재할 수 있다.
위 소스의 MyForms 클래스는 비즈니스 로직을 구현한 MyForms1.cs 파일과 프리젠테이션 로직을 구현한 MyForms2.cs 파일로 나뉘어져 있다. 컴파일러는 이와 같이 나뉘어져 있는 파일을 조합하여 하나의 MyForms 클래스를 작성한다.

Partial 클래스를 작성할 때 다음과 같은 사항을 유의해야 한다.

1. Partial 클래스는 동일한 어셈블리/모듈(dll 또는 exe)에 존재해야 한다.
2. 한번이라도 partial로 선언된 클래스는 모두 동일하게 partial로 선언되어야 한다.

partial public class MyForms {}

public class MyForms {} // 컴파일 오류

3. Generic으로 사용될 매개 변수들이 일치해야 한다.
4. public/private/protected/internal 등을 사용할 수 있다.
5. 중첩된 클래스에 대해서도 Partial 클래스를 작성할 수 있다.
6. Partial 클래스에 적용된 특성(Attribute)들은 컴파일 시에 모두 병합된다.

3. Nullable
 만약 값 타입과 참조 타입의 큰 차이점이 무엇이냐고 묻는다면, 널(null) 값을 설정할 수 있는지의 여부일 것이다. 참조 타입은 널 값을 설정할 수 있는 반면 값 타입은 불가능하다. 이는 값 타입 입장에서 보면, 상당히 불합리한 처우가 아닐 수 없다. 왜 값 타입은 언제나 초기화가 필요한 것일까? 참조 타입은 널 값을 설정함으로써 구체적으로 객체를 생성하는 것을 뒤로 미룰 수 있지만, 값 타입은 변수를 선언함과 동시에 개발자가 원하든 원하지 않든 간에 어떤 값으로 설정되기 때문에 개발자가 할 수 있는 일이라곤 0이나 -1을 널 대신 사용하는 정도이다. 0과 -1이 해당 변수에서 특별한 의미를 지니고 있다면, 그나마도 불가능하다.

Nullable 타입은 기본 타입에 물음표(?)를 추가하여 선언한다. 예를 들어, int?와 같이 선언하면 기본 타입인 int의 Nullable 타입이 선언된다. 이 때 선언된 타입은 널인지에 대한 여부를 확인할 수 있는 기능을 지원한다는 점을 제외하면 내부적으로 기본 타입(int 형)과 동일하다. 이와 같은 기능이 가능한 이유는 바로 Generic 덕분이다.

 <리스트 3> Nullable 타입의 예

int? x;
if (x != null)
  Console.WriteLine(x.Value);
else
  Console.WriteLine("Null");

C# 언어 스펙을 보면 Nullable 타입은 다음 <리스트 4>와 같이 HasValue와 Value 속성을 노출하는 Generic 구조체이다. 이때 HasValue가 false이면 널인 경우이고 HasValue가 false일 때, Value 속성 값을 설정하면 System.InvalidOperationException 예외가 발생하도록 구현되어 있다.

 <리스트 4> Nullable Generic 클래스의 기본 구조

public struct Nullable where A : struct {
  bool HasValue { get; }
  A Value { get; }

  public Nullable(A value);
}

따라서 int? x = 123; 과 같은 코드를 작성하면 컴파일러는 Nullable x = new Nullable(123); 을 생성한다.

지금까지 Nullable 타입에 대해서 간단하게 살펴보았는데, Nullable 타입은 탄생 배경부터 여러 가지 이슈들을 동반하고 있다(예를 들면, int?와 int??의 사용). 따라서 Nullable 타입에 관한 보다 자세한 정보는 MSDN의 블로그를 통해서 확인하도록 한다.@




'IT > C#' 카테고리의 다른 글

닷넷 트랜잭션 정리  (0) 2009.09.30
C#2.0 , C# 3.0 New Features  (0) 2009.09.15
C# 3.0 개요  (0) 2009.09.11
[C# 2.0] Generics, Iterator, Anonymous, Partial  (0) 2009.08.24
[.net Framework] System.Activator 객체  (0) 2009.08.24
posted by 방랑군 2009. 10. 7. 10:47

미니 팝업창

트레이 아이콘


모니터 제어

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        // 모니터 ON/OFF 관련

        const int WM_SYSCOMMAND = 0x0112;
        const int SC_MONITORPOWER = 0xF170;
        const int MONITOR_ON = -1;
        const int MONITOR_OFF = 2;
        const int MONITOR_STANBY = 1;

        [System.Runtime.InteropServices.DllImport("User32")]
        private static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SendMessage(this.Handle.ToInt32(), WM_SYSCOMMAND, SC_MONITORPOWER, MONITOR_OFF);
        }
    }
}

posted by 방랑군 2009. 10. 6. 09:24


직렬화란 무엇인가
영어 원어로부터 이야기를 시작해 보겠다. 시리얼(serial)이라는 표현은 영어 사전을 찾아보면 영화나 TV의 연속물, 연재물을 뜻하는 명사이거나 ‘연속적인’, ‘순차적인’이라는 의미의 형용사라는 것을 알 수 있다. 여기서 요점은 ‘순서가 있는 연속물’이라는 점이다. 2부를 1부보다 먼저 하는 경우는 없다. 컴퓨터 제품이나 소프트웨어를 구입하면 시리얼 번호라는 것을 흔하게 볼 수 있다. 시리얼 번호의 한글 번역은 ‘일련 번호’에 해당한다. 각 제품의 순차적인 번호를 적은 것이다.
serialize는 ‘serial하게 만든다’는 뜻의 동사로서, 연재물로 상영한다 또는 순서대로 나열하다라는 뜻이다. 최종적으로 이 동사의 명사화인 serialization은 ‘무엇인가를 연속적인 형태로 나열하는 행위’를 말한다.
정의하자면, 직렬화란 우리가 프로그램에서 다루고자 하는 모든 객체를 쉽게 저장하거나 네트워크로 전송할 수 있게, 컴퓨터의 가장 원초적인 자료 표현 형식인 바이트(byte)의 연속 형태로 변환하는 과정을 말한다. 당연히 디스크에 파일 형태로 저장되어 있거나 네트워크를 통해 전송받아 메모리에 저장한 바이트 연속물(byte stream)을 다시 원래의 객체로 변환하는 복원 과정도 항상 고려해야 한다. 이를 de-serialization이라 한다

[출처] 시리얼라이즈|작성자 썬더스

'IT > 기본에충실' 카테고리의 다른 글

값, 참조 타입  (0) 2009.09.30
[ASP.NET] 페이지 CacheTest  (0) 2009.09.15
[C#] pdb 파일  (0) 2009.09.15
[ASP.NET] Transfer, Redirect, Excute..  (0) 2009.09.15
기본... 여기는...  (0) 2009.09.15
posted by 방랑군 2009. 9. 30. 15:04
변수는 값 타입과 참조 타입이 있으며 값 타입에는 int, double, char 등이며 참조 타입은 class 등입니다. 

 값 타입은 스택이라는 영역의 메모리에 저장됩니다. 

 반면에 참조 타입은 new라는 연산자를 통해서 객체가 생성되면 멤버변수들은 힙이라는 영역의 메모리에 저장되며 이 객체 변수는 힙 영역에 메모리를 가리키는 주소값을 가지며 스택에 저장이 됩니다. 
그래서 참조 타입이라고 불립니다.

'IT > 기본에충실' 카테고리의 다른 글

Serialize  (0) 2009.10.06
[ASP.NET] 페이지 CacheTest  (0) 2009.09.15
[C#] pdb 파일  (0) 2009.09.15
[ASP.NET] Transfer, Redirect, Excute..  (0) 2009.09.15
기본... 여기는...  (0) 2009.09.15
posted by 방랑군 2009. 9. 30. 14:20

참조 : http://resisa.tistory.com/34


이번 프로젝트를 하면서 트랜잭션에 대해서 다시 한번 생각해보게 되었고 아래의 사이트들을 통해서 좋은 정보를 얻었다.

트랜잭션에 대한 정리를 해놓은 MS 장현춘 부장님의 블로그 링크이다.
http://kingcrap.com/entry/닷넷-트랜잭션-정리

System.Transactions(TransactionScope)
대해서 정리를 해놓은 드원테크놀로지의 유경상 수석님의 블로그링크이다.
http://www.simpleisbest.net/articles/996.aspx


위을 내용을 아주 간단히 요약을 해보겠다~
먼저 트랜잭션 처리는 1. 로컬 트랜잭션(수동) 2. 분산 트랜잭션(자동)으로 나뉜다. 가지의 방법은 서로 장단점있는데 속도의 측면에서는 로컬 트랜잭션이 편리성 측면에서는 분산 트랜잭션이 좋다. 하지만 TransactionScope 사용하면 Promotion이라는 기능이 있고(TransactionScope 트랜잭션이 발생할  로컬 또는 분산 트랜잭션인지를 자동으로 처리해주는데 로컬 트랜잭션으로 실행하다가 다른 DB 접속을 하는 순간에 자동으로 분산 트랜잭션으로 전환이 되는데 이러한 것을 Promotion이라고 한다.) 이러한 Promotion MSSQL 2005, 2008에서만 지원을 한다고 한다.
이번에 내가 프로젝트에서 DB Oracle여서 TransactinoScope 사용하려고 했더니 oramts.dll 필요하다며 예외가 발생했다. Ora MTS 설치하면 TransactionScope 사용할 있었다.

Ora MTS
대해서는 아래의 링크를 보자.
http://www.simpleisbest.net/archive/2005/08/23/208.aspx

다음은 Ora MTS 다운받는 링크이다.
http://www.oracle.com/technology/software/tech/windows/ora_mts/htdocs/utilsoft.html

테스트 환경은 윈도우 서버 2003에서 Oracle 9i 클라이언트와 Ora MTS 9.2.0.7.0 버전을 사용해서 해본 결과 TransactionScope 사용할 있었다. 위의 첫번 링크(장현춘님) 가보면 비스타에서도 Ora MTS 10.2.0.4.0버전을 사용해서 분산 트랜잭션으로 MSSQL Oracle 묶어 프로젝트에서 사용하고 있다는 말이 제일 마지막에 나온다. 하지만 비스타에서 Ora MTS(버전:10.2.0.1, 10.2.0.2) 설치 오류가 나서 테스트를 해볼 수가 없었고 Ora MTS 10.2.0.4.0버전을 구할 수도 없었다. 아마 무엇인가 문제가 있어서 배포를 잠시 중단한게 아닌가 싶다.

<<
수정일자 : 1220>>
Ora MTS 10.2.0.4.0
버전이 아니라 Oracle Database 10g Release 2 (10.2.0.4.0) Patch Set 버전이다. Ora MTS 10.2.0.2.0 설치하면 된다. 또한 Ora MTS 오류가 나는 것의 원인은 Office 2007 때문이였다. 설치를 하다가 javaw.exe프로세스가 종료되었다는 메시지와 함께 설치가 종료되는데 Office 지우고 설치를 하면 설치가 된다. 이것이 설치되었다고 해서 비스타에서TransactionScope 사용해서 분산 트랜잭션을 사용할 있는 것이 아니다. Oracle Database 10g Release 2 (10.2.0.4.0) Patch Set까지 설치해야한다. Oracle Meta Link에서 이것을 다운을 받을 있는데 Meta Link 오라클과 계약을 맺어 인증번호가 있어야 사용할 있다. 패치까지 받고 테스트는 안해봤지만 아마도 것이다사용자등록을 했는데 관리자가 있어 패스워드를 받아야한다. 하나 해보기 힘들다. 차후에 패치를 받고 테스트를 마친후에 정리를 해야할꺼 같다.

저작자 표시비영리


기사 보기...

'IT > C#' 카테고리의 다른 글

C#2.0 Iterators,Partial 클래스,Nullable 타입  (0) 2009.10.07
C#2.0 , C# 3.0 New Features  (0) 2009.09.15
C# 3.0 개요  (0) 2009.09.11
[C# 2.0] Generics, Iterator, Anonymous, Partial  (0) 2009.08.24
[.net Framework] System.Activator 객체  (0) 2009.08.24
posted by 방랑군 2009. 9. 30. 14:10



올해 초에 웹타임 교육센터에서 교육을 받은 내용을 나름대로 정리한 내용이다.

내용은 많고 시간은 부족(?)해서 설명 부분이 많이 부족하다.

그래서 버전은 0.9이다.. +_+

차후에 보완 수정하여 더욱 더 유용한(?) 자료로 거듭났으면 좋겠다 ㅋ

posted by 방랑군 2009. 9. 30. 14:04

참조 :http://elky.tistory.com/215

1 . 데이터의 결합방법

1) 가로로 연결 : JOIN

     - 의미 있는 연결을 위해서는 로우(ROW)의 공통 요소를 이용하여 연결할 경우 사용

2) 세로로 연결 : UNION

     - 컬럼(Colum)의 공통된 형식을 어기면 연결 불가

2 . JOIN

가로(수평적)로 하나의 결과 집합과 다른 결과 집합을 연결하는 것

(집합 : 테이블, 뷰, 인라인뷰, 테이블변수....)

조인의 종류

 ◎ INNER JOIN

 ◎ OUTER JOIN (LEFT , RIGHT 모두)

 ◎ FULL JOIN

 ◎ CROSS JOIN

 ◎ SELF JOIN

1) INNER JOIN

 두 집합간의 하나나 그 이상의 공통 필드들에 기반해서 레코드들을 일치

 INNER JOIN 은 배타적(exclusive) 결합 이다.

 두 집합(테이블) 모두에서 일치하는 것이 없으면 그 레코드는 반환되지 않는다.

 ▷ 구문

<ANSI>

 SELECT <선택_목록>

 FROM <결과집합1> INNER JOIN <결과집합2>  ON <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 

 SELECT <선택_목록>

 FROM <결과집합1> JOIN <결과집합2>  ON <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 

<T-SQL>

 SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2>  WHERE <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 ▷ 예제

       USE Pubs

       SELECT discounttype ,discount ,s.stor_name

       FROM discounts d JOIN stores s

                               ON d.stor_id = s.stor_id

1) OUTER JOIN

JOIN 이전에 나오는 테이블은 왼쪽(LEFT) 테이블이 되고 , JOIN 이후에 나오는 테이블이 오른쪽(RIGHT) 테이블이 된다.

LEFT OUTER JOIN 은 왼쪽 테이블로부터 모든 정보를 포함시키며

RIGHT OUTER JOIN 은 오른쪽 테이블로부터 모든 정보를 포함시킨다

 ▷ 구문

 <ANSI>

 SELECT <선택_목록>

 FROM <결과집합1> LEFT OUTER JOIN <결과집합2>  ON <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 

<T-SQL>

 SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2>  WHERE <결과집합1>.<조인조건1> *= <결과집합2>.<조인조건2>

 <ANSI>

SELECT <선택_목록>

 FROM <결과집합1> RIGHT OUTER JOIN <결과집합2>  ON <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 

<T-SQL>

SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2>  WHERE <결과집합1>.<조인조건1> =* <결과집합2>.<조인조건2>

 

▷ 예제

       USE Pubs

       SELECT discounttype ,discount ,s.stor_name

       FROM discounts d LEFT OUTER JOIN stores s

                               ON d.stor_id = s.stor_id

       USE Pubs

       SELECT discounttype ,discount ,s.stor_name

       FROM discounts d RIGHT OUTER JOIN stores s

                               ON d.stor_id = s.stor_id

 

※ OUTER JOIN 을 이용하여 일치하지 않는 레코드들 찾기

-- 할인 레코드를 가지지 않은 모든 상점들의 이름 찾기

 

       USE Pubs

       SELECT s.stor_name AS [Store Name]

       FROM discounts d RIGHT OUTER JOIN stores s

                               ON d.stor_id = s.stor_id

       WHERE d.stor_id IS NULL

3) FULL JOIN

JOIN 양쪽의 데이터를 모두 일치 시켜서 양쪽 모두를 포함시키는 것이다.

어느쪽에도 중점을 두지 않고 양쪽 모두의 데이터를 보려 할 때를 위하여 만들어진 것

간단히 FULL JOIN 은 RIGHT JOIN 과 LEFT JOIN 을 동시에 적용하는 것이라 할 수 있다.

 ▷ 구문

<ANSI>

 SELECT <선택_목록>

 FROM <결과집합1> FULL JOIN <결과집합2>  ON <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 

<T-SQL>

 SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2>  WHERE <결과집합1>.<조인조건1> *= <결과집합2>.<조인조건2>

 UNION

 SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2>  WHERE <결과집합1>.<조인조건1> =* <결과집합2>.<조인조건2>

▷ 예제

       USE Pubs

       SELECT discounttype ,discount ,s.stor_name

       FROM discounts d FULL JOIN stores s

                               ON d.stor_id = s.stor_id

4) CROSS JOIN

한쪽의 모든 레코드를 그 반대쪽의 모든 레코드들과 결합시킨다.

간단히 CROSS JOIN 은 '데카르트의 곱(Cartesian product)' 이라 할수 있다

CROSS JOIN 의 구문 구조는 ON 연산자가 없다는 점만 빼고는 다른 JOIN 들과 동일하다.

테스트용 데이터를 만드는 용도로 사용한다.

 ▷ 구문

<ANSI>

 SELECT <선택_목록>

 FROM <결과집합1> CROSS JOIN <결과집합2> 

 

<T-SQL>

 SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2> 

▷ 예제

       USE Pubs

       SELECT discounttype ,discount ,s.stor_name

       FROM discounts d CROSS JOIN stores s

5) SELF JOIN

필요에 의해 JOIN 구문에 같은 테이블이 두번 이상 등장하는 경우이다.

 

자신의 상급자를 매핑하기위해 SELF 조인을 사용한 예제이다.

▷ 예제

       USE Northwind

       SELECT a.EmployeeID, a.LastName, a.FirstName, b.EmployeeID, b.LastName, b.FirstName

       FROM employees a, employees b

       WHERE a.reportsTo = b.employeeid

2 . UNION

2개이상의 데이터 집합을 세로(수직적)로 연결하는 방법으로

결합되는 각 컬럼간의 형식이 일치하면 하나의 집합으로 도출 가능하다.

 

▷ 주의점

 ◎ UNION 으로 쿼리들을 결합할 때, 모든 쿼리들의 SELECT 목록에 있는 열들의 개수는 같아야 한다.

 ◎ 결합된 결과의 제일 처음에 나타날 헤더들은 오직 첫번째 쿼리에 의해서만 결합된다.

 ◎ 결합될 쿼리들의 각 열들은 동일한 데이터 형식이거나 적어도 묵시적으로 변환될 수 있는 것들이어야 한다.

 ◎ UNION 의 경우 기본적으로 DISTINCT 가 적용된다. 중복된 행을 표시하고 싶들떄는 UNION ALL 을 사용한다.

 

Northwind 에 관련된 모든사람에게 우편물을 보내고자 할 때의 UNION 을 통해 모든 사람의 주소를 가져오는 쿼리

▷ 예제

       USE Northwind

 

       SELECT CompanyName as Name, Address, City, Region, PostalCode, Country

       FROM Customers

       UNION

       SELECT CompanyName , Address, City, Region, PostalCode, Country

       FROM Suppliers

       UNION

       SELECT FirstName + ' ' + LastName , Address, City, Region, PostalCode, Country

       FROM Employees

 
3 . 요약

RDBMS 에서는 데이터를 둘 이상의 테이블에 분산시켜야 하는 경우가 많다.

따라서 JOIN 및 UNION 을 이용하여 여러 테이블들의 있는 데이터를 결합시켜 사용 할 수 있다.

 ◎ 일치하지 않는 열들을 제외하고자 할 경우에는 INNER JOIN 을 사용한다.

 ◎ 일치하는 것들을 뽑아야 할 뿐만 아니라, JOIN의 한 쪽에 있는 테이블의 모든 것들을 포함시키려 할 때는 OUTER JOIN 을 사용한다.

 ◎ 일치하는 것들을 뽑아야 할 뿐만 아니라, 양쪽에 있는 테이블의 모든 것들을 포함시키려 할 때는 FULL JOIN 을 사용한다.

 ◎ 두 테이블의 대해 행들에 기반한 데카르트 곱을 수행하려 할 때에는 CROSS JOIN 을 사용한다. 과학계산이 필요하거나 테스트 데이터를 생성할때 유용하다.

 ◎ 여러 쿼리들의 결과를 수직적으로 결합할 때에는 UNION 을 사용한다.

posted by 방랑군 2009. 9. 30. 14:03

참조 : http://elky.tistory.com/214


용어 정리
Driving Table : 조인에서 기준이 되는 테이블 (= Outer Table)
Drived Table : 조인에서 결합 되어지는 테이블 (= Inner Table)

Nested Loop
- 두개 이상의 테이블에서, 하나의 집합을 기준으로 상대방 테이블의 Row를 결합하여 원하는 결과를 추출하는 방식. (기준 테이블 한 행당, 상대 테이블 전체가 수행된다.)
- 부분 범위 처리 가능 (정지, 재개 가능. 예를 들어 조건에 만족하는 데이터 1000개만 얻어낸 상태에서, 요청이 들어올경우 1001~2000번째 값을 얻어오는 것이 가능)
- Driving Table에서 상대 테이블로 비교할 데이터 량이 적은 것이 효율에 좋다.
- 기준 테이블과 상대 테이블 간에 서로 대응하는 값에 인덱스가 걸려있는 것이 효율에 좋다.
- 특정 범위만 알아오는 쿼리에 유용.
- Any Join에서 사용 됨.

Sort Merge
- 쿼리에 따라 기준 테이블, 상대 테이블 각각 조인에 포함될 데이터들만 추려내 테이블로 구성한 후 (집합을 구성), 추린 테이블의 데이터를 정렬한다.
(상황에 따라 테이블 전체를 정렬해서 사용하는 경우도 있다.)
- 두 테이블의 크기가 다를 경우, 유후 시간 발생 (정렬 되는 시간이 동일하지 않기 때문에)
- 지그 재그 계단식 비교 방식을 취함 (읽고 있는 데이터 포인터를 기억한 후, 다음 데이터를 읽을 때 이미 읽은 위치를 다시 읽지 않는 방식으로 검색량을 줄인다.)
- 지그 재그 계단식 비교를 하기에, 겹치는 값이 존재할 경우 이미 읽은 데이터를 다시 읽어야 되는 상황이 발생하기도 한다. (같은 값이 여러개일 경우, 방금 읽었던 값도 또 읽어야 하기에) 그래서, 겹치는 값이 존재할 경우 DBMS가 Hash Join을 사용할 가능성이 높다.
- 추려진 결과가 한번에 나오고, 그 전에는 결과를 낼 수 없기에, 처리 속도가 중요한 쿼리에서는 사용되지 않는다.
- Any Join 에서 가능 하지만 주로 Equal Join 에서 유용.

Hash

- 테이블 내의 모든 데이터에 해시 함수를 적용하여 해시 버킷에 담는다. 값 별로 버킷에 나누어 담기에, 해당 버킷을 읽음으로써 같은 값을 사용하는 집합에 억세스. (버킷에 담긴 데이터를 연속으로 읽을 수 있으므로)
- 해시 테이블 구성 비용 (CPU, 메모리)이 크다.
- 값 별로 버킷에 담기기에 버킷 억세스는 같은 값을 찾는 경우에만 빠르다. 그래서, Equal Join 에서만 가능하도록 되어있다.

posted by 방랑군 2009. 9. 30. 14:02
참조 :http://elky.tistory.com/212

1. Clustered Index만 존재했을 때
CI의 정렬 기준으로 실제 데이터를 정렬해 둡니다. 데이터를 찾을 때 CI를 타느냐, 테이블 스캔 하느냐의 차이만 존재합니다. 

1-2. 구조
루트페이지와 리프페이지의 2중 구조

루트페이지에는  검색기준이  리프페이지에는 실제 데이터가 검색기준에 맞쳐 분류되어있음

쿼리시  루트 페이지에서 해당 검색기준을 통해 리프페이지(실제데이터)를 검색하여 결과처리

데이터 변경작업시 루트페이지에 맞쳐서  리프페이지를 다시 분류작업함

2.
Non-Clustered Index만 존재했을 때

이 경우 NI의 키 값 대로 정렬된 데이터가 존재하고, 키 값에 대응하는 실제 데이터의 주소 (파일, 페이지, 행번호) 를 가집니다.

NI에서의 키 값에 매칭되는 값을 찾은 후, 실제 데이터를 찾아가는 과정만큼의 비용이 필요합니다.
이 비용이 크기 때문에, 일반적으로 NI를 이용해서 찾는 데이터가 전체 데이터의 3~5%이내 일 때만 NI를 이용하고, 그렇지 아닐 경우 테이블 스캔을 합니다.

2-1. 구조
루트페이지와 리프페이지. 실제데이터의 3중구조.

루트페이지에는 검색기준, 리프레이지에는 실제데이터를 참조한 분류 ,실제데이터에는 데이터

select 시에는 3중구조임으로 클러스터형 인텍스보다 비효율적임

그러나. 데이터 변경작업시에는 실제데이터에는 변경이 없음으로 클러스터형 보다 효율적.

3. Non-Clustered Index와 Clustered Index 공존시

이 경우 NI가 실제 데이터의 행번호를 가리키는 것이 아니라, CI의 키 값을 가리킵니다.

장점은 CI가 변경될 때, NI에 적은 영향을 줍니다. (CI로 정렬 되어 있는 만큼, 테이블 중간에 데이터가 끼어들거나 삭제되면 페이지 분할등이 일어나 행번호가 바뀔여지가 있습니다. 행번호가 바뀌어도 행번호가 아니라, CI의 키 값을 가리키기 때문에 NI에 적은 영향만을 주고 데이터를 변경할 수 있게 됩니다.)

3-1. 구조
루트페이지(비클러스터형)  -> 리프페이지 (비클러스터형) ->  루트페이지 (클러스트형) -> 리프페이지 (클러스트형) 의 4중구조 (실제데이터는 리프페이지 - 클러스트형)

'IT > DB' 카테고리의 다른 글

데이터 결합 방법 정리  (0) 2009.09.30
MS-SQL 조인 내부 처리 방식 정리  (0) 2009.09.30
인덱스 정리  (0) 2009.09.30
인덱스가 있지만 인덱스를 안 타는 경우  (0) 2009.09.30
MS-SQL 실행 계획 확인  (0) 2009.09.30
posted by 방랑군 2009. 9. 30. 14:01

참조 : http://elky.tistory.com/211

데이터를 찾는 과정이 필요한 모든 일 (Select, Update, delete, Insert 모두) 에 영향을 준다.

데이터를 빠르게 찾기 위해 필요하다.

인덱스 추가시 인덱스 관리 비용(처리하는 일, 인덱스 관리용 공간 필요)

인덱스는 항상 타는게 아니다. 인덱스를 탈 때 통계를 참고하는데, 이 통계가 최적 수행 방법을 산출하려면, 통계가 최신에 가까워야 좋다.

하지만, 통계 갱신에는 비용이 존재하므로, 적절한 수위를 유지하는 것이 좋다.

인덱스가 걸려 있는 경우에는 정렬이 필요하다.  1Page가 꽉 찬 상태에서, 데이터가 중간 삽입 될 경우, 들어갈 데이터를 포함해 데이터를 반으로 쪼개서 두개의 페이지에 넣는다. 이 것을 페이지 분할이라 부른다. 

페이지 분할이 자주 일어날꺼라 생각되면 인덱스 생성시 채우기 비율 설정으로, 미리 페이지 분할 해두는 것이 가능하다.

이렇게 할 경우, 페이지를 여러개로 나누는 만큼 페이지를 읽어오는 양이 늘어나는 부담이 생긴다.
검색에 사용된 인덱스가 유니크 인덱스일 경우에는, 데이터를 찾자마자 검색 과정을 중단하면 되기에 검색시에 더 빠르다.

인덱스 검사하는 법
explain select * from Table_Name where A='a' and B='b' order by C,D,E ;
해당 쿼리문이 인덱스를 타는지 안타는지 알기 위해서는 쿼리문 앞에 explain을 붙여주면 인덱스를 타는지 안타는지 알 수 있습니다.
type의 결과값이 ALL일 경우 인덱스를 타지 않고 있습니다. range,index등일 때 인덱스를 타고 있습니다.(system,const,eq_ref,range,index,ALL,fulltext)
key의 값이 해당 쿼리문이 타고 있는 인덱스입니다.


인덱스 관련 용어 정리
-
Table Scan
인덱스를 사용하지 않고 테이블 전체를 읽는것.

- Index Seek
인덱스를 사용해서 데이터를 찾은 것.

- Random Access
 여러 데이터를 찾을 때, 순차적으로 다음행을 읽지 못하고, 데이터 하나당 검색을 수행해야 하는 경우를 말함.

- Clustered Index (CI) 
실제 데이터를 키에 따라 정렬 하는 것이다.
페이지 분할시 실제 데이터도 분할해야 하는 것이 단점이다.
범위 처리에 일반적으로 유용하다. (쿼리에 따라 다르지만)

- Non-Clustered Index (NI) 
키 + 주소로 설정된 별도의 저장소를 가진다.
일반적으로 CI보다 크기가 작으므로, 한 페이지에 많이 들어간다. 데이터 검색시 페이지 간 이동이 CI보다 적다는 장점이 있다.
키에 따라 검색이 끝나도 실제 주소를 찾으러 가야하기 때문에, 범위 처리가 CI보다 느리다.

Covered Query : Index에 포함된 값만 필요로 해서 (a, b컬럼이 복합 인덱스로 걸려 있을 때 select a, b from table), 인덱스만 읽어서 결과를 보여줄 수 있는 쿼리를 말합니다.

posted by 방랑군 2009. 9. 30. 14:01

참조 : http://elky.tistory.com/210

1. 인덱스  컬럼의 변형
select * from table  where LOWER(name)  ='word';
select * from table  where idx - 1 = 5;
이 처럼 인덱스에 변형을 가하게 되면, DBMS가 인덱스를 이용하지 않는다.

2. NOT 또는 IN 연산자 사용
NOT일 경우 무조건 인덱스를 안타는 것이 아니다.
NOT일 경우에도 인덱스를 타긴 타지만, 일반적으로, NOT에 사용된 값이 아닌 데이터의 비율이 높은 경우가 많기 때문에 인덱스를 타지 않는 경우가 많다.
마찬가지로 IN일 경우에도, IN에 포함된 데이터들의 비율이 매우 높다면 FULL SCAN을 하는 것이 낫다고 DBMS가 판단하면 인덱스를 타지 않는다.


3. 와일드 카드 LIKE문장에서 범위를 전체를 지정시
select * from table  where name like '%word'; 
문자열로 이루어진 값을 인덱스로 잡았을 때, %가 앞쪽에 사용되면 정렬 순서를 사용할 수 없으므로 테이블 FULL SCAN이 이루어진다.

select * from table  where name like 'word%'; 
당연한 얘기지만 쿼리가 이런 경우 인덱스를 탄다. 문자열 정렬 순서를 그대로 이용할 수 있기 때문이다.

4. 복합 컬럼 index에서 조건이 잘못되여 index 가 적용 되지 못하는경우
select * from table where name = 'word' or idx = 5

name과 idx가 둘다 인덱스가 걸려있는 경우라해도, DBMS가 최적의 OR 조건을 뽑기 힘들어, FULL SCAN 하는 경우가 많다.

5. Optimizer 의 선택
select * from table  where name ='word' and  id ='elky'; 

인덱스가 name 과   id로 2개가 있을 경우 id나 name 인덱스 중 하나가 선택될수도 있고, 둘다 선택 될 수도있다.
어떤 방식으로 선택하는냐가 속도에 중요할수도있다. 즉 실행 계획을 추적해서 원하는 결과가 나오도록 관리가 필요하다

'IT > DB' 카테고리의 다른 글

한 테이블에 존재하는 인덱스의 종류에 따른 차이  (0) 2009.09.30
인덱스 정리  (0) 2009.09.30
MS-SQL 실행 계획 확인  (0) 2009.09.30
Inline 쿼리 VS 저장 프로시저  (0) 2009.09.30
SUBQUERY와 INLINE-VIEW의 차이  (1) 2009.09.30
posted by 방랑군 2009. 9. 30. 14:00

참조 : http://elky.tistory.com/218


MSSQL에선 실행 계획을 통해 인덱스를 타는지, 어떠한 쿼리가 더 빠른지 측정할 수가 있습니다.

쿼리
Set Statistics Profile { ON | OFF } -- 쿼리 결과에 실행 계획을 포함
Set Statistics IO {ON | OFF}         -- 페이지의 입출력 수를 알 수 있다.
Set Showplan_All { ON | OFF }     -- 실행 계획만 보는 옵션

실행 계획은 SQL Server 쿼리 프로세서가 각 문을 실행할 때 취한 단계를 나타내는 계층적 트리를 이루는 행 집합으로 정보를 반환합니다. 출력에 반영된 문에는 문의 텍스트가 있는 단일 행이 포함되고, 이 단일 행 뒤에는 실행 단계에 대한 자세한 정보가 있는 몇 개의 행이 있습니다 아래 표에서는 출력에 포함된 열을 보여 줍니다.

열 이름

설명

Rows

실행된 행수

Executes

Loop 일 경우 Loop 실행 된 횟수

StmtText

PLAN_ROW 형식이 아닌 행에 대해 이 열에는 Transact-SQL 문의 텍스트가 포함됩니다. PLAN_ROW 유형의 행에 대해서는 이 열에 작업에 대한 설명이 포함됩니다. 이 열에는 물리적 연산자가 포함되며 논리 연산자가 포함될 경우도 있습니다. 이 열 다음에 물리적 연산자가 결정한 설명이 나올 경우도 있습니다. 자세한 내용은 논리 물리 연산자 참조를 참조하십시오.

StmtId

현재 일괄 처리에 있는 문의 수입니다. (몇번째 쿼리에 대한 통계인지)

NodeId

현재 쿼리의 노드 ID입니다. (현재 노드의 식별값)

Parent

부모 단계의 노드 ID입니다 (이 값이 같은 것 끼리, 같은 depth라고 생각하면 된다)

PhysicalOp

노드에 대한 물리적 구현 알고리즘입니다. PLAN_ROWS 형식의 행에만 해당됩니다.

LogicalOp

이 노드가 나타내는 관계형 대수 연산자입니다. PLAN_ROWS 형식의 행에만 해당됩니다.

Argument

수행되는 작업에 대한 추가 정보를 제공합니다. 물리적 연산자에 따라 이 열의 내용이 달라집니다.

DefinedValues

이 연산자가 사용하는 값에 대한 쉼표로 구분된 목록을 포함합니다. 이 값은 현재 쿼리에 있었던 계산된 식(: SELECT 목록이나 WHERE 절에 있음)이거나 이 쿼리를 처리하기 위해 쿼리 프로세서에서 사용한 내부 값입니다. 쿼리 내의 어디에서든 정의된 이 값이 참조될 수 있습니다. PLAN_ROWS 형식의 행에만 해당됩니다.

EstimateRows

이 연산자가 생성한 출력의 예상 행 수입니다. PLAN_ROWS 형식의 행에만 해당됩니다.

EstimateIO

작업에 대한 예상 I/O 비용입니다. PLAN_ROWS 형식의 행에만 해당됩니다.

EstimateCPU

이 연산자에 대한 예상 CPU 비용입니다. PLAN_ROWS 형식의 행에만 해당됩니다.

AvgRowSize

이 연산자를 통해 통과되는 행의 예상 평균 행 크기(바이트)입니다.

TotalSubtreeCost

이 작업 및 모든 자식 작업에 대한 예상(누적) 비용입니다.

OutputList

현재 작업에서 예상하고 있는 열에 대한 쉼표로 구분된 목록을 포함합니다.

Warnings

현재 작업과 연관된 경고 메시지에 대한 쉼표로 구분된 목록을 포함합니다. 경고 메시지에 열 목록과 함께 "NO STATS:()" 문자열이 포함될 경우도 있습니다. 이 경고 메시지는 쿼리 최적화 프로그램이 이 열의 통계에 기초하여 결정을 내리려고 했지만 사용 가능한 통계가 없었음을 나타냅니다. 따라서 쿼리 최적화 프로그램이 추측을 해야 했고 결과적으로 비효율적인 쿼리 계획을 선택했을 수도 있습니다. 쿼리 최적화 프로그램이 더 효율적인 쿼리 계획을 선택할 수 있도록 통계를 만들거나 업데이트하는 방법은 UPDATE STATISTICS를 참조하십시오. 어떤 경우에는 이 열에 조인 조건자 없이 조인(테이블을 수반하는)이 일어났음을 나타내는 "MISSING JOIN PREDICATE" 문자열이 포함되기도 합니다. 실수로 조인 조건자를 삭제하면 예상보다 실행 시간이 긴 쿼리가 만들어지고 큰 결과 집합이 반환됩니다. 이 경고가 나타나면 조인 조건자를 의도적으로 사용하지 않았는지 확인하십시오.

Type

노드 유형. 각 쿼리의 부모 노드에 대해서는 노드 유형이 Transact-SQL 문 유형(: SELECT, INSERT, EXECUTE )입니다. 실행 계획을 나타내는 하위 노드에 대해서는 PLAN_ROW 유형입니다.

Parallel

0 = 연산자가 병렬로 실행되지 않습니다.

1 = 연산자가 병렬로 실행됩니다.

EstimateExecutions

현재 쿼리를 실행하는 동안 이 연산자가 실행될 예상 횟수입니다.



Physical Op & Losical Op 에 사용되는 연산자
1) Bookmark Lookup 실행 계획 연산자
Bookmark Lookup 연산자는 책갈피(행 ID 또는 클러스터링 키)를 사용하여 테이블이나 클러스터형 인덱스에서 해당 행을 조회합니다. Argument 열에는 테이블이나 클러스터형 인덱스에서 행을 조회할 때 사용하는 책갈피 레이블이 포함됩니다. Argument 열에는 행을 조회하는 테이블 또는 클러스터형 인덱스의 이름도 포함됩니다. WITH PREFETCH 절이 Argument 열에 나타나는 경우에 쿼리 프로세서에서는 테이블 또는 클러스터형 인덱스에서 책갈피를 조회할 때 비동기 사전 인출(미리 읽기)을 사용하는 것을 최적의 방법으로 결정합니다.

SQL Server 2008에서는 Bookmark Lookup이 사용되지 않습니다. 대신 Clustered Index Seek 및 RID Lookup이 책갈피 조회 기능을 제공합니다. Key Lookup 연산자도 이 기능을 제공합니다.

Clustered Index는 DATA PAGE가 Index Leaf Level 에 존재를 한다.
Non-Clustered Index의 DATA PAGE는 Index Leaf Level에 존재하지 않는다.

즉, Non-Clustered Index로 해당 값을 Index Seek로 검색을 하였어도 출력될 값을 찾기 위해서는 해당 DATA PAGE 까지 찾아 들어가야 하는것이다. 그래서 MS-SQL 2000에서는 Bookmark lookup이라는것이 발생하는것이다.

2) RID Lookup 실행 계획 연산자
RID Lookup은 제공된 RID(행 식별자)를 사용하여 힙을 조회하는 책갈피 조회입니다. Argument 열은  테이블의 행을 조회하는 데 사용되는 책갈피 레이블 및 행을 조회할 테이블의 이름을 포함합니다.

RID Lookup은 항상 NESTED LOOP JOIN과 함께 사용됩니다.
RID Lookup은 물리 연산자입니다.

이제 RID Lookup을 실제 재현해보기 위해서 Test_Lookup Table에 Unique Non-Clustered Index를 만들어 보겠다.
왜 굳이 Non-Clustered Index를 만드느냐? RID Lookup은 Heap Table에서 만 일어난다. Heap Table은 Clustered Index가 없는 Table을 지칭한다. 그럼 왜 또 구지 Unique Type으로 만드냐? Unique Type이 아니면 Query 실행 될때 Table Scan이 일어난다

3) Key Lookup 실행 계획 연산자
SQL Server 2005 서비스 팩 2에 새로 추가된 Key Lookup 연산자는 클러스터형 인덱스가 있는 테이블의 책갈피 조회입니다. Argument 열에는 클러스터형 인덱스의 이름과 클러스터형 인덱스에서 행을 조회할 때 사용되는 클러스터링 키가 포함됩니다. Key Lookup은 항상 Nested Loops 연산자와 함께 사용됩니다. WITH PREFETCH 절이 Argument 열에 나타나는 경우에 쿼리 프로세서에서는 클러스터형 인덱스에서 책갈피를 조회할 때 비동기 사전 인출(미리 읽기)을 사용하는 것을 최적의 방법으로 결정합니다. 

Table에서 KEY Lookup을 발생시키려면 3가지 조건이 필요하다.
첫번째, Clustered Index가 존재해야 한다.
두번째, 검색될 Non-Clustered Index가 존재해야 한다.
세번째, Index가 걸리지 않은 출력될 목록이 있어야 한다.

posted by 방랑군 2009. 9. 30. 13:37

 저장프로시저가 좋다고 지랄하는 놈들한테 넌지시 말한번 꺼낼수 있는 좋은 아티클..^^;

이분한테 참 감사하고 싶다...

그래도, 나도 싫은 DB 에 잘 몰라서다... 우기기는 싫거든....


참조 : http://resisa.tistory.com/55


"저장 프로시저 사용해보셨나요?" 어떤 분이 저에게 이렇게 묻는다면 저는 "아니요. "라고 대답을 할 것입니다. 안타깝게도(?) 프로젝트에서 전 저장 프로시저를 사용해보지 못했습니다. 그래서 전 저장프로시저에 대해서 잘모릅니다. 이번에는 진짜로 제가 받은 질문입니다. 개발시에 Inline쿼리와 저장 프로시저중에 선택을 해야 한다면 어떤 것을 선택할 것이냐는 질문입니다. 개발인력이 많다면 전 Inline쿼리를 사용할 것이라고 대답했습니다. 개발인력이 많다는 것은 제 개인적인 생각이지만 저처럼 저장 프로시저를 사용해보지 못한 사람들도 많을 것이라는 생각때문이였고 저장 프로시저에 대해서 제 자신이 잘 모르기 때문입니다. 그 분이 다시 저에게 이런 말을 했습니다. 저장 프로시저는 컴파일이 된 이후에 다음에 사용할 경우에는 캐쉬된 상태로 사용되기 때문에 당연히 저장 프로시저를 사용해야 된다는 말이였습니다. 그래서 제가 정적SQL인지 동적SQL인지 명칭이 확실하지는 않지만 파라미터를 사용하는 쿼리는(MSSQL @문자로 오라클은 :문자로 받을 경우) 컴파일을 한번만 한다고 말했지만 그 분은 아니라고 하셨습니다. 그럼 한 번 확인해볼까요?

테스트 환경은 운영체제는 Vista, DB MSSQL2005이며 System.Data.SqlClient를 사용해서 확인해보도록 하겠습니다. 코드는 아래와 같습니다.
1.
파라미터 없는 SQL

string ConnStr = "Data Source=(local);Initial Catalog=TestDB;Persist Security Info=True;User ID=sa;Password=dsdvp";

 

string query = " SELECT * FROM Student WHERE ID = '2' ";

SqlConnection conn = new SqlConnection(ConnStr);

 

SqlCommand cmd = new SqlCommand(query, conn);

conn.Open();

 

cmd.ExecuteNonQuery();

conn.Close();


2. 파라미터 있는 SQL

string ConnStr = "Data Source=(local);Initial Catalog=TestDB;Persist Security Info=True;User ID=sa;Password=dsdvp";

 

string query = " SELECT * FROM Student WHERE ID = @ID ";

SqlConnection conn = new SqlConnection(ConnStr);

 

SqlCommand cmd = new SqlCommand(query, conn);

SqlParameter param = new SqlParameter("ID", "2");

 

cmd.Parameters.Add(param);

conn.Open();

 

cmd.ExecuteNonQuery();

conn.Close();


3. 저장 프로시저

string ConnStr = "Data Source=(local);Initial Catalog=TestDB;Persist Security Info=True;User ID=sa;Password=dsdvp";

SqlConnection conn = new SqlConnection(ConnStr);

 

SqlCommand cmd = new SqlCommand();

cmd.Connection = conn;

cmd.CommandType = CommandType.StoredProcedure;

cmd.CommandText = "TestProc";

conn.Open();

 

cmd.ExecuteNonQuery();

conn.Close();

=> Inline쿼리나 저장 프로시저가 컴파일되는지의 여부를 알기 위해서 이전에 SQL 튜닝교육을 받았던 문서를 보다가 운영체제에서 제공해주는 XP에서는 관리도구-성능 Vista에서는 관리도구-안정성 및 성능모니터를 사용하였습니다. 성능모니터를 하기 위해서는 카운터를 추가해주어야 합니다. SQL Server:SQL Statstics에서 SQL Compilations/sec SQL Re-Complilations/sec를 추가해주고 배율을 좀 더 확인하기 쉽도록 1에서 10으로 변경해준 후에 위의 구문 3개를 실행해보았습니다.
먼저 1, 2, 3번을 차례대로 실행했을 경우의 화면입니다.

=> 파라미터가 없는 SQL이 가장 높게 나타나는 것을 볼 수 있고 파라미터가 있는 SQL과 저장 프로시저를 동일하게 나타납니다. 이후의 1, 2, 3번 어떤 것을 계속 실행하여도 다시 컴파일 되는 것을 볼 수 없습니다. 혹시나 1, 2, 3번을 실행한 순서에 관계가 있나 싶어 서비스에서 SQL를 내렸다 다시 올려 번갈아 가면서 실행해 보았지만 순서만 달라질 뿐 위의 결과와 똑같은 것을 확인할 수 있었습니다. 여기서 Inline쿼리도 저장 프로시저와 마찬가지로 한번만 컴파일 된다는 것을 알 수 있습니다. 저는 2, 3번만 컴파일이 한번 될 줄 알았는데 1번도 컴파일은 한번만 됩니다. 그런데 왜 1번만 컴파일 과정에서 높게 나타날까요? SQL Server Profiler로 알아보도록 하겠습니다.

새추적를 누르고 '모든 이벤트 표시'를 체크해준 후에 Stored Procedures TSQL의 모든 이벤트를 체크해줍니다그리고 1, 2, 3번을 실행시킨 화면입니다.
1.
파라미터 없는 SQL

2. 파라미터 있는 SQL

3. 저장 프로시저

=> 차이가 보이시나요? 1번에서는 SP:CacheInsert가 두 번 되는 것을 확인하실 수 있습니다. 그래서 2번이나 3번보다 컴파일시에 더 높게 나타나는 것입니다. 다음은 컴파일 된 이후에 1번을 실행시킨 것을 추적한 화면입니다.

=> SP:CacheHit가 일어나는 것으로 보아 그냥 날리는 Inline 쿼리의 경우에도 캐쉬가 되는 것을 알 수있습니다. 더군다나 파라미터가 있는 SQL의 경우에는 마치 저장 프로시저처럼 실행이 되는 것도 알 수 있었습니다컴파일도 캐쉬도 Inline쿼리가 저장 프로시저보다 사용하기에 나쁜 이유는 되지 않는 것 같습니다.

다음은 제가 SQL 튜닝 교육을 받았던 강사님의 홈페이지에 대한 저장 프로시저에 대한 내용입니다.
http://www.sqlworld.pe.kr/

1. 저장 프로시져에 사용된 모든 구문이 미리 분석되어 최적화된 후 처음 수행시 메모리에 올려져 이후에 사용 될때는 메모리에 올려진 내용이 수행되므로 속도가 월등히 빠릅니다.
2. 복잡한 퀴리문을 네트워크를 통하여 서버로 보낼 필요가 없이, 단지 저장 프로시져를 호출하는 간단한 내용만 서버로 전달되므로 네트워크 트래픽이 감소됩니다.
3. 특정 테이블에 대한 권한이 없는 사용자 계정에 저장 프로시져를 수행 할 수 있는 권한을 주어 필요한 작업을 할 수있게 할 수 있으므로 보안성을 높일 수 있습니다.
4. 특정 기능을 수행하는 저장 프로시져를 만들어 두면 여러 응용프로그램에서 이를 활용 할 수 있습니다. , 특정처리를 위한 모듈화작업이 가능합니다. 모듈화가 되어 있으므로 응용프로그램 전체의 수정없이 해당 저장 프로시져만을 수정하여 원하는 기능 구현을 할수 있습니다.

=> 1번의 경우 월등히 빠르다는 위에서 제가 테스트한 결과와 조금은 다른 내용으로 저에게 질문을 하신 분과 같은 의견입니다. 2번의 경우가 제가 표현을 못했던 가장 중요한 이유입니다. 복잡한 쿼리문을 네트워크로 전송하는 것보다는 저장 프로시저의 이름만 넘기는 것이 당연히 네트워크의 부하를 주지 않을 것입니다하지만 이 경우도 일반적인 응용 프로그램이 아닌 웹 프로그램이면서 웹서버와 DB가 같이 돌고 있는 경우라면 그렇게 큰 차이가 있을까요? 3번의 경우에는 응용 프로그램 자체에서 권한 관리를 한다면 굳이 상관없어 보입니다. 4번이 인라인과 저장 프로시저를 어떤 것을 선택해야 하는지의 가장 중요한 지표가 되는 것 같습니다. 쿼리 부분을 프로그램에서 관리할 것인지 DB안에 저장 프로시저로 관리할 것인지의 여부입니다.

일반적으로 비지니스 로직 레이어에서 트랜잭션을 발생시킵니다. 저장 프로시저를 사용하면 저장 프로시저안에서 트랜잭션 처리를 하게 되고 실질적으로 비지니스 로직 레이어가 의미가 없어져 버립니다. 하지만 이 트랜잭션이라는 것이 단순히 DB에 대한 트랜잭션만 있어야 하는 것일까요? 파일이나 레지스트리에 대한 모든 것에 트랜잭션으로 한꺼번에 처리하고 싶을 경우에도 저장 프로시저로 모든 것이 가능할까란 생각이 제일 먼저 듭니다. 또한 비지니스 로직에 계산 로직 등 복잡한 로직이 들어간 상태에서 트랜잭션 처리를 해야 한다면 저장 프로시저에서는 어떻게 처리할까요다시 한번 말씀드리지만 저는 저장 프로시저를 싫어하는 사람이 아니라 저장 프로시저에 대해서 잘 모르는 사람입니다. 아마 정답은 상황에 맞게 Inline쿼리와 저장 프로시저를 적절하게(?) 사용하는 것 아닐까요?

저작자 표시



'IT > DB' 카테고리의 다른 글

인덱스 정리  (0) 2009.09.30
인덱스가 있지만 인덱스를 안 타는 경우  (0) 2009.09.30
MS-SQL 실행 계획 확인  (0) 2009.09.30
SUBQUERY와 INLINE-VIEW의 차이  (1) 2009.09.30
[MS SQL] ldf 파일 사이즈 줄이기 또는 삭제하기  (0) 2009.09.28
posted by 방랑군 2009. 9. 30. 13:31

참조 : http://blog.naver.com/addibuddi?Redirect=Log&logNo=16037753


SUBQUERY와 INLINE-VIEW가 표현되는 방식이 달라....

의미상으로도 다른줄 알았는데...

INLINE-VIEW자체도 SUBQUERY의 하나의 방식이라는 군요..

 

및에는 참조~

 


☞ Subquery란?  
 
 ◈ SUBQUERY는 다른 하나의 SQL 문장의 절에 NESTEDED된 SELECT 문장 입니다.

 ◈ SELECT, UPDATE, DELETE, INSERT와 같은 DML문과 CREATE TABLE 또는 VIEW에서
     이용 될 수 있습니다.

 ◈ 알려지지 않은 조건에 근거한 값들을 검색하는 SELECT 문장을 작성하는데 유용 합니다.

 ◈ SUBQUERY는 MAIN QUERY가 실행되기 이전에 한번 실행 됩니다.


☞ Guidelines

 ◈ SUBQUERY는 괄호로 묶어야 합니다.

 ◈ 두 종류의 비교 연산자들이 SUBQUERY에 사용 됩니다.
    - 단일 행 연산자( =,>, >=, <, <=, <>, != )
    - 복수 행 연산자( IN, NOT IN, ANY, ALL, EXISTS )

 ◈ SUBQUERY는 연산자의 오른쪽에 나타나야 합니다.


☞ SUBQUERY의 유형
 
 ◈ 단일 행(Sing-Row) 서브쿼리 : SELECT문장으로부터 오직 하나의 행만을 검색하는 질의입니다

 ◈ 다중 행(Multiple-Row) 서브쿼리 : SELECT문장으로부터 하나 이상의 행을 검색하는 질의입니다

 ◈ 다중 열(Multiple-Column) 서브쿼리 : SELECT문장으로부터 하나 이상의 컬럼을 검색하는
    질의입니다

 ◈ FROM절상의 서브쿼리(INLINE VIEW) : FROM절상에 오는 서브쿼리로 VIEW처럼 작용 합니다.

 ◈ 상관관계 서브 쿼리 : 바깥쪽 쿼리의 컬럼 중의 하나가 안쪽 서브쿼리의 조건에 이용되는
     처리 방식 입니다.


☞ FROM절상의 서브쿼리(INLINE VIEW)

 ◈ SUBQUERY는 FROM절에서도 사용이 가능 합니다.

 ◈ INLINE VIEW란 FROM절상에 오는 서브쿼리로 VIEW처럼 작용 합니다.

 
예제)급여가 20부서의 평균 급여보다 크고 사원을 관리하는 사원으로서 20부서에 속하지 않은
      사원의 정보를 보여주는 SQL문 입니다.
 
SQL>SELECT b.empno,b.ename,b.job,b.sal, b.deptno
        FROM (SELECT empno
                  FROM emp  
                  WHERE sal >(SELECT AVG(sal) FROM emp WHERE deptno = 20))
a, emp b
        WHERE a.empno = b.empno
             AND b.mgr is NOT NULL
            AND b.deptno != 20
 
     EMPNO ENAME      JOB              SAL     DEPTNO
---------- ---------- --------- ---------- ----------
      7698 BLAKE      MANAGER         2850         30
      7782 CLARK      MANAGER         2450         10

 

 


☞ 다중 열(Multiple-Column) 서브쿼리

 ◈ 다중 열 서브쿼리란 서브쿼리의 결과값이 두개 이상의 컬럼을 반환하는 서브쿼리 입니다.


☞ Pairwise(쌍비교) Subquery
 
 - 서브쿼리가 한번 실행되면서 모든 조건을 검색해서 주 쿼리로 넘겨 줍니다.
 
SQL> SELECT empno, sal, deptno
        FROM emp
        WHERE (sal, deptno) IN ( SELECT sal, deptno
                                            FROM emp
                                            WHERE deptno = 30
                                                 AND comm is NOT NULL )
;
                             
     EMPNO        SAL     DEPTNO
---------- ---------- ----------
      7521       1250         30
      7654       1250         30
      7844       1500         30
      7499       1600         30



☞ Nonpairwise(비쌍비교) Subquery

 - 서브쿼리가 여러 조건별로 사용 되어서 결과값을 주 쿼리로 넘겨 줍니다.
 
SQL>SELECT empno, sal, deptno
        FROM emp
        WHERE sal IN ( SELECT sal
                              FROM emp
                              WHERE deptno = 30
                                   AND comm is NOT NULL )

            AND deptno  IN ( SELECT deptno
                                    FROM emp
                                    WHERE deptno = 30
                                         AND comm is NOT NULL );


     EMPNO        SAL     DEPTNO
---------- ---------- ----------
      7521       1250         30
      7654       1250         30
      7844       1500         30
      7499       1600         30



☞ Null Values in a Subquery

   - 서브쿼리에서 null값이 반환되면 주 쿼리 에서는 어떠한 행도 반환되지 않습니다.

 

☞ 다중 행(Multiple-Row) 서브쿼리

 ◈ 하나 이상의 행을 RETURN하는 SUBQUERY를 다중 행 SUBQUERY라고 합니다.

 ◈ 복수 행 연산자(IN, NOT IN, ANY, ALL, EXISTS)를 사용 할 수 있습니다.


☞ IN 연산자의 사용 예제
 
  부서별로 가장 급여를 많이 받는 사원의 정보를 출력하는 예제
 
SQL>SELECT empno,ename,sal,deptno  
        FROM emp
        WHERE sal IN (SELECT MAX(sal)
                              FROM emp
                              GROUP BY deptno)
;

     EMPNO ENAME             SAL     DEPTNO
---------- ----------   ---------- ----------
      7698 BLAKE             2850           30
      7788 SCOTT            3000           20
      7902 FORD              3000           20
      7839 KING               5000           10



☞ ANY 연산자의 사용 예제

  ANY연산자는 서브쿼리의 결과값중 어느 하나의 값이라도 만족이 되면 결과값을 반환 합니다.

SQL>SELECT ename, sal
        FROM emp
        WHERE deptno != 20
             AND sal > ANY(SELECT sal FROM emp WHERE job='SALESMAN');  
 
ENAME             SAL
---------- ----------
ALLEN            1600
BLAKE            2850
CLARK            2450
KING              5000
TURNER          1500
MILLER           1300

6 개의 행이 선택되었습니다.



☞ ALL 연산자의 사용 예제

  ALL연산자는 서브쿼리의 결과값중 모든 결과 값이 만족 되야만 결과값을 반환 합니다.
 
SQL>SELECT ename, sal
        FROM emp
        WHERE deptno != 20
             AND sal > ALL(SELECT sal FROM emp WHERE job='SALESMAN');
 
ENAME             SAL
---------- ----------
BLAKE            2850
CLARK            2450
KING             5000

3 개의 행이 선택되었습니다.



☞ EXISTS 연산자의 사용 예제

 - EXISTS 연산자를 사용하면 서브쿼리의 데이터가 존재하는가의 여부를 먼저 따져 존재하는
   값들만을 결과로 반환해 줍니다.
 - SUBQUERY에서 적어도 1개의 행을 RETURN하면 논리식은 참이고 그렇지 않으면 거짓 입니다.

예제)사원을 관리할 수 있는 사원의 정보를 보여 줍니다.
 
SQL>SELECT empno, ename, sal
        FROM emp e
        WHERE EXISTS (SELECT empno FROM emp WHERE e.empno = mgr) 

     EMPNO ENAME             SAL
---------- ---------- ----------
      7566 JONES             2975
      7698 BLAKE             2850
      7782 CLARK             2450
      7788 SCOTT            3000
      7839 KING               5000
      7902 FORD              3000
 
6 개의 행이 선택되었습니다.

  ================================================
    * Oracle Community OracleClub.com
    * http://www.oracleclub.com
    * http://www.oramaster.net
    * 운영자 : 김정식 (oramaster _at_ empal.com)
  ================================================ 



posted by 방랑군 2009. 9. 29. 13:13

참조 : http://kingcrap.com/entry/닷넷에서-native-dll-사용하기



닷넷에서 C/C++로 작성된 dll을 사용하고자 할 경우 다음과 같은 방법이 있다.

1. 일반적인 native dll의 경우 - P/Invoke (Platform Invoke)를 써서 직접 호출
닷넷에서 Win32 API를 호출하거나 C/C++로 작성된 native dll을 호출할 경우, native dll이 제공하는 메소드의 signature나 타입에 대해 닷넷에서 인식하고 호출할 수 있도록 이에 대한 선언을 해야 한다. 크게 보면 세 단계로 구성되는데, 첫째 DllImport하여 필요한 dll 로딩하는 부분, 둘째 원하는 메소드 signature를 extern으로 선언하는 부분(즉, 이 메소드가 외부 native dll에서 정의되어 있다고 선언하는 부분), 마지막으로 이 메소드를 호출하여 원하는 값을 취하는 부분으로 되어 있다.

Win32 API에 대한 선언을 일일이 기억하기란 쉽지 않기 때문에 웹에 이에 대한 데이터베이스 형태의 wiki로서 PInvoke.net이 존재한다. 아래 화면은 http://www.pinvoke.net 에서 볼 수 있다.pinvoke 
아울러 PInvoke.net에서는 Visual Studio 2005에 대한 플러그 인을 제공하여 무료로 다운받아 설치할 수 있으며 아래 그림에서 처럼 VS내에서 원하는 선언문을 검색하여 바로 붙여 넣을 수 있다.
image 

이보다 좀 더 나은 방식으로 간단한 애플리케이션 형태의  AppViewer가 존재하여 편리하게 원하는 API에 대한 선언문을 사용할 수 있다. 아래 그림에서 보듯이 다양한 언어, 심지어 delphi나 MASM에서 사용할 수 있는 기능까지 제공하고 있다.
 image image

자바에서도 이와 동일한 세 단계 방식의 호출 방법이 있는데, JNI (Java Native Interface)라고 부른다. System.loadLibrary()하여 dll을 메모리에 올리는 부분, 호출하고자 하는 메소드의 signature를 native라는 modifier를 써서 선언하는 부분(역시 이 메소드의 구현은 native하게 외부에 정의되어 있다고 선언하는 부분), 마지막으로 이 메소드를 호출하는 부분으로 구성된다. 자바가 호출하는 메소드를 C/C++에서 구현하기 위해서는 각 언어에 맞는 헤더파일이 필요한데 이를 위해 javah -jni 명령어를 써서 *.h 파일을 생성하며 이렇게 생성된 *.h를 C/C++에서 include하여 개발하는 과정을 거치게 된다.

2. COM 서버 접근 - RCW (Runtime-Callable Wrapper)를 이용하는 방법
COM 객체에 대한 wrapper를 만들어서 닷넷에서는 마치 일반적인 닷넷 객체를 호출하듯 프로그래밍할 수 있도록 지원하는 방법이다. Visual Studio에서 Add Reference기능을 클릭하며 아래에서 처럼 COM 컴포넌트를 선택할 수 있으며 OK를 누르는 순간 레퍼런스가 추가되면서 이 COM 컴포넌트에 대한 닷넷 Wrapper가 생성된다. 생성되는 wrapper는 Interop.xxx.dll의 어셈블리가 된다. 따라서 개발자는 닷넷 프로그래밍 하는 방식으로 COM 객체를 생성하고 호출할 수 있게 된다.
image
Visual Studio를 사용하지 않는 경우에는 .NET SDK에 들어있는 TlbImp.exe 명령어를 사용하여 wrapper를 생성할 수도 있다.
COM 객체가 대단히 크거나 복잡할 경우 생성되는 Wrapper의 크기 또한 부담스러우며, COM 내부에서 사용하기 위해 만든 인터페이스를 wrapper에서 숨길 수 있는 방안도 없기 때문에, 간편하게 생성하여 사용할 수 있는 장점이 있지만  COM 객체의 특성에 따라 이 방법이 적합한지 한번쯤은 생각해 볼 필요가 있다. 아울러 사용이 끝난 COM 객체는 해당 wrapper가  GCed될 때까지 살아 있기 때문에, wrapper가  Garbage Collector에 의해 GCed될 때까지 기다리지 말고 System.Runtime.InteropServices.Marshal.ReleaseComObject()를 이용하여 즉시 해제해주는 것이 좋다.

Posted by 장현춘 
posted by 방랑군 2009. 9. 28. 08:54

Mssql의 로그파일인 LDF파일이 너무 커져버렸을때 용량 줄이기 방법

backup log 데이터베이스이름 with TRUNCATE_ONLY

DBCC SHRINKFILE (데이터베이스이름_Log, 10)

-숫자 10은 용량 !

한줄씩 실행하면 끝 !



+  testdb를 지정한다.(물론 다들 알고 계시겠죠.)
   줄이길 원하는 데이터베이스를 사용하겠다고 지정하는 겁니다.
use testdb

+ 로그파일의 정보를 확인합니다.

dbcc loginfo

+ 현재 지정된 디비가 사용하는 mdf 및 ldf파일의 경로, 이름 및 크기를 확인합니다.

exec sp_helpfile

+ 디비의 로그를 백업해 줍니다.

backup Log testdb to disk='f:\mssql\dbbackup\temp\testdb.bak'

 

+ 로그파일을 최소의 단위로 축소합니다.

backup log testdb with truncate_only


+ 로그파일을 삭제합니다.

backup log testdb with no_log

+ 로그파일을 10메가로 다시 생성합니다.

dbcc shrinkfile (testdb_log, 10)

+ mdf와 ldf파일 확인
exec sp_helpfile


+ 로그파일의 최대크기를 지정(물론 안해도 상관없습니다.)

alter database testdb

    modify file ( name = testdb_log, maxsize = 100 mb )


이상입니다.위에 축소나 삭제에 대한 사항은 원하시는 것을 선택해서 작업하시면 됩니다.

'IT > DB' 카테고리의 다른 글

인덱스 정리  (0) 2009.09.30
인덱스가 있지만 인덱스를 안 타는 경우  (0) 2009.09.30
MS-SQL 실행 계획 확인  (0) 2009.09.30
Inline 쿼리 VS 저장 프로시저  (0) 2009.09.30
SUBQUERY와 INLINE-VIEW의 차이  (1) 2009.09.30
posted by 방랑군 2009. 9. 15. 17:25



참조 : http://debop.egloos.com/2299315



C# 2.0 /3.0 New Features

작성자 : 리얼웹 개발본부 배성혁

 

들어가는 말

.NET Framework 버전과 C# Specification 버전이 꼭 일치하지는않지만유사하게 버전이 올라가고 있습니다. 2009년 현재 C# 4.0 Spec Preview가 공개되었고이를 .NET Framework 4.0, VS.NET 2010 부터 사용이 가능할 것 같습니다.

 

여러분은 처음 .NETFramework 또는 C#을 공부하면서문법, API 등을 공부하고쓰고 있지만 어떤 버전을 쓰고 있는지는 잘모르셨을 것이라 생각됩니다하지만 S/W 개발쪽에 경력이쌓이게 되면, version에 따라 변화되는 기능에 대해 어느정도 무의식 속에 파악하고수용하게 됩니다.

보통 어느정도 초보딱지를 뗀 개발자라면자신이 사용하는 툴이나 라이브러리를 가장 최신의 것으로 유지하려고 하는 경향이 있습니다. Early adapter라고 하지요… 하지만신제품 개발단계가 아닌 제품의 라이프사이클을 고려하게 되면꼭최신의 제품을 사용할 수 없을 때가 더 많아지기도 합니다. – backward compatibility가있는 제품이라면 영향이 작을 수는 있지만, Microsoft는 워낙 악명이 높습니다차라리 open source 진영에서 더 신경쓰고 있는 부분입니다.

 

제품 Spec을결정하던가버전관리를 주도하는 개발자는 사용하는 제품의 새로운 버전이 출시되었을 때 Upgrade를 해야 하는지를 고려해야 합니다아예 눈/귀를 닫아서는 안되고,Library 하나라도담당 제품의 많은 장점을 줄 수 있는 기능이 있는지?, 제품 개발 혹은 Customizing 시의 공수외부 인터페이스 변화 등을 고려해서신 버전 사용을 결정해야 합니다.

 

고려대상은 사용하는 제품마다 다르고독자 판단만으로 안되는 경우도 많습니다특히나 MS 제품은 무조건 신버전을 사용하도록(지들 제품 많이 팔리도록강요하는 경우가 많습니다. (여기에 놀아나지 말아야 하지만… 가만보면 제가 가장 많이 놀아나는 것도 같고…) – 고객 중에서도최신버전을 좋아하는 사람기존 버전을 고수하는 사람 등등 참 많습니다.

 

어쨌든 새로운 제품에 대해서는 항상 새로운 기능이 무엇인지뭐가 바뀌었는지기존 제품과의 호환성은 어떤지를 파악해야 합니다새로 도입할 제품도현재 버전이 어떤기능을 가졌는지발전 단계는 어떤지앞으로의 로드맵에는 어떤 기능이 있는지를 조사해야합니다.

 

그럼 이제부터 .NET Framework 2.0/3.0  이제 4.0이 공개될 건데왠 뒷북이라 할 수도 있지만 사실 개발자들이 C# 2.0 spec조차도 잘 사용하지 못하는 경우가 대부분이어서 – 의 새로운 기능에 대해 살펴보겠습니다.

 

먼저 C# 2.0 Spec부터 살펴보죠… 개인적으로 C# 2.0의 새로운 특성 중에 제일 반겼던 것은 Generic 을 지원한다는 것입니다물론 다른 좋은 기능들도 많지만굵은 글자로 되어 있는 부분이 제게는 도움이 많이 되었던 것들입니다.

대부분 실제 많이 사용하고 있는 기능들이므로설명이나 의미는 생략하겠습니다다만 Generic에 대해서는 다음 기회에 다시 설명하도록 하겠습니다.

 

표 1. C# 2.0 New Features

항목

설명

Generic

형식 매개 변수를 사용하여, run time 시에 cat, boxing 작업에 대한 위험없이 단일 class 작성 가능

Iteration

Yield return

Yield break;

Public void GetEnumerator()

{

    for(int i=0; i< _data.Count; i++)

        yield return _data[i];
}

Partial class

public partial class Employee { public void DoWork() { … } }

public partial class Employee { public void GoToLunch() { … } }

Nullable type

System.Nullable 구조체의 Instance

int? num = null;

int count = num ?? 0;

int count = num.GetValueOrDefault(0);

Anonymous method

Delegate void Del(int x);

Del d = delegate() {

    Console.WriteLine(“delete “ + x);

};

Static class

public static class Utils {

    public static void UtilityMethod() { … }

}

Property accessor

string FullName { get; protected set; }

Fixed size buffer

Public struct MyArray { public fixed char PathName[128]; }

Friendly assembly

[assembly:InternalsVisibleTo(“cs_friend_assemblies_2”)]

 

한가지 짚고 넘어가고 싶은 것은 Anonymous method 라는기능입니다이는 java 문법에서 제공되는 기능을 차용한것으로 보이는데앞으로 설명할 C# 3.0 spec에서이를 토대로 많은 기능들을 구현할 수 있음을 알 수 있습니다.

 

다음으로는 C# 2.0 (.NET Framework 2.0 이 더옳은 표현이지만, C#이 대표 Language이므로에서 새롭게 제공하는 delegate 에 대해 알아 보겠습니다.

 

표 2. C# 2.0 중요 Delegate

Type

Definition

Action

public delegate void Action<T> ( T arg )

public delegate void Action<T1, T2> ( T1 arg1, T2 arg2  )

public delegate void Action<T1, T2, T3> ( T1 arg1, T2 arg2, T3 arg3 )

public delegate void Action<T1, T2, T3, T4> ( T1 arg1, T2 arg2, T3 arg3, T4 arg4 )

Func

public delegate TResult Func<T, TResult> ( T arg )

public delegate TResult Func<T1, T2, TResult> ( T1 arg1, T2 arg2 )

public delegate TResult Func<T1, T2, T3, TResult> ( T1 arg1, T2 arg2, T3 arg3 )

public delegate TResult Func<T1, T2, T3, T4, TResult> ( T1 arg1, T2 arg2, T3 arg3, T4 arg4 )

Predicate

public bool Predicate<T>( T obj )

 

 2.에 나온 Action,Func, Predicate라는 delegate는 일반적으로는 많이 사용하는 delegate를 미리 정의해 둔 것이라 볼 수 있습니다특징중에 Generic을 이용한 것인데, Generic을 이용하면, signature는 하나지만다양한 Type을 지원하는 단 한 개의 delegate만을 정의해서 사용할수 있는 장점이 있습니다.

Action voidfunction point (C Language 용어)라 할 수 있는데,  지정된 형식의 인자를 N를 받아 수행하고반환값이 없는 함수를 말합니다.

Func는 반환값이 있다는 차이가 있고, Predicate Func<T, bool>(T arg) 와같은 뜻입니다.

 

위의 delegate를 보시면 메소드 인자의 개수가 최대 4개인데더 많은 인자를 가지는 메소드는 개발자가 추가로 정의하여사용이 가능합니다.

 

사용 예는 다음과 같습니다.

 

Func<stringstring> convert = delegate(string s)

                          {

                                  return s.ToUpper();

                          };   // anonymous method

string name = "Dakota";

 

Console.WriteLine(convert(name));

 

ð  DAKOTA

 

convert라는 delegate를만들고이를 사용하는 방식을 설명했습니다. Anonymousmethod 를 사용하여실제 delegate를위한 메소드 원형의 class에서 정의하지 않고내부적으로이름없는” 메소드를 정의하여 사용할 수 있습니다.

 

더 자세한 내용은

ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.ko/fxref_mscorlib/html/da586d48-5345-2de1-63f2-d6208f298942.htm

ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.ko/fxref_system.core/html/a0ab867a-da51-dd82-2e1a-e87b93712102.htm

를 참고하세요.

 

C# 2.0의 새로운 특징은 이쯤에서 정리하고 C# 3.0의 새로운 기능에 대해서 알아봅시다.

우선 MSDN C# 3.0의새로운 기능에 대한 설명은 ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.ko/dv_csref/html/e5193336-6adb-471e-ab22-e3fc60e0fa52.htm에 자세히 나와 있으니 참고하세요특히 새로운 기능의 필요성다른 새로운 기능의 토대가 되는지 등등을 파악하 보시기 바랍니다.

참고로 C# 3.5의 경우에는 ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.ko/dv_fxintro/html/1b0d91e8-2d01-47a0-affc-966894de71f8.htm에 있습니다. – 3.5에서는 Language 차원에서크게 발전된 건 없습니다.

 

그럼 C# 3.0에서 새롭게 도입된 기능을 알아 봅시다.

 

표 3. C# 3.0 Language enhancements

항목

설명

Local variable type inference

지역변수와 함께 사용될 경우 var 키워드는 초기화 문의 오른쪽에 있는 식에서 변수 또는 배열 요소의 형식을 유추하도록 컴파일러에게 지시한다.

 

var i = 5;

var s = "Hello";

var a = new[] {1,2,3};

for(var x =1; x <10; x++)

{

        // some codes

}

var 키워드는 "Variant"를 의미하지 않으며 변수가 느슨한 형식이거나 런타임에 바인딩됨을 의미하는게 아닙니다.

Object initialize

생성자를 명시적으로 호출하지 않고 개체 초기화를 수행할 수 있게 한다.

var cat = new Cat {Age = 10, Name = "Sylverster"};

 

Object intializer에 익명 형식 허용 단 nullable 형식은 불가

var o = new {Title = "Book In Action", Publisher = "Manning"};

 

Collection initialize

List<int> digits = new List<int> { 01234567 };

List<int> digits2 = new List<int> { 0+112 % 3, MakeInt() };

List<Cat> cats = new List<Cat> {

                       new Cat { Age=10, Name=“Sylverster” },

                       new Cat { Age=4, Name=“Peaches” },

                       null

               };

 

Anonymous types

익명 형식은 형식을 먼저 명시적으로 정의할 필요 없이 읽기 전용 속성 집합을 단일 개체로 캡슐화하는 편리한 방법을 제공합니다형식 이름은 컴파일러에 의해 생성되고 소스 코드 수준에서 사용할 수 없습니다속성의 형식은 컴파일러에 의해 유추됩니다다음 예제에서는 Amount 및 Message라는 두 개의 속성을 사용하여 초기화되는 익명 형식을 보여 줍니다.

 

var o = new {Title = "Book In Action", Publisher = "Manning"};

Auto-implemented properties

속성중에 추가 논리가 필요없을때속성 선언을 간결하게 한다.

 

class MyClass

{

public double TotalAmount { getset; }

public string Name { getprivate set; }       // read-only

public int CustomerId { getprotected set; }  // read-only for user, writable for drived class

}

 

Extension Methods

인스턴스 메서드 구문을 사용하여 호출할 수 있는 정적 메서드를 사용하여 기존 클래스를 확장합니다.

 

public static class MyExtensions {

    public static int WordCount(this String text) {

        return str.Split(new char[] { ‘ ‘, ‘.’, ‘?’, StringSplitOperations.RemoveEmptyEntries).Length;

    }

}

String s = "New Features in C# 3.0";

int wordCount = s.WordCount();

 

Lambda expression

대리자나 식 트리에 바인딩할 수 있는 입력 매개 변수를 가진 인라인 식을 사용할 수 있게 합니다

 

Func<intint> myPower2 = x => x*x;

int x2 = myPower2(5); // x2 = 25

 

Partial methods

Abstract class의 abstract method와 유사한 효과를 나타낸다몇가지 제한사항이 있음

// define in file1.cs

partial void onNameChanged();

// define in file2.cs

partial void onNameChanged()

{

    
}

 

 

C# 3.0 기능 중에 몇 가지는 코딩 시에 작업을 수월하게 하고코드 분석을 쉽게 해 주는 문법적인 발전도 있고, Lambdaexpression과 같이 동적 표현이 가능케 해주는 획기적인 기능도 추가되었습니다 (lambdaexpression은 다음에 얘기할 LINQ에서도 설명할 예정입니다.)

 

요즘 Resharper 4.1 이상을 깔면 추천 코드를 제공해 주는데특정 타입을 “var” 예약어로 바꾸는 것을 추천하는 경우가 많습니다. “var”라는 것이 어찌보면모든 수형을 표현하는 것처럼 보이므로 COM+에서 여러 Language에서 상이한 수형을 표현하기 위한 VARIANT를 연상할 수 있는데실제 var는 동적으로 수형이 결정되는 VARIANT 와는 달리 컴파일시에 결정됩니다. C# 코드상에서만 결정이 안되었지컴파일된 IL Code 상에서는 실제 수형으로 선언되고사용되고 있음을 알수 있습니다.

 

아래 원본 C# 코드와Reflector를 통한 diassembling 된 코드를 비교해 보십시요.

“var”, “object initializer” 를 이용하게 되면아래와 같이 약간의 변형을 거쳐지만원하는 결과가 되는 것은 마찮가지 입니다.

// C# 코드

public virtual Config CreateConfig(string section, string name, string value)

{

        var config = new Config(name, value)

                               {

                                       Application = AdminContext.Current.Application,

                                       Enterprise = AdminContext.Current.Enterprise,

                                       Section = section,

                                       IsEnabled = true

                               };

 

        Session.SaveOrUpdate(config);

        return config;

}

// Deassembler code
public virtual Config CreateConfig(string section, string name, string value)
{
    Config <>g__initLocal7 = new Config(name, value);
    <>g__initLocal7.Application = AdminContext.Current.Application;
    <>g__initLocal7.Enterprise = AdminContext.Current.Enterprise;
    <>g__initLocal7.Section = section;
    <>g__initLocal7.IsEnabled = true;
    Config config = <>g__initLocal7;
    this.Session.SaveOrUpdate(config);
    return config;

}




Deassembled code에서 보듯이 var Config 수형으로 선언되어 있습니다확실히 VARIANT 수형과는 다른 것입니다. (C# 4.0 spec에 보면 dynamic language 기능이포함되는데이때는 기존 variant와 비슷한 수형이 나올것입니다.)

 




다음으로 .NET Framework 3.0 부터 아주 새로운 개념이 추가 되었는데LINQ (Language INtegrated Query) 입니다.

이 부분에 대한 자세한 설명은 MSDN에 있으니 참고하시고다른 글로서 설명을 드리겠습니다.

 

이 글에서는 LINQ의 기본적인 문법을 설명하고위의 C# 3.0 에서 추가된 특징이 어떻게 활용되는지 (반대로 LINQ 라는 개념을 구현하기 위해 C# 3.0의 새로운 기능들이 만들어졌다라고 볼 수 있습니다.)

 

LINQ를 사용하는데는 크게 두가지 방식이 있습니다.

 

1.     Query Expression ( SQL 문과 비슷 )

2.     Query Operator (Extension Methods 사용)

 

우선 2가지 방식의 예를 봅시다.

 

1.     Query Expression

 

Query Expression은 우리가 잘 알고 있는 Database 질의 형식과 유사하다 SQL 문법과 유사하게 사용할 수 있고기본적으로 메모리에 적재된 Object들로부터 질의를 수행하고결과를 받을 수 있다. (물론 LINQ to SQL, LINQ to XML 등 다양한 질의 대상이 추가될 수 있다)

 

표 4. Query Expression Format

 

from [ type ] id in source

join [ type ] id in source on expr equals expr [ into id ] ]

from [ type ] id in source | let id = expr | where condition }

orderby ordering, ordering, … ]

select expr | group expr by key

[ into id query ]

 

 

Query Expression 예를 들어 보자.

 

코드 1. Query Expression Sample


예제 코드는 시스템에 수행중인 모든 프로세스 중에 메모리가 20Mb 이상을 사용하는 프로세스를 찾아사용하는 메모리 양을 기준으로 정렬을 수행하고그 프로세스의 속성 중에 Id, Process Name 만으로 새로운 anonymous type을 생성해서 반환하도록 한다.

 

기존 코드로 이 작업을 수행하려면, Filtering, Sorting, 새로운 Class 정의 등 상당히 많은 코드를 구현해야 하지만예제 코드를 사용하면 (질의 문법에 약간이라도 익숙하다면직관적이고코드도 상당히 간단해 진다.

 

 

2.     Query Operator

Query operator query expression과는 달리메소드 호출을 이용하여 질의를 수행하므로기존 C# Language 문법과 유사하다.다만 C#의 새로운 특징인 (사실 새로운 기능이 아니더라도 가능하게 할 수는 있다. – Nhibernate ICriteria, DetachedCriteria가 그런 경우이다.) extension methods 를 이용하여코드를 일목요연하게 표현 할 수 있다.


 코드 2. Query Operator Sample

 

Query expression과 같은 작업을 수행하는 코드지만기존 C# 코드와 큰 차이가 없다다만 Lambda expression에 대한 공부는 좀 해야겠지요

 

두 예제 모두 붉은 글자로 코드상에서 사용된 C# 3.0의 새로운 특징을 명시했습니다많은 특징들을 LINQ가 이용하므로여러분 중LINQ를 쓰시고자 한다면, C# 3.0의 새로운 특징들을 먼저 공부해야 합니다물론 이러한 새로운 특징들이 꼭 LINQ 기술을 쓸 때만 유용한 것은 아니고전통적인 코드상에서도 상당한 잇점을 제공합니다.

 

그럼 이 두 가지 방식 중에 어떤 걸 이용해야 할까요?

답은 당신 맘대로” 입니다.

 

그럼 넌저요 Query operator 방식을 더 선호합니다.

이유는?

뭐 여러가지가 있겠지만가장 먼저 생각나는 건 메소드 사용이 익숙하고이해하기에도 더 쉽거든요.

또다른 큰 이유는 Query Operator는 확장이 가능하지만, Query expression은 예약어 방식이라, MS 말고는 확장이 곤란합니다.

 

 5.에서는 Query operator와 expression 간의 대응관계를 표시하고 있는데실제 예약어 방식인 query expression에서는 제공하지 않는 부분이 많습니다다만 query operator의 메소드 명이 제게는 직관적이지 않은 부분은 불만입니다.

 

 

 

표 5. Query Operator & Expression

Operator

Expression

Operator

Expression

All

N/A

OrderBy

Orderby …, …

Any

N/A

OrderByDescending

Orderby …, … descending

Average

N/A

Select

Select

Cast

From int I in numbers

SelectMany

Multiple from clauses

Count

N/A

Skip

N/A

Distinct

N/A

SkipWhile

N/A

GroupBy

Group … by … [ into …]

Sum

N/A

GroupJoin

Join … in … on … equals … into …

Take

N/A

Join

Join … in … on … equals …

TakeWhile

N/A

LongCount

N/A

ThenBy

Orderby …,…

Max

N/A

ThenByDescending

Orderby …,… descending

Min

N/A

Where

Where

 

 

 

 

 

이제까지 C# Language의 버전별 새로운 특징을 살펴봤고마지막에는 LINQ에 대한 간략한 소개를 했습니다앞서 설명했지만새로운 버전으로 Upgrade시에는 새로운 기능이 뭐가 있고어떤 장점이 있는지 파악하고 선택적으로 사용하는 것이 우선입니다특히나 C# Language 는 가장 기본이 되는 특성이므로꼭 알아둬야 하고자신의 것으로 만들 필요가 있습니다.

'IT > C#' 카테고리의 다른 글

C#2.0 Iterators,Partial 클래스,Nullable 타입  (0) 2009.10.07
닷넷 트랜잭션 정리  (0) 2009.09.30
C# 3.0 개요  (0) 2009.09.11
[C# 2.0] Generics, Iterator, Anonymous, Partial  (0) 2009.08.24
[.net Framework] System.Activator 객체  (0) 2009.08.24