728x90
Visual Studio 을 사용하면서 가장 많이 보는 페이지가 바로 시작 페이지 입니다. Visual Studio 가 업데이트 되면서 시작 페이지는 개발자 / 설계자 분들이 보다 사용하기 편하도록 조금씩 변화되어 왔습니다. 그런데 Visual Studio 2010 에서 부터는 파격적으로 그 모습이 변화가 되었는데요, 일단 그 모습을 한번 보도록 하겠습니다.


산뜻한 인디고 블루 톤의 파란색 화면이 무척 인상적입니다. 이 시작 페이지는 재미있게도 WPF 의 XAML 로 구성되어 있는 페이지 입니다. XAML 로 되어 있다는 말은, 사용자가 XAML 파일을 수정해서 본인의 입맛에 맞게 구성할 수 있다는 이야기 입니다. 후에 다른 포스팅을 통해서 XAML 을 커스터마이징 하는 모습을 보도록 하겠습니다.


새로운 프로젝트를 생성하는 화면도 보기 좋게 변했습니다. 참 오랫동안 새 프로젝트 생성 화면이 변화가 없었는데요 윈도우 서버 2008 의 관리 콘솔과 같은 3단 구성으로 깔끔하게 바뀐 모습입니다. 닷넷 프레임워크 4.0 이 올라가면서 프레임워크 4가 새롭게 추가된 모습도 눈에 들어옵니다.

- NoPD -
728x90
728x90
금요일을 맞이하여 마이크로소프트가 새롭게 준비중인 Visual Studio 2010 의 Beta 1 버전을 설치했습니다. 따로 개발 적인 측면에서 VS 를 살펴보려는 이유는 아니고, 준비중인 원고에서 Visual Studio 2010 에서 확인할 내용이 몇가지 있어서 임시로 회사 PC 에 설치를 감행(?)했습니다. 워낙에 하드디스크 용량이 부족한 회사 PC 인지라, VS 2010 과 .NET Fx 4 가 올라가면 시스템이 뻗어버리는 것 아닐까 하는 걱정 때문이었지요.

여차저차 설치를 마치고 나니 하드디스크의 용량은 약 400MB 정도 남았습니다. VS2010 의 설치경로를 별도의 Path를 잡아 주었음에도 공통 모듈과 같은 부분들이 윈도우 OS 의 설치 경로에 영향을 받는게 아닌가 싶습니다. 간단하게 설치과정을 보도록 하겠습니다.


셋업 파일을 실행하면 군더더기 없는 푸른색의 깔끔한 인스톨러 화면이 눈에 띕니다. 시간이 지나면서 마이크로소프트가 공급하는 프로덕트들의 인스톨 화면들은 단순함을 추구하는 방향으로 가는 듯 합니다. 가볍에 Next 버튼을 눌러 다음 과정으로 넘어갔습니다.


어제 Visual Studio 2008 과 닷넷 프레임워크 4 의 연계를 먼저 해보려고 시도했던 탓에 이미 설치된 컴포넌트로 구분되어 화면에 출력됩니다. 5가지 항목이 새롭게 설치될 거라는 내용이 보이는데요, 실제로는 더 세세하고 다양한 항목들이 설치 과정중에 제 하드디스크에 침투하는 모습을 볼 수 있었습니다.


간단한 런타임 부터 Visual Studio 의 메인 프로그램까지 즐비한 요소들이 설치를 준비하고 있습니다. 웹 인스톨러를 다운로드 받아 설치를 진행했기 때문에 웹 에서 설치파일 다운로드가 먼저 진행되고 실제 설치는 다운로드가 끝난 다음 진행되는 모습입니다. 사용자가 한눈에 설치 진행상황을 볼 수 있는 좋은 구조입니다.


30분정도 웹서핑을 즐기면서 기다리니 설치가 성공적으로 끝났다는 메세지가 출력됩니다. 아주 일반적인 윈도우 XP 환경에서 설치작업을 진행했는데 큰 문제없이 설치가 마무리 되었습니다. 아마도 닷넷 프레임워크 4 를 같이 설치하는 경우에는 시간이 조금 더 소요될 것 같습니다. 닷넷 프레임워크 3.5 SP 1 도 필요하다는 처음의 메세지로 미루어 볼 때, 미리 이것저것 깔려있지 않다면 1시간 이상 설치시간이 소요되지 않을까 싶습니다.


Visual Studio 2008 의 스타트 업 화면과 비슷한 느낌의 화면이 떠오릅니다. SVN 클라이언트도 지가 알아서 잘 땡겨오는 착한 모습을 보여주고 있습니다. 평가판이니 평가만 하고 재빨리 지워주는게 도리이겠지요? 간만에 설치해본 Visual Studio 였습니다 :-)

- NoPD -
728x90
728x90
* 이 글은 오라클 기술 네트워크(Oracle Technology Network)에 공개된 Joh Paul Cook 의 영문 아티클을 번역 / 의역한 글입니다. 원문은 링크(http://tinyurl.com/m69mvh)를 통하여 확인하실 수 있습니다.

에러 핸들링

에러가 발생하게 되면 닷넷 어플리케이션은 유연하게 에러를 핸들링 해야 하며 사용자에게 의미있는 메세지를 전달해 주어야 합니다. Try-Catch-Finally 에러 핸들링 구조는 닷넷 언어의 한 부분입니다. 아래의 소스코드는 오라클 연계 개발시 Try-Catch-Finally 에러 핸들링 구조를 사용하는 간단한 예입니다.

try
{
    conn.Open();

    OracleCommand cmd = new OracleCommand();
    cmd.Connection = conn;

    cmd.CommandText = "SELECT dname FROM dept WHERE deptno = " + textBox1.Text;
    cmd.CommandType = CommandType.Text;
    if (dr.Read())
    {
        label1.Text = dr["dname"].ToString();
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message.ToString());
}
finally
{
     // 객체 초기화 코드
}
이러한 에러 핸들링 방식은 에러 발생시 무리 없이 에러를 처리할 수 있는 구조이긴 하지만, 사용자 친화적인 방식의 에러 처리라고 보기는 어렵습니다. 이러한 코드상에서 에러가 발생하는 경우 아래와 같이 불친절한 메세지가 사용자에게 출력되게 됩니다.


ORA-12154 와 같은 에러 코드, 에러 메시지는 오라클 DB 관리자(DBA)나 개발자 에게는 굉장히 유용한 메세지 임은 틀림없는 사실입니다만 사용자에게는 전혀 그렇지 못합니다. 보다 나은 에러 핸들링 방법은 추가적인 Catch 구문을 이용하여 주요 데이터베이스 에러 코드를 처리하고 사용자 친화적인 메세지를 출력해 주는 것입니다.

catch (OracleException ex)
{
    switch (ex.Number)
    {
        case 1 :
            MessageBox.Show(" 중복된 데이터를 Insert 하고 있습니다 ");
            break;
        case 12545 :
            MessageBox.Show(" 데이터베이스를 사용할 수 없습니다 ");
            break;
        ...
        ...
        default :
            MessageBox.Show(" 처리되지 않은 데이터베이스 에러가 발생했습니다 : " + ex.Message.ToString();
            break;
        }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message.ToString());
}
보다 상세하게 처리 로직을 추가한 위의 코드를 보면 catch 문이 2개가 사용된 것을 볼 수 있습니다. 오라클과 관련된 에러를 핸들링하는 catch 구문과 일반적인 에러를 핸들링하는 catch 구문이 그것입니다. 이와 같이 에러 메세지를 처리해 주면 사용자에게 보다 편안한 에러 메세지를 제공해 줄 수 있을 것입니다.

- NoPD -
728x90
728x90

* 이 글은 오라클 기술 네트워크(Oracle Technology Network)에 공개된 Joh Paul Cook 의 영문 아티클을 번역 / 의역한 글입니다. 원문은 링크(http://tinyurl.com/m69mvh)를 통하여 확인하실 수 있습니다.

Visual C# 구문

프로젝트에 참조 추가를 한 다음 using 구문을 이용하여 네임스페이스를 선언해 주어야 합니다. 기술적으로 네임스페이스 선언은 해주지 않아도 관계 없지만, 간결한 코드를 위해서는 꼭 선언해 주는 것이 좋습니다. 일반적인 경우와 마찬가지로 네임스페이스나 클래스 선언이 시작되기 전에 using 문을 추가해 주면 됩니다.

using Oracle.DataAccess.Client
참조가 정상적으로 추가되었다면 using 문으로 네임스페이스를 선언하는 동안 인텔리센스의 도움을 받으실 수 있었을 것입니다.


연결 문자열과 객체

오라클 연결 문자열은 tnsnames.ora 파일에 정의된 내용과 밀접한 관계를 가지고 있습니다. 여러분들의 tnsnames.ora 파일에 아래와 같이 XE 라는 이름으로 오라클 연결 문자열이 정의되어 있다고 가정해 봅시다. (참고로, tnsnames.ora 파일은 오라클 클라이언트가 설치된 경로의 하위에 network/admin 폴더에 저장되어 있습니다. 클라이언트 버전에 따라 위치는 조금씩 상이할 수 있습니다)

XE =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = DBSVR)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = XE)
    )
  )
XE 라는 약어는 오라클 클라이언트를 위한 데이터베이스 연결 주소 정보를 정의하고 있습니다. tnsnames.ora 파일에 정의된 위의 약어를 사용하기 위해서 비주얼 스튜디오에서 아래와 같은 연결 문자열 선언을 해야합니다.

string oradb = "Data Source=XE;User ID=scott;Password=tiger;";
물론 tnsnames.ora 파일을 사용하지 않기 위하여 연결 문자열을 아래와 같이 변경할 수도 있습니다. tnsnames.ora 파일에 지정된 내용을 그대로 연결 문자열에 정의하면 됩니다.

string oradb = "Data Source=(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = DBSVR)(PORT = 1521))) " +
               "(CONNECT_DATA =(SERVICE_NAME = XE)));" +
               "User Id=scott;Password=tiger;";
위에서 볼 수 있는 것처럼, 사용자 이름과 패스워드는 연결 문자열 속에 평문으로 저장되어 있습니다. 이 방법은 연결 문자열을 만드는 가장 간단한 방법이지만 보안의 관점에서 봤을 때는 평문으로 저장된 사용자 이름, 패스워드는 좋은 선택이 아닙니다. 특히, 닷넷 어플리케이션은 DLL, EXE 를 막론하고 디스 어셈블러를 통해서 소스 코드의 복원이 가능하기 때문에 보안에 취약합니다. 이와 관련한 내용은 다른 글에서 보다 자세히 다루도록 하겠습니다.

다음으로, 여러분은 커넥션 클래스를 이용하여 객체를 생성하고 초기화 해야만 합니다. 연결 문자열은 커넥션 객체에 할당 되어야 합니다.

OracleConnection conn = new OracleConnection(XE);
연결 문자열의 할당은 오버로드된 객체의 생성자를 통해서 전달되어 할당이 가능합니다. 생성자의 다른 오버로드는 아래와 같은 구문도 사용 가능하도록 정의되어 있습니다.

OracleConnection conn = new OracleConnection();
conn.ConnectionString = oradb;
연결 문자열의 할당이 끝나면 이제 남은 일은 커넥션 객체의 Open 메소드를 이용하여 오라클 데이터베이스와의 실제 연결을 만드는 작업을 하면 됩니다. 이 과정에서의 에러 핸들링은 다음 포스트에서 소개하도록 하겠습니다.

conn.Open();
Command 객체

Command 객체는 실행 되어야 하는 SQL 문자열이나 저장 프로시저를 SQL 명령의 형태로 지정할 때 사용됩니다. Connection 객체와 마찬가지로 해당 클래스로부터 인스턴스가 만들어져야 합니다. 아래의 예제에서 ODP.NET 은 부서 테이블로부터 부서 번호가 10인 부서 명(DNAME)을 돌려주는 SQL 구문을 수행할 것입니다.

string sql = "SELECT dname FROM dept WHERE deptno = 10";
OracleCommand cmd = new OracleCommand(sql, conn);
cmd.COmmandType = COmmandType.Text;
오버로드된 다른 생성자를 사용하면 구문은 조금 다르게 변할 수 있습니다. Command 객체는 커맨드 텍스트를 실행할 수 있는 메소드를 가지고 있습니다. 이 메소드들은 서로 다른 형태의 SQL 구문에 적절한 메소드 들입니다.

스칼라 값 얻기

실제로 데이터를 데이터베이스로부터 얻기 위해서 OracleDataReader 객체를 생성하고 ExecuteReader 메소드를 사용하면 됩니다. 데이터는 컬럼 이름을 지정하거나 인덱스 번호를 이용하여 엑세스 할 수 있습니다. 결과 값은 닷넷 고유의 데이터 형을 이용하거나 오라클 고유의 데이터 형을 이용하여 엑세스 할 수 있습니다. 닷넷에 포함되어 있는 어떤 언어를 사용하더라도 이같은 특징을이용할 수 있습니다.

OracleDataReader dr = cmd.ExecuteReader();
dr.Read();

label1.Text= dr["dname"].ToString();
label1.Text = dr.ZGetString(0).ToString();
label1.Text = dr.GetOracleString(0).ToString();
위의 예제에서 우리는 DNAME 이라는 문자열 형태의 리턴 값을 가지고 데이터를 핸들링 하고 있습니다. 그러나 DEPTNO (부서번호) 와 같은 문자열이 아닌 데이터를 핸들링 할 떄는 타입 미스매치(Type Mismatch)에 주의해야 합니다. 닷넷 런타임 라이브러리는 암시적으로 적절한 형 변환을 자동으로 시도합니다. 그러나 간혹 데이터 형의 호환성에 문제가 있거나 암시적인 형 변환이 실패하면 예외가 발생하게 됩니다. 암시적인 형 변환이 에러 없이 수행된다 하더라도 필요한 경우에 대하여 명시적으로 형 변환을 하는 것을 권장합니다.

객체 소멸

데이터베이스 엑세스가 모두 끝나고 나면 Connection 객체의 Close 혹은 Dispose 메소드를 반드시 호출해 주어야 합니다. Dispose 메소드는 내부적으로 Close 메소드를 호출하도록 되어 있습니다.

conn.Close();
conn.Dispose();
코드를 만들 때 using 문을 이용하여 로직을 구성한 경우에는 명시적으로 Close 나 Dispose 메소드를 호출할 필요가 없습니다. 아래의 코드는 using 문을 이용하여 데이터베이스를 연결하는 예제 코드입니다.

using (OracleConnection conn = new OracleConnection(oradb))
{
    conn.Open();
    OracleCommand cmd = new OracleCOmmand();
    cmd.Connection = conn;
    cmd.CommandText = "select dname from dept where deptno = 10";
    cmd.COmmandType = COmmandType.Text;
    OracleDataReader dr = cmd.ExecteReader();
    dr.Read();
    label1.Text = dr.GetString(0);
}
추가적으로 OracleCommand 객체는 Dispose 메소드를 포함하고 있고 OracleDataReader 객체는 Close 와 Dispose 메소드를 포함하고 있습니다. 일반적인 경우에는 객체의 생성과 소멸이 큰 영향을 주지 않을 수 있지만 닷넷 환경에서 시스템의 리소스를 해제하고 어플리케이션의 성능 향상을 위해서 반드시 신경써 주어야 할 부분입니다.

- NoPD -
728x90

+ Recent posts