2012년 5월 1일 화요일

516) ADO 닷넷 강좌 펌111

깜찍아, ADO.NET??? ADO.NET!!!
   강좌 최초 작성일 : 2002년 03월 04일
   강좌 최종 수정일 : 2002년 03월 04일
   작성자 : 깜찍이(박 수인)
   편집자 : Taeyo(김 태영)
   강좌 제목 : 데이터베이스에 명령을 내리자
강좌 전 태오의 잡담>
기대하시라.. 짜잔!! 태오의 웹 서비스 강좌!!! 짜잔!! 언제??? 그런 예리한... -_-+ (히죽)



안녕하세요.
제 두번째 강좌가 올라가고 또 많은 시간이 흘렀네요. 모든 강좌를 빨리 올리겠다고 생각을 하고 있는데 그게 그리 쉽게 되지가 않네요. 아무튼 이제부터라도 더 빨리 올릴 수 있도록 노력하겠습니다. 강좌를 시작하기 전에 어떤 분께서 질문하신 내용 중에서 강좌 내용대로 했는데 다음과 같은 에러가 난다고 하신 분이 계셨습니다.
using System.Data.SqlClient;를 사용할때 다음과 같이 에러가 납니다. 조언부탁드립니다.
--------------------------------------------------------------------------------------------------
E:\vb7.0\vc\net\ConnectionEx\Class1.cs(2): The type or namespace name 'Data' does not exist in the class or namespace 'System'

이런 에러는 .NET 버전 때문에 그렇거든요. 전 비주얼 스튜디오 닷넷 RTM 으로 진행하고 있습니다. 베타 2 이상에서는 무리없이 돌아갈 거예요.
이번에 다룰 내용은 데이터베이스에 여러가지 명령을 내릴 수 있는 것에 대해서 알아보도록 하겠습니다. 기존에 ADO 와 함께 ASP 를 다뤄보신 분이라면 ( 제 강좌를 보신 분이라면 잘 알고 계신 ^^ ) Command 객체를 사용하게 됩니다. ADO.NET에서의 Command 객체는 이전과는 그리 다르지 않습니다. 다만 ADO 에서는 Command 객체를 사용하지 않더라도 데이터베이스에서 레코드를 가져올 수 있었습니다. Command 객체를 사용할 때라고는 Stored Procedure ( 이하 sp )를 사용할 때에 자주 사용되었죠.
하지만 ADO.NET에서는 모든 명령을 내릴 경우에는 이 Command 객체를 사용해야 합니다. 데이터를 가져올 때에도, 데이터를 입력, 수정, 삭제 등 모든 명령은 Command 객체를 사용해야 한다는 것이죠.
Command 객체의 라이프 사이클 ( Life Cycle ) 은 다음과 같습니다.
ⓐ Connection 객체를 생성합니다.
ⓑ Command 객체를 생성합니다.
ⓒ Command 객체의 CommandText 프로퍼티에 쿼리문이나 저장 프로시저를 설정합니다.
ⓓ Command 객체의 CommandType 프로퍼티에 실행될 쿼리문의 종류를 설정합니다.
ⓔ Command 객체의 Connection 프로퍼티에 Connection 객체를 설정해줍니다.
ⓕ Connection 객체의 Open() 메서드를 호출하여 데이터베이스를 열어줍니다.
ⓖ Command 객체의 Execute 메서드를 호출하여 해당 쿼리문이나 저장 프로시저를 실행합니다.
ⓗ Connection 객체의 Close() 메서드를 호출하여 데이터베이스를 닫아줍니다.
물론 꼭 위와 같이 해야 하는 것은 아닙니다. Command 객체의 생성자에서 Connection 객체와 CommandText 프로퍼티를 같이 지정할 수 있어서 한꺼번에 사용할 수도 있습니다. 이번에는 생성자에 매개 변수가 없는 것을 사용해서 위와 같은 사이클을 따라서 구현해 보도록 하겠습니다.
우선 예제에 사용할 데이터베이스의 환경을 구축하도록 하겠습니다. 전 Study 라는 데이터베이스를 생성해서 사용하도록 하겠습니다. 사용하시려는 데이터베이스에서 다음과 같이 테이블을 생성합니다. 이번 예제는 테이블의 이름에서도 알 수 있듯이 주소록이 되겠습니다. ^^;;
Create Table Address
(
    ID        varchar(20)    Not Null    -- ID
,    Name        varchar(20)    Not Null    -- 이름
,    Email        varchar(100)    Null        -- 이메일
,    Age        tinyint        Not Null    -- 나이
,    BirthDay    datetime    Not Null    -- 생일
)
위와 같이 테이블을 만들었으면 테이블에 값을 입력할 수 있도록 sp를 작성하도록 하겠습니다. 참고로 모든 입력, 수정, 삭제는 sp를 사용해서 진행하도록 하겠습니다. 하지만 이번 강좌는 기초를 알아보는 부분이므로 sp 를 사용하는 방법과 쿼리문을 바로 입력할 수 있도록 하겠습니다. 입력을 하는 sp는 필요한 모든 데이터가 입력된 경우에만 데이터를 입력합니다. 또, 필요한 필드의 값이 들어오지 않는다면 -1 ~ -4 의 값을 리턴해서 응용 프로그램에서 사용할 수 있도록 합니다.
Create Proc up_InsertAddress
    @ID        varchar(20)    = Null
,    @Name        varchar(20)    = Null
,    @Email        varchar(100)    = Null
,    @Age        tinyint        = 0
,    @BirthDay    datetime    = Null
As
Begin
    -- ID 를 입력하지 않으면 -1을 리턴한다.
    If @ID Is Null
        Return    -1

    -- 이름을 입력하지 않으면 -2를 리턴한다.
    If @Name is Null
        Return    -2

    -- 나이를 입력하지 않으면 -3을 리턴한다.
    If @Age = 0
        Return    -3

    -- 생일을 입력하지 않으면 -4를 리턴한다.
    If @BirthDay is Null
        Return    -4

    -- 테이블에 데이터를 입력한다.
    Insert Into Address (
        ID
        , Name
        , Email
        , Age
        , BirthDay
    ) values (
        @ID
        , @Name
        , @Email
        , @Age
        , @BirthDay
    )

    -- 오류번호를 리턴한다.
    -- 0 이라면 정상적으로 처리된 것이다.
    Declare    @iErr    int

    Set    @iErr = @@ERROR

    Return    @iErr
End
어떤가요? sp는 그리 어렵지는 않지요? 이렇게 만들고 나면 준비작업은 모두 끝났습니다. 비주얼 스튜디오 닷넷을 실행해서 예제를 만들어보도록 하겠습니다.
VS.NET을 띄우고 새 프로젝트를 선택한 후에 다음과 같이 프로젝트를 생성합니다. 프로젝트의 이름은 CommandEx 입니다.
새 프로젝트가 생성이 되면 코드 편집기에 다음의 코드를 입력합니다. 이번 강좌에서는 데이터를 입력하는 부분만 다루도록 하겠습니다. 만일 수정이나 삭제를 하실 경우는 입력과는 쿼리문만 다르므로 그 부분만 손을 보시면 되겠네요.
using System;
using System.Data;
using System.Data.SqlClient;

namespace CommandEx
{
    ///
    /// Summary description for Class1.
    ///

    class Class1
    {
        ///
        /// The main entry point for the application.
        ///

        [STAThread]
        static void Main(string[] args)
        {
            // Connection 객체를 생성합니다.
            SqlConnection connection = new SqlConnection( "server=localhost;"
                + "database=Study;uid=sa;pwd=0000" );

            // 데이터를 입력하는 메서드를 호출합니다.
            InsertData( connection );
        }

        static void InsertData( SqlConnection connection )
        {
            // Command 객체를 생성합니다.
            SqlCommand command = new SqlCommand();

            /*****************************************************
             * 데이터베이스에 데이터를 입력합니다.
             * **************************************************/
            // CommandText 프로퍼티를 사용해서 커리문을 설정합니다.

            command.CommandText = "Insert into Address "
                + "( ID, Name, Email, Age, BirthDay ) "
                + " values ( '9999', '9999', '9999@999.com', 32, '19710301' )";
            // CommandType 프로퍼티를 사용해서 쿼리문의 종류를 설정합니다.
            command.CommandType = CommandType.Text;

            // Connection 객체의 연결을 사용하도록 하기 위해서
            // Command 객체의 Connection 프로퍼티를 설정합니다.
            command.Connection = connection;

            try
            {
                // 데이터베이스를 열고 명령을 실행합니다.
                connection.Open();
                // 명령을 실행하고 명령에 영향을 받은 레코드수를 반환받습니다.
                int iResult = int.Parse( command.ExecuteNonQuery().ToString() );
                Console.WriteLine( "================================" );
                Console.WriteLine( "{0} 개의 레코드가 입력되었습니다.", iResult );
                Console.WriteLine( "================================" );
            }
            catch( Exception e )
            {
                Console.WriteLine( e.Message );
            }
            finally
            {
                connection.Close();
            }
        }
    }
}
모든 소스를 입력했으면 Ctrl + F5 를 눌러서 실행을 합니다.
어떤가요? 제대로 나오나요?
예? 쿼리문을 그냥 넣을 거면서 왜 sp 를 작성했냐구요? 조금만 기다리세요. 잠시 후에 sp 를 이용할 거랍니다. ^^ 이번에는 위의 소스를 간단히 분석해 보도록 하겠습니다. 머 별로 복잡하지도 않고 단순히 3가지만 유의 해서 보면 됩니다. 우선 첫번째로 CommandText 프로퍼티 입니다.
/*****************************************************
* 데이터베이스에 데이터를 입력합니다.
* **************************************************/
// CommandText 프로퍼티를 사용해서 커리문을 설정합니다.

command.CommandText = "Insert into Address "
    + "( ID, Name, Email, Age, BirthDay ) "
    + " values ( '9999', '9999', '9999@999.com', 32, '19710301' )";
CommandText 프로퍼티는 데이터베이스에 전달할 쿼리문을 설정하는 프로퍼티이지요.
따라서 위와 같이 쿼리문을 직접 입력해서 소스에 넣는다면 쿼리문을 그대로 넣어주면 되는 것이고 그렇지 않고 sp 를 사용하는 경우에는 sp의 이름을 설정하면 되는 것입니다.
다음으로는 CommandType 프로퍼티입니다.
// CommandType 프로퍼티를 사용해서 쿼리문의 종류를 설정합니다.
command.CommandType = CommandType.Text;
CommandType 프로퍼티에는 Text, StoredProcedure, TableDirect 의 3가지가 있는데 여기에서는 일반적인 쿼리문을 그대로 넣어주었으므로 Text로 설정을 했습니다.
다음으로는 ExecuteNonQuery 메서드입니다.
connection.Open();
// 명령을 실행하고 명령에 영향을 받은 레코드수를 반환받습니다.
int iResult = int.Parse( command.ExecuteNonQuery().ToString() );
데이터를 입력하는 쿼리문을 실행할 때에는 위와 같이 ExecuteNonQuery() 메서드를 사용합니다.
이 메서드는 명령을 실행한 후에 영향을 받은 레코드의 숫자를 반환합니다.
어떤가요? 상당히 쉽죠?
이번에는 sp를 사용해서 데이터를 입력해 보도록 하겠습니다.
다음의 소스를 위의 Class1.cs 파일에 추가합니다.
static void InsertDataWithSp( SqlConnection connection )
{
    // Command 객체를 생성합니다.
    SqlCommand command = new SqlCommand();

    // CommandText 프로퍼티를 사용해서 sp의 이름을 설정합니다.
    command.CommandText = "up_InsertAddress";

    // CommandType 프로퍼티를 사용해서 sp를 사용한다고 알립니다.
    command.CommandType = CommandType.StoredProcedure;

    // Connection 객체의 연결을 사용하도록 하기 위해서
    // Command 객체의 Connection 프로퍼티를 설정합니다.
    command.Connection = connection;

    // 저장 프로시저의 매개변수를 설정합니다.
    command.Parameters.Add( "@ID", SqlDbType.VarChar, 20 );
    command.Parameters.Add( "@Name", SqlDbType.VarChar, 20 );
    command.Parameters.Add( "@Email", SqlDbType.VarChar, 100 );
    command.Parameters.Add( "@Age", SqlDbType.TinyInt, 0 );
    command.Parameters.Add( "@BirthDay", SqlDbType.DateTime, 20 );

    // 지정한 매개변수에 값을 입력합니다.
    command.Parameters["@ID"].Value = "CuteGuy";
    command.Parameters["@Name"].Value = "깜찍이";
    command.Parameters["@Email"].Value = "Cuteguy@CuteGuy.net";
    command.Parameters["@Age"].Value = 30;

    DateTime dt = new DateTime( 1972, 3, 1);

    command.Parameters["@BirthDay"].Value = dt;

    // 리턴 값을 받을 매개변수를 설정합니다.
    SqlParameter param = command.Parameters.Add( "@Result", SqlDbType.Int );
    param.Direction = ParameterDirection.ReturnValue;

    // 데이터베이스와의 연결을 열고 sp를 실행합니다.
    command.Connection.Open();
    command.ExecuteNonQuery();

    // 리턴값을 받아서 결과값을 화면에 출력합니다.
    int iResult = Convert.ToInt32( command.Parameters["@Result"].Value );
    string ErrMsg = null;

    switch( iResult )
    {
        case    0 :
            ErrMsg = "정상적으로 입력되었습니다.";
            break;

        case    -1 :
            ErrMsg = "ID가 입력되지 않았습니다.";
            break;

        case    -2 :
            ErrMsg = "이름이 입력되지 않았습니다.";
            break;

        case    -3 :
            ErrMsg = "나이가 입력되지 않았습니다.";
            break;

        case    -4 :
            ErrMsg = "생일이 입력되지 않았습니다.";
            break;
    }

    Console.WriteLine( ErrMsg );
}
이렇게 추가를 한 후에는 Main 메서드를 다음과 같이 변경합니다.
static void Main(string[] args)
{
    // Connection 객체를 생성합니다.
    SqlConnection connection = new SqlConnection( "server=localhost;"
        + "database=Study;uid=sa;pwd=0000" );

    // 데이터를 입력하는 메서드를 호출합니다.
    InsertData( connection );

    // sp를 이용해서 데이터를 입력하는 메서드를 호출합니다.
    InsertDataWithSp( connection );

}
이제까지 쿼리문을 통해 직접 데이터베이스에 전달하는 방법과 sp를 사용해서 데이테베이스에 전달하는 방법에 대해서 간단히 알아보았습니다.
기존에 제 강좌를 보신 분이라면 asp 에서 sp를 사용했던 것과 그리 큰 차이를 보이지 않고 있는걸 알고 계실 것입니다.
이번 강좌에 사용한 소스 파일은 제 홈페이지의 공개 소스 자료실에서 다운을 받으실 수 있습니다.
다음에는 데이터를 불러오는 클래스인 DataReader에 대해서 준비하도록 하지요..
여러분들 모두 좋은 하루 되시구요...
그럼 이만...
Written By 깜찍이
HomePage : http://www.cuteguy.pe.kr

댓글 없음:

댓글 쓰기

국정원의 댓글 공작을 지탄합니다.

UPBIT is a South Korean company, and people died of suicide cause of coin investment.

 UPBIT is a South Korean company, and people died of suicide cause of coin. The company helps the people who control the market price manipu...