C# DB 코딩 강좌 2008. 11. 14. 21:11

    아무래도 이야기의 질이 다소 떨어지는듯 싶다. 너무 이야기가 중구난방으로 흐르는듯 해서 하나의 집약하는 방법을 다시금 생각해 봐야겠다.

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

    자 이제 앞써 이야기 했던 ER-win은 친숙해 졌을거니 가볍게 테이블을 하나 추가해보자

    1. 테이블을 하나 만들고(콤보박스용)

    2. 그 테이블을 이용해서 데이터를 가져오도록 하는 DB접속 클래스를 하나 만들고

    3. 그 db접속 클래스를 오라클과 ms-sql용으로 만들고..

    4. 다시그 그 클래스를.. 요리보고 저리보고를 할것이다.

    테이블은 이렇게 만들어 보자.

    clip_image001

    차수는 정규화적 규칙을 위한 PK를 만들고

    콤보박스ID란 각 콤보박스의 고유번호라고 생각하자.(오타를 쩝.. 웃으며 넘기자 고치는게 귀찮다.)

    하여간 심플한 테이블을 하나 만들고 바로 물리테이블을 다시 또 만들자.

    clip_image002

    대략 위와같이 만들수가 있겠다.

    CREATE TABLE Combo

    (

    SEQ int identity NOT NULL ,

    ViewSEQ INTEGER NOT NULL ,

    Expression varchar(100) NOT NULL ,

    Value varchar(100) NOT NULL ,

    UseBool char(1) NULL ,

    Memo varchar(1000) NULL ,

    ComboID varchar(20) NOT NULL

    )

    Execution Successful

    ALTER TABLE Combo

    ADD CONSTRAINT XPKCombo PRIMARY KEY NONCLUSTERED (SEQ ASC)

    Execution Successful

    Schema Generation Complete

    2 query succeeded.

    대충 이렇게 생성을 하도록 하자.(너무 안일한 자세인가?)

    1. 폼설계는 대충 하자.

    clip_image003

    이렇게 하고 버튼의 코드에는

    setDB DB = new setDB();

    dataGridView1.DataSource = DB.callSQL("select * from combo").Tables[0] ;

    이렇게 두줄만 적기로 하자.

    그럼.. 저 setDB를 이제 우리는 클래스를 만들어야 겠다.

    clip_image004

    자 가볍게 이런 소스를 적었다고 보자.

    그럼 결국 디비에 접속해서 정보를 가져오게 될것이다.

    이거야 원 너무 쉬운 이야기라서 참 아쉽기도 하다만.. 문제는 이런 장난같은 함수를 또는 클래스를 만들지 않고 쓴다는게 첫번째 문제이다.

    clip_image005

    SP를 어떻게 사용하는가 하는 질문도 어디서 본듯한데..

    SP의 경우도 별게 없다.

    clip_image006

    자 이렇게 만들었다면.. 이제는 콤보박스에 바인딩을 연습을 해보도록 하자.

    상세한 설명은 링크의 글을 읽어보도록 하고

    http://www.devpia.com/Maeul/Contents/Detail.aspx?BoardID=45&MAEULNO=18&no=394&page=1

    자 일단은 우리가 만든 테이블에 정보를 넣어야 겠다 그래야 콤보박스에 바인딩 하는것을 보여줄테니 말이다.

    insert into combo(viewSeq,Expression,Value,UseBool,Memo,ComboID)

    values(1,'첫번째','1000','T','이건 연습이야','TEST1')

    insert into combo(viewSeq,Expression,Value,UseBool,Memo,ComboID)

    values(2,'두번째','2000','T','너무 귀찮아','TEST1')

    …………...

    이런식으로 넣고 싶은데로. 데이터를 넣어두자.

    clip_image007

    이렇게 콤보박스를 하나 더 추가 시키고..

    테이블의 정보를 저 콤보박스에 셋팅을 시켜보도록 하자.

    DataTable DT = DB.callSQL("select * from combo").Tables[0];

    dataGridView1.DataSource = DT;

    comboBox1.DataSource = DT;

    comboBox1.DisplayMember = DT.Columns["Expression"].ToString();

    comboBox1.ValueMember = DT.Columns["Value"].ToString();

    clip_image008

    이런방식으로 콤보박스가 셋팅되는것을 볼수 있을것이다.

    그러면 또 하나의 질문이 나올듯 한데 왜 이렇게 어렵게 콤보박스를 셋팅하는것인가 말이다.

    그러게 말이다.

    왜 이렇게 어렵게 하는것인지 아마도 잘난척인가 보다. 그저 넘기도록 하자.

    원본 위치 <http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=18&MAEULNO=8&no=1587&page=1>

'C# DB 코딩 강좌' 카테고리의 다른 글

C#을 이용한 DB코딩 12  (0) 2008.11.14
C#을 이용한 DB코딩 11  (0) 2008.11.14
C#을 이용한 DB코딩 10  (0) 2008.11.14
C#을 이용한 DB코딩 9(인터페이스)  (0) 2008.11.14
C#을 이용한 DB코딩 8  (0) 2008.11.14
C#을 이용한 DB코딩 6(TcpChannel)  (1) 2008.11.14
C#을 이용한 DB코딩 5  (0) 2008.11.14
C#을 이용한 DB코딩 4(Virtual PC)  (0) 2008.11.14
C#을 이용한 DB코딩 3  (0) 2008.11.14
C#을 이용한 DB코딩 2  (0) 2008.11.14
posted by 삶의여유로움
:
C# DB 코딩 강좌 2008. 11. 14. 21:10

    이상하게 6번글을 적을때 익스플로워가 버그가 생겨서 글이 날라가거나 또는 적지 못하게 되는 상황이 발생했다.

    아쉽다.. 내가 적은 6번글에 아쉬움을 뒤로하며

    다시 적기도 싫고..

    그냥 이번글에는 아래 강현철님 덕분에 그냥 dataset이야기를 잠시 적어보자.

    DataSet이란…

    게 뭔지는 몰라도 이글을 적는 사람의 입장에서는 거의 예찬론을 펴고 싶다.

    이것은 MVC 의 한몫을 하는 매우 중요한 개념을 지니고 있고 또한 그렇게 설계되고 사용되어지고 있다.

    (누누히 이야기 했지만 난 MVC가 뭔지 모른다.)

    게다가 이 개념덕분에 닷넷의 모든 컨포넌트들이 이것을 지원하기 위해서 다시 만들어지고 또한 잘 지원하고 있다.

    게다가 이녀석이 나올때부터 개인적 느낌인지 몰라도 Linq가 나올것을 예언하지 않았나 한다.

    다들 잘 알고 있듯이 자바의 하이버네이트라는 ORmapper의 등장이 있음으로 닷넷에 추가될 기능이라든지 자바의 Vector를 좀 색다르게 사용하는 느낌의 dataset이라고 생각할수도 있으나 그것은 아니지 않나 하는 느낌을 많이 가진다.(어라 표현이 이상하다.)

    하여간 DataSet의 닷넷의 핵심적인것중 하나임에는 분명한것 같다.

    아님 DB코딩에서 그런것이던지..

    어디 강좌나 또는 PPT 세미나 등등을 다녀보면 무수히 마샬링과 언마샬링 또는 시리얼라이징

    아님 닷넷리모팅 같은 이야기를 하는데

    당최 못 알아 들을 이야기들이고..

    지금 적는것은 3티어란 글이 아래에 있으니 그냥 하나의 컴퓨터에서 다른 컴퓨터로 이 데이타셋을 넘기는 법을 살펴보자.

    이건 계획에 없던글이다. 그러니 대충 대충 적어보자.

    http://msdn.microsoft.com/ko-kr/library/system.data.dataset(VS.80).aspx

    MSDN에 보면

    이런 문구가 있다.

    DataSet 및 DataTable 개체는 MarshalByValueComponent에서 상속되며 원격 서비스를 위한 ISerializable 인터페이스를 지원합니다. 이 두 개체는 원격화할 수 있는 유일한 ADO.NET 개체입니다.

    말 그대로 원격화를 위해서 이녀석을 만들었고(물론 그 이유만 있는것은 아니다.)

    이 녀석을 사용해서 3 tier을 해라는 무언의 암시가 아닌가 싶다.

    그럼 이녀석을 가지고 발음도 이상한 마샬링이란 것을 해볼려면 어떻게 해야하는가?

    대략 일반적으로 3가지 방법있는것 같은데 흔히들 말하는 Com과 Dcom

    그리고 Web Service 같은것들 또는 3.5에서 WCF 를 이용하거나.

    마지막으로 기초적인 TCPClientChannel / TCpServerChannel이 있겠다.

    이미 하드에 다들 보유하고 있는 MSDN에 적혀 있는것이니 그리 유심히 볼 필요도 없는 심풀한것을 구현해 보자.

    http://msdn.microsoft.com/ko-kr/library/system.runtime.remoting.channels.tcp.tcpclientchannel.aspx

    clip_image001

    이건 위의 링크에 있는 MSDN의 소스를 그대로 복사해 둔것이다.

    물론.. 서버도 가동시키고.. 192.168.1.4에는.. TCPServerChannel의 소스를 실행해 두었다.

    이것의 실행화면은

    clip_image002

    이런식이 되는데.. 잘 보듯이 GetCount가 절대로 9를 돌려줄만한 일이 없다는걸 잘 보길 바란다.

    서버쪽의 GetCount는

    clip_image003

    이런식으로 구현이 되어 있다.

    즉 서버의 함수를 실행하는것이다.

    자바를 배운사람들은 스텁과 스캘레톤을 배운적이 있을건데… 잘 모르겠는가?

    그럼 RMI는 ?...

    RMI도 사전에 없긴하지만.. 여기는 c#게시판이니 적어보도록 하자.

    Remote Method Invocation 의 약자가 RMI인데 쉽게 말하자면 원격에 있는 녀석의 매서드 즉.. 함수를 사용하는것이다.

    자 쓸쓸 짜증이 밀려오니.. 다시금.. 다른 생각을 해보자. 은혜를 꼬시던지.

    2강에 적은 여자이름이 뭐였는지 사실 기억이 나지 않기 시작한다. 은영이였나?

    쩝…

    예전에 지금도 있겠지만 이런 프로젝트가 있었다. DES해석을 시도하기 위해서 전세계 PC를 이용하자. 그래서 어쩌고 저쩌고 하는것 말이다.

    (설마 DES ?를 모르지는 않겠지.. 쩝.. 왜 이리 예제도 어려운거야 -_-;;)

    하여간 이 엄청난 암호화 기법을 역공법으로 해석하기 위해서 현재의 CPU의 형태로 안되니 전세계의 PC의 역량을 빌리자는 프로젝트 말이다. 그럼 다른 PC에 있는 계산 능력을 어떻게 사용해야 한단 말인가? 결국 이 기법이란게 핵심적으로 계산을 할 수 있는 함수가 그 피시에 있고 난 그 함수를 호출하면 되는것 아니겠는가?

    조금 어려운가?

    에이.. 막판이다. 이런 생각을 해보자.

    난 지금 피자가 먹고싶다. 그런데 무슨피자를 시킬지 모르겠다

    그래서 피자카타로그를 집어드니

    거기에는 콤비네이션이랑 …. 란 그림과 함께 여러가지가 있었다.

    난 전화를 했다. <-----------

    상대쪽에서 전화를 받았다. 그리고는 나에게 피자를 배달했다.

    여기서 내가 보고 있는 피자카타로그는.. 하나의 내가 원하는것(인터페이스, 또는 스텁)

    이고 피자가게에서 만든 내가 주문한것을 듣고 피자를 만드는 행위를 하는것(스켈레톤)

    그 피자를 나에게 배달하는것 내가 피자를 받는게 결과값을 받는것과 동일하다.

    아.. 어렵다. 뭐야 정말.

    이게 왜 dataset과 관계가 있고 3tier랑 관계가 있는거야?

    그렇다. 아무런 관계가 없다. 그냥.. 심심해서 적어봤다. 하여간 저따구걸 하는 동작을 마샬링이라고 하는데 말이다.

    쩝.. 좀 있다 다시 짜장으로 다시 설명을 해보자.

    근데 3tier를 왜 설명하고 있는지 모르겠네 이렇게 구현할것도 아닌데 쩝..

    괜히 말린것 같다.

    아래에 3tier란 글이 올라오니 그게 뭔지도 모르면서 갑자기 설명하고픈 욕구가 생겨나다니 난 왜 이런단순세포일까..

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

    일단 소스를 이용해서 getCount함수를 이번에는 return값을 DATASET 으로 받아보자.

    Dataset 음.. 하여간 그래야 조금 더 실감이 날 것 같다.

    clip_image004

    자.. 함수를 아래쪽을 봐라.. 리턴값을 수정했다.

    이걸 호출을 해보자.

    clip_image005

    물론 서버에도 수정해야겠지.

    실행결과는

    clip_image006

    이렇게 나온다.

    clip_image007

    호출을 XML형태로 뿌려주게 했기 때문이다.

    서버에서 dataset을 만들어서 데이터를 저렇게 넣어둔것이다.

    이말은 즉.. 서버에서 보내는 dataset을 클라이언트가 받는다는 이야기가 된다.

    조금 이해가 오는가?

    3 tier란게 사실 별게 없다. 중간에 TCP서버같은 일종의 체팅서버가 떡하니 하나가 있고

    다른녀석들이 여기에 접속해서 정보를 받아가는것에 불과하다.

    단지 그 정보를 받아가는것이 Dataset으로 받아갈수 있다는것 그게 핵심이다.

    (물론 이것은 지금만 그렇다는것이고 실제적으로 후벼파다 보면 EJB같은것까지 여러형태로 사용되어진다.

    그러나 지금처럼 DB코딩 그것도 닷넷에서 의 한정적인 입장에서는 dataset을 일종의 다리로 이용해서

    정보를 전달하기 때문에 이렇게 설명을 하고 있다. 물론 닷넷에서는 EJB가 아닌  Dcom을 사용해서 처리하게 될것이다만

    기초를 알면 저런건... 사전을 찾아보면 될것이다. 물론 사전에 EJB가 없긴 하더라만..)

    결과에 나오는정보는 클라이언트 소스의 어디에도 없다는 것이고 결국 저것이 실행된곳은 서버이고 정보를 받는것만 하는것이다.

    그럼 왜 클라이언트에도 Getcount란 함수가 있어야 하는가 말이다.

    그건 내가 짜장면집에 전화를 걸어서 짬뽕 한그릇 했을때 난 이미 짱뽕이란 개체가 어떤건지 알고 있어야 되는것이 아닌가?...

    최소한 그것이 "음식"이란것을 알고 있어야지만 된다는 것이다. 돌려주는 값의 타입을 알아야 시킬것이 아닌가…

    이런 개념들을 자바에서는 RMI라고 이야기 하고

    개체가 왔다 갔다를 위해서 처리되는것을 마샬링 역으로 언마샬링이라고 한다.

    그 내부적인형태를 시리얼라이징 이라고 해서 "개체 직렬화"라고 이야기 하고

    그러기 위해서 가장 적당하다는 XML을 통해서 처리하는게 다반사이다.

    물론 이 이야기를 더 발전시키면 Com+와 Dcom쪽까지 이야기를 전진해야 하므로 다소 이 DB시리즈 낙서와 너무 이야기가 멀어지므로.. 좀 생략하자.(사실 모른다. 흐흐)

    여하튼 3tier라는게 생각외로 그리 어려운건 아니다.(물론 실제적으로 실무에 사용하려면 아직 넘어야 될 산이 많다.)

    자 요약을 하자.

    1. Dataset 은 직렬화가 가능한 개체이다.

    2. 3 tier란게 사실상 비지니스로직을 처리하는 서버에 클라이언트가 접속해서 데이터를 받아오는것에 불과하다.

    이정도가 될듯 하다.

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

    귀차니즘으로 tcpServerChannel을 찾지 않을듯 하여 아래에 적어둔다.

    http://msdn.microsoft.com/ko-kr/library/system.runtime.remoting.channels.tcp.tcpserverchannel.aspx

    using System;

    using System.Runtime.Remoting;

    using System.Runtime.Remoting.Channels;

    using System.Runtime.Remoting.Channels.Tcp;

    using System.Security.Permissions;

    public class Server

    {

        [SecurityPermission(SecurityAction.LinkDemand)]

    public static void Main()

        {

    // Set up a server channel.

    TcpServerChannel serverChannel = new TcpServerChannel(9090);

            ChannelServices.RegisterChannel(serverChannel);   

    // Expose an object for remote calls.

            RemotingConfiguration.RegisterWellKnownServiceType(

                typeof(Remotable), "Remotable.rem", WellKnownObjectMode.Singleton

            );

    // Show the name and priority of the channel.

            Console.WriteLine("Channel Name: {0}", serverChannel.ChannelName);

            Console.WriteLine("Channel Priority: {0}", serverChannel.ChannelPriority);

    // Show the URIs associated with the channel.

            ChannelDataStore data = (ChannelDataStore) serverChannel.ChannelData;

    foreach (string uri in data.ChannelUris)

            {

                Console.WriteLine(uri);

            }

    // Wait for method calls.

            Console.WriteLine("Listening...");

            Console.ReadLine();

        }

    }

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

    using System;

    using System.Runtime.Remoting;

    public class Remotable : MarshalByRefObject

    {

    private int callCount = 0;

    public int GetCount()

        {

            callCount++;

    return(callCount);

        }

    }

    원본 위치 <http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=18&MAEULNO=8&no=1585&page=2>

'C# DB 코딩 강좌' 카테고리의 다른 글

C#을 이용한 DB코딩 11  (0) 2008.11.14
C#을 이용한 DB코딩 10  (0) 2008.11.14
C#을 이용한 DB코딩 9(인터페이스)  (0) 2008.11.14
C#을 이용한 DB코딩 8  (0) 2008.11.14
C#을 이용한 DB코딩 7  (0) 2008.11.14
C#을 이용한 DB코딩 5  (0) 2008.11.14
C#을 이용한 DB코딩 4(Virtual PC)  (0) 2008.11.14
C#을 이용한 DB코딩 3  (0) 2008.11.14
C#을 이용한 DB코딩 2  (0) 2008.11.14
C#을 이용한 DB코딩 1  (0) 2008.11.14
posted by 삶의여유로움
:
C# DB 코딩 강좌 2008. 11. 14. 21:00

    3티어에 대한 이야기를 적어 볼까 했는데

    http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=18&MAEULNO=8&no=1582&page=1

    바로 아래에 글이 적혔다. 여러모로 감사함을 전한다.

    ^^;;

    촌장의 눈치가 계속 보이는 덕에 이번 강좌에는 C#코드를 조금 넣어보도록 하자.

    계속 낙서만 적다가는 내가 적은글들이 모두 자게로 갈듯 하다.

    프레임웍에는 빠지기 어려운것중 하나가 DB 컨넥션일것이다.

    DB연결하는 클래스를 간단하게 만들어 보자.

    처음 DB에 연결을 하기 위한 요구사항은

    1. 오라클이 되고

    2. ms-sql이 되며

    3. sql 로 코딩이 가능하고

    4. Sp로도 코딩이 가능하고 싶다.

    하여간.. 자유로운 영혼이길 바랄것이다.

    그러한 코딩을 해보도록 하자.

    단지 여기서 코딩하는 기법은 정상적이라기 보다는..

    비정상적인것에 가까울수도 있고 되도록 소스를.. 안정적(?)이기

    보다는 짧게 가는방향을 선택할것이다.

    여하튼 시작해 보자.

    일단 클래스 디자인은.

    clip_image001[2]

    이런모습이 일단 나올것이다. 아래의 setDB는 생성자이니.

    기본적으로 callSP와 callSQL형태의 두개의 매서드가 존재한다.

    기능이야 알고 있듯이 sql넣어서 실행하고 하나는 SP를 호출해서

    실행할것이다.

    3.5의 링쿠는.. 지금 다루어야 되는 부분이 아니라고 생각하니까. 일단은 2.0

    을 기준으로 계속 가도록 하자.

    여러가지 형태가 있겠지만. 우리는 간단하게 뭔가의 쿼리를 때리고 결과치를 받기만 하면된다. 물론 조금 더 있다가는 입력하는것도 하겠지만.. 지금은 심풀하게 쿼리내용을 데이타셋으로 받는것에 집중하자.

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

    기본적으로 말이다.

    닷넷은.. 값을 하나만들고 오는 함수와 reader같은것도 있고

    dataset을 채우는것들이 있다.

    여기서 우리는 뜬금없이.. 자전거와 오토바이 그리고 자동차에 대해서 이야기를 해보자.

    A지역에서 B지역으로 물건을 옮기는데 거리가 100미터라고 생각을 해보자.

    가끔 우리는 자전거로 가기가 편한곳이 있고 주차문제로 오토바이를 타기가 유용할때도 있으며

    그래도 옮겨야 되는 물건이 많다면 당연히 자동차를 타야한다.

    하지만 결론적으로 모든것이 가능한것은 자동차일것이다.

    하지만 어떻는가 덩치가 크고 다시 세워두어야 하니 여러모로 귀차니즘이 발생한다.

    하지만 반대로 작은데이타던지 큰 데이타던지 무관하게 자동차를 모두 이용하게 한다면 사용자 측면에서는 단일한 인터페이스(?)를 유지시킬수 있을것이다.

    물론 어떤업무인가에 따라 많은 모습이 변화되겠지만. 결론적으로 우리가 지금 구상하고 있는 테스트 프로그램에서는

    단일한 인터페이스인 자동차(?)를 유지해 보도록 하자.

    이말은... 무조건 쿼리를 날리고 dataset 을 얻어오는것을 기본으로 하겠다는 이야기다.

    계속 모습이 변하겠지만.. 기본적인 형태를 코딩을 하면

    clip_image002[1]

    이런 모습을.. 예상할수도 있을것이다.

    아니 이런것들로 시작을 하면 머리가 아플듯 하니 일단은 사용에 대해서 좀 더 초점을 두고 구현은 나중에 살펴 보도록 하자.

    실제적으로 위의 내용을 잘~~~ 설명을 하자면 우리는 기본적으로

    "생성자패턴" 이라고 하는것들에 대해서 한번쯤 이야기를 해야 되기 때문이다.

    물론 내가 여기서 가벼운 싱글톤 패턴정도야 이야기 해줄 수 있긴해도 왜 팩토리 패턴이 어쩌고를 떠들게 되고

    3티어라던지에 대한 잡설을 펼치게 되었다가는 아마도 너무 코드없는 이야기가 될수도 있기 때문이라고 위안을 삼자.

    (당연히 난 모르면서 아는척 하는데 거의 상승의 경지에 이르렀다.)

    사용을 어떻게 할것인가가

    실제적인 구현에 영향을 미칠것이니.. 우리의 사용법을 편리하게 하는것에 집중을 하자.

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

    우리가 클래스를 만들고 객체지향(?)이라는 허접한 단어를 남발하면서 코딩을 하는 이유는 머리쓰기가 싫어서 이다.

    클래스를 만드는 이유는 그 자체가 머리를 어떻게 하면 더 안쓰고(?) 코딩을 할까를 머리쓰다가 만든게 그 이유다.

    모순인가?.. 머리를 쓰지 않기 위해서 클래스를 머리쓰면서 만드는거 말이다.

    세상이 뭐 다 그런거 아니겠는가?

    요구사항

    자.. DB를 접속을 하고는 싶다.

    근데 귀찮다. 그냥 대충 결론적으로 DataSet만 가지고 오고싶다.

    입력할것은 select * from 주저리 주저리만 입력하면 알아서 가져오면 좋겠다.

    아.. 가끔 sp도 써야 하니.. 이것도.. 인자값만 넣으면.. 알아서 dataset을 가져오면 좋겠다.

    아.. 오라클도 되고 ms-sql도 되면 좋겠다.

    이정도만 되면.. 좋은거 아닌가?

    clip_image001[3]

    자.. 위의 요구사항을.. 정리를 하면.. 생성자에 DB가 오라클인지 ms-sql인지를 넣고

    Sp호출을 하던지 sql를 넘기면.. Dataset 을 돌려주는 클래스를 설계를 하면

    아마도 이렇게 될듯 싶다.

    뭘 이딴걸 만들고 있냐고 또 한소리 하는 사람이 있을듯 하여 계속 말하지만.

    사용법은

    setDB DB = new setDB("Oracle");

    dataGridView1.DataSource = DB.callSQL("select * from tab").Tables[0] ;

    이렇게 두줄 적으면..그냥 이유없이.. 데이터       

    clip_image003[1]

    이렇게 될것이라는 거다.

    당연히 sql를 두줄로 이렇게 적으면..

    setDB DB = new setDB("Oracle");

    dataGridView1.DataSource = DB.callSQL("select * from tab").Tables[0] ;

    dataGridView2.DataSource = DB.callSQL("select * from emp").Tables[0];

    clip_image004[1]

    이렇게 된다는것이다.

    즉.. 귀찮게 뭔가를 하지 않아도 결과만 가져오기 위해서 우리는..

    클래스를 만든다.

    그럼.. MS-sql은 어떻게 할까?

    setDB DB = new setDB("MS");

    dataGridView1.DataSource = DB.callSQL("select * from comboboxt").Tables[0] ;

    clip_image005[1]

    위와 동일하게 적어주면.. 된다.

    모든게 동일하니.. 우리는 쉽게 setDB에 단지 인자값만 조정해 주면 되는것이다.

    그럼.. SP는 어떻게 할까?를 또 고민해야 하는데.

    이건 인자값을 일단 받아야 한다. 그것을 모두 string으로 통일하는 입장을 가지도록 하자. 왜냐면 나는 당신에게 솔류션을 제공하는게 아니기 때문이다.

    그리고 대부분의 경우(80~90%)는 string으로 모든걸 처리하는게 편하다.

    예를들어서..

    CREATE PROCEDURE yun_test

    @one char(12),

    @two char(12)

    AS

    BEGIN

    select * from comboboxt where viewseq <> @one

    END

    이런 sp를 작성했다고 하자. 물론 @two는 사용하지 않지만 인자값을 여러 개 넘기는것을 테스트 하는 모습을 보여주기 위해서 이다.

    이것은 이렇게 호출하도록 하자.

    setDB DB = new setDB("MS");

    Dictionary<string, string> para = new Dictionary<string, string>();

    dataGridView1.DataSource = DB.callSQL("select * from comboboxt").Tables[0] ;

    para["@one"] = "1";

    para["@two"] = "2";

    dataGridView2.DataSource = DB.callSP("yun_test", para).Tables[0];

    clip_image006[1]

    다소 길어졌다.

    하여간 이정도면.. 나름대로 ms와 오라클을 쓰고 그리고 sql로도 가능하며

    SP도 가능한 편한 클래스라고 생각한다.

    아마도 누군가.. 왜 datatable를 사용하지 않고 dataset을 사용했는가를 딴지를 걸수도 있을것 같다.

    이런것은 이미 다 말하지 않아도 알것 같긴하지만 그래도 굳이 설명을 한다면

    (설명하기 전부터 막 귀찮아 지고 있다.)

    예를 들어서 SP를..

    ALTER PROCEDURE [dbo].[yun_test]

    @one char(12),

    @two char(12)

    AS

    BEGIN

    select * from comboboxt where viewseq <> @one;

    select * from comboboxt ;

    END

    이런식으로 바꾸었다고 하자.. 두개의 쿼리문장이 있다면 저것을 한번에 받을때 어떻게 받을것인가?

    그렇다. 그래서 데이터 셋으로 받는다.

    이런경우는 생각외로 드물게 일어나므로(10%정도) 클래스는 그냥 일반적인 형태로 디자인 하고 있다.

    아.. 오라클도 해야되나. ㅠ.ㅠ

    오라클을 보자.

    오라클은..짜증만땅이다.

    나름대로 뭔가를 잘 지켜줘야 하기도 하고 나름대로 괜찮기도 하면서 또 나름대로 피곤하다.

    DB로는 참 괜찮다.

    연결적인느낌으로는 피곤하다.

    를 이야기 할수 있다.

    일단… 오라클의 경우 SP호출시 커서로 받아야 되어야 인자값이 늘어나야 한다.

    para["one"] = "1";

    para["two"] = "2";

    para["o_rc"] = "";

    para["o_rc2"] = "";

    이런식으로 증가하게 될것이다. 받아야 되는 커서를 넣어야 한다.

    여기서 "O_"로 시작하면 커서타입으로 되도록 클래스내에 약속을 지정했다.

    그리고 SP에도 이것들을 다 설정해야 하는데

    CREATE OR REPLACE package types

    as

    Type cursorType is ref cursor;

    end;

    형태로 선언을 처리하고..

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

    CREATE OR REPLACE procedure yun_test

    (

    one in varchar,

    two in varchar,

    o_rc out types.cursortype,

    o_rc2 out types.cursortype

    )

    is

    begin

    open o_rc for

    select * from emp where sal like '%' || one || '%';

    open o_rc2 for

    select * from emp ;

    end;

    이런 형태로 커서를 열어주고 처리를 해야한다.

    그래서 ms쪽 책을 보면 커서를 사용하지 말라는 이야기를 적어둔게 있던데

    DB의 차이 때문에 그런말이 나온듯 하다.

    사용법은 동일하다.

    setDB DB = new setDB("oracle");

    Dictionary<string, string> para = new Dictionary<string, string>();

    para["one"] = "1";

    para["two"] = "2";

    para["o_rc"] = "";

    para["o_rc2"] = "";

    dataGridView1.DataSource = DB.callSP("yun_test", para).Tables[0];

    dataGridView2.DataSource = DB.callSP("yun_test", para).Tables[1];

    물론 저렇게 적어서 두번이나.. 디비를 굴리는 코딩은 하지 않을것이라 믿는다.

    이건 예제이므로 용서해다오.. 두어줄 더 적는것도 귀찮다.

    하여간.. Sp에서 많은 커서를 넘긴다면.. Dataset을 public으로 하나 두는것도 좋을듯 싶다.

    지금은 그렇게 하지 않는다.

    clip_image007[1]

    물론 세부적인 세세한 것을 더 작성한다면 더욱좋겠지만.. -_-;; (이건 솔류션이 아니라고 …~~~~!!! 단지 낙서야 낙서)

    테이블이름을 매칭을 시킨다던지 하는것들 말이다. 그런건 알아서 하기 바란다.

    개인적인 이야기지만 대략 지금의 기능을 구현하는데 클래스 하나에 100여줄 코딩으로 끝나지만..

    세세한 기능을 다 주고 에러처리에 몇몇가지를 추가하면 여러가지 클래스를 만들어야 하며 몇몇가지 Adapter적인것과 Interface적인 녀석까지 추가해서 만든다면 전체 코딩이 1000여줄이 넘어설것이다.

    그러니 그냥 가자.

    간단히 가기위한 몇몇가지 방책들..

    1.

    심풀하게 이녀석은 singleton도 구현하지 말고 그냥.. 무식하게 static connection 하나로 버팅기는 식으로 코딩을 하자.

    2.

    낙서에는 기본적으로 try ~ catch같은걸 적는걸 배제하는 이유는 소스가 길어지기 때문이다.

    3.

    인자값은 무조건 스트링 리턴값은 무조건 데이타셋이다.

    에러가 뜬다면.. 질답란에 질문을 하면

    답변을 달아줄 사람이 부지기수니 잘 물어보기만 하면 될것이다.

    저짝에 벌써 손들고 SP에 인자값 없어도 되는 오버로딩도 하나 추가해달라는 사람이 보인다. 그런건.. 제~ 발 알아서 하기 바란다.

    원본 위치 <http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=18&MAEULNO=8&no=1583&page=2>

'C# DB 코딩 강좌' 카테고리의 다른 글

C#을 이용한 DB코딩 10  (0) 2008.11.14
C#을 이용한 DB코딩 9(인터페이스)  (0) 2008.11.14
C#을 이용한 DB코딩 8  (0) 2008.11.14
C#을 이용한 DB코딩 7  (0) 2008.11.14
C#을 이용한 DB코딩 6(TcpChannel)  (1) 2008.11.14
C#을 이용한 DB코딩 4(Virtual PC)  (0) 2008.11.14
C#을 이용한 DB코딩 3  (0) 2008.11.14
C#을 이용한 DB코딩 2  (0) 2008.11.14
C#을 이용한 DB코딩 1  (0) 2008.11.14
DB 이야기를 시작하면서  (0) 2008.11.14
posted by 삶의여유로움
: