2. 예광탄(C#에서 MSSQL 사용) [안드로이드 앱+ASP.NET+WCF+MSSQL]

1. 소개

안녕하세요. 언제나휴일입니다.

이번에는 WCF 서비스에서 구현할 내용을 예광탄 형태로 만들어 볼거예요. (무료 동영상 강의)

C# 콘솔 앱(.NET Framework) 프로젝트에서 가입, 로그인, 로그아웃, 탈퇴 기능을 구현합니다.

여기서 만든 예광탄의 코드는 다음에 WCF 서비스에 기능으로 구현할 거예요.

2. 가입 요청 구현

먼저 연결 문자열을 정적 멤버로 선언합시다.

연결 문자열은 서버 이름, DB 이름, User ID, Password가 필요합니다.

Data Source에는 서버 이름, Initial Catalog에는 DB 이름으로 설정합니다.

제가 실험하는 컴퓨터 이름은 DESKTOP-T87J0UT 이며 MSSQL 서버 이름도 같습니다.

using System;
using System.Data;
using System.Data.SqlClient;

namespace 예광탄
{
    internal class Program
    {
        static string constr = "Data Source=DESKTOP-T87J0UT; Initial Catalog=eh; User ID=scott; Password=tiger;";
        static void Main(string[] args)
        {

        }

    }
}

가입 요청을 실험하는 함수를 정의하여 Main 함수에서 호출합시다.

        static void Main(string[] args)
        {
            RegTest();
        }
        private static void RegTest()
        {
        }

가입 요청에는 ID, PW, 이름을 전달해야 합니다.

여기에서는 다음처럼 네 번 가입 요청을 실험하기로 할게요.

        private static void RegTest()
        {
            Console.WriteLine(RegReq("eh", "hello", "언휴"));
            Console.WriteLine(RegReq("pub", "hello", "야휴"));
            Console.WriteLine(RegReq("eh", "hello", "강휴"));
            Console.WriteLine(RegReq("jejutour", "hello", "후휴"));
        }
        private static bool RegReq(string id, string pw, string name)
        {
            return false;
        }

가입 요청은 SQL 쿼리문으로 수행할게요.

이를 위해 쿼리문과 연결 개체를 입력 인자로 SqlCommand 개체를 생성합니다.

SqlCommand 개체의 ExecuteNonQuery를 호출했을 때 반환 값은 insert 쿼리를 수행한 결과와 같습니다.

만약 정상적으로 추가했으면 영향 받은 행의 개수가 1개이므로 1을 반환합니다.

가입 요청 결과는 ExecuteNonQuery 반환 값이 1인지 여부를 반환하게 할 거예요.

같은 ID가 있을 때는 주요 키 정책에 의해 중복 키가 있다는 예외가 발생합니다.

이를 처리하기 위해 ExecuteNonQuery 반환 값을 받을 변수를 0으로 초기 설정한 상태에서 구현하세요.

        private static bool RegReq(string id, string pw, string name)
        {
            int re = 0;
            try
            {
                SqlConnection scon = new SqlConnection(constr);
                string text = string.Format("insert into EHMember(ID,PW,MNAME,Status) values('{0}','{1}','{2}',0);", id, pw, name);
                SqlCommand cmd = new SqlCommand(text, scon);
                scon.Open();
                re = cmd.ExecuteNonQuery();
                scon.Close();
            }
            catch { }
            return re == 1;
        }

정상적으로 작성했고 EHMember 테이블에 데이터가 빈 상태라면 True, True, False, True 값을 출력할 것입니다.

3. 로그인 요청 구현

로그인 요청을 테스트 하는 함수를 정의하고 Main에서 호출합니다.

앞에서 테스트 한 RegTest는 주석 처리하세요.

        static void Main(string[] args)
        {
            //RegTest();
            LoginTest();
        }

Login 테스트도 앞에서 작성한 계정과 없는 계정 등을 이용하여 다양한 테스트를 수행할 수 있게 작성해 보세요.

        private static void LoginTest()
        {
            Console.WriteLine(LoginReq("eh", "hello")); //성공 예상
            Console.WriteLine(LoginReq("pub", "hello")); //성공 예상
            Console.WriteLine(LoginReq("eh", "hello2")); //실패 예상 - 비밀 번호 틀림
            Console.WriteLine(LoginReq("eh", "hello"));  //실패 예상 - 이미 로그인
            Console.WriteLine(LoginReq("eb", "hello"));  //실패 예상 - ID 없음
        }

로그인 요청은 ID와 PW를 입력 인자로 받습니다.

LoginReq 저장 프로시저를 사용할 것이므로 함수 시작부분에서 저장 프로시저에 전달할 파라미터 개체를 생성합니다.

        private static string LoginReq(string id, string pw)
        {
            SqlParameter sp_id = new SqlParameter("@ID", id);
            SqlParameter sp_pw = new SqlParameter("@PW", pw);
            SqlParameter sp_name = new SqlParameter("@MName", SqlDbType.NVarChar,50);
            sp_name.Direction = ParameterDirection.Output;
            sp_name.Value = "";
            SqlParameter sp_result = new SqlParameter("@Result", 0);
            sp_result.Direction = ParameterDirection.Output;

저장 프로시저는 SqlCommand의 CommandType을 StoredProcedure로 설정해 주어야 합니다.

물론 생성한 SqlParameter 개체들을 SqlCommand의 Parameters 컬렉션에 추가한 후에 쿼리를 수행해야겠죠.

다음은 LoginReq 함수 소스 코드입니다.

        private static string LoginReq(string id, string pw)
        {
            SqlParameter sp_id = new SqlParameter("@ID", id);
            SqlParameter sp_pw = new SqlParameter("@PW", pw);
            SqlParameter sp_name = new SqlParameter("@MName", SqlDbType.NVarChar,50);
            sp_name.Direction = ParameterDirection.Output;
            sp_name.Value = "";
            SqlParameter sp_result = new SqlParameter("@Result", 0);
            sp_result.Direction = ParameterDirection.Output;
            try
            {
                SqlConnection scon = new SqlConnection(constr);
                string text = "LoginReq";
                SqlCommand cmd = new SqlCommand(text, scon);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(sp_id);
                cmd.Parameters.Add(sp_pw);
                cmd.Parameters.Add(sp_name);
                cmd.Parameters.Add(sp_result);
                scon.Open();
                cmd.ExecuteNonQuery();
                scon.Close();
            }
            catch { }
            return sp_name.Value.ToString();
        }

4. 로그 아웃 구현

로그아웃 요청을 테스트 하는 함수를 정의하고 Main에서 호출합니다.

앞에서 테스트 한 LoginTest는 주석 처리하세요.

        static void Main(string[] args)
        {
            //RegTest();
            //LoginTest();
            LogoutTest();
        }

Logout테스트는 앞에서 로그인 성공한 정보로 수행해 봅시다.

로그아웃은 요청 결과를 반환하지 않게 할게요.

수행 한 후에 테이블의 정보를 확인하거나 다시 로그인 테스트를 통해 정상적으로 작동하는지 확인하세요.

        private static void LogoutTest()
        {
            LogoutReq("eh", "hello");
            LogoutReq("pub", "hello");
        }

로그아웃 요청도 저장 프로시저를 이용할 것입니다.

구현 방법은 로그인 요청과 크게 다른 점이 없습니다.


        private static void LogoutReq(string id, string pw)
        {
            SqlParameter sp_id = new SqlParameter("@ID", id);
            SqlParameter sp_pw = new SqlParameter("@PW", pw);            
            try
            {
                SqlConnection scon = new SqlConnection(constr);
                string text = "LogoutReq";
                SqlCommand cmd = new SqlCommand(text, scon);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(sp_id);
                cmd.Parameters.Add(sp_pw);                
                scon.Open();
                cmd.ExecuteNonQuery();
                scon.Close();
            }
            catch { }            
        }

5. 탈퇴 구현

탈퇴 요청을 테스트 하는 함수를 정의하고 Main에서 호출합니다.

앞에서 테스트 한 LogoutTest는 주석 처리하세요.

        static void Main(string[] args)
        {
            //RegTest();
            //LoginTest();
            //LogoutTest();
            UnregTest();
        }

탈퇴 테스트는 앞에서 가입한 정보로 수행해 봅시다.

탈퇴 기능도 요청 결과를 반환하지 않을게요.

        private static void UnregTest()
        {            
            UnregReq("eh", "hello");
            UnregReq("pub", "hello");
        }

탈퇴 요청도 저장 프로시저를 이용하며 앞에 구현과 큰 차이가 없습니다.

        private static void UnregReq(string id, string pw)
        {
            SqlParameter sp_id = new SqlParameter("@ID", id);
            SqlParameter sp_pw = new SqlParameter("@PW", pw);
            try
            {
                SqlConnection scon = new SqlConnection(constr);
                string text = "UnregReq";
                SqlCommand cmd = new SqlCommand(text, scon);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(sp_id);
                cmd.Parameters.Add(sp_pw);
                scon.Open();
                cmd.ExecuteNonQuery();
                scon.Close();
            }
            catch { }
        }

6. 전체 소스 코드

using System;
using System.Data;
using System.Data.SqlClient;

namespace 예광탄
{
    internal class Program
    {
        static string constr = "Data Source=DESKTOP-T87J0UT; Initial Catalog=eh; User ID=scott; Password=tiger;";
        static void Main(string[] args)
        {
            RegTest();
            //LoginTest();
            //LogoutTest();
            //UnregTest();
        }

        private static void UnregTest()
        {            
            UnregReq("eh", "hello");
            UnregReq("pub", "hello");

        }

        private static void UnregReq(string id, string pw)
        {
            SqlParameter sp_id = new SqlParameter("@ID", id);
            SqlParameter sp_pw = new SqlParameter("@PW", pw);
            try
            {
                SqlConnection scon = new SqlConnection(constr);
                string text = "UnregReq";
                SqlCommand cmd = new SqlCommand(text, scon);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(sp_id);
                cmd.Parameters.Add(sp_pw);
                scon.Open();
                cmd.ExecuteNonQuery();
                scon.Close();
            }
            catch { }
        }

        private static void LogoutTest()
        {
            LogoutReq("eh", "hello");
            LogoutReq("pub", "hello");
        }

        private static void LogoutReq(string id, string pw)
        {
            SqlParameter sp_id = new SqlParameter("@ID", id);
            SqlParameter sp_pw = new SqlParameter("@PW", pw);            
            try
            {
                SqlConnection scon = new SqlConnection(constr);
                string text = "LogoutReq";
                SqlCommand cmd = new SqlCommand(text, scon);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(sp_id);
                cmd.Parameters.Add(sp_pw);                
                scon.Open();
                cmd.ExecuteNonQuery();
                scon.Close();
            }
            catch { }            
        }

        private static void LoginTest()
        {
            Console.WriteLine(LoginReq("eh", "hello")); //성공 예상
            Console.WriteLine(LoginReq("pub", "hello")); //성공 예상
            Console.WriteLine(LoginReq("eh", "hello2")); //실패 예상 - 비밀 번호 틀림
            Console.WriteLine(LoginReq("eh", "hello"));  //실패 예상 - 이미 로그인
            Console.WriteLine(LoginReq("eb", "hello"));  //실패 예상 - ID 없음
        }

        private static string LoginReq(string id, string pw)
        {
            SqlParameter sp_id = new SqlParameter("@ID", id);
            SqlParameter sp_pw = new SqlParameter("@PW", pw);
            SqlParameter sp_name = new SqlParameter("@MName", SqlDbType.NVarChar,50);
            sp_name.Direction = ParameterDirection.Output;
            sp_name.Value = "";
            SqlParameter sp_result = new SqlParameter("@Result", 0);
            sp_result.Direction = ParameterDirection.Output;
            try
            {
                SqlConnection scon = new SqlConnection(constr);
                string text = "LoginReq";
                SqlCommand cmd = new SqlCommand(text, scon);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(sp_id);
                cmd.Parameters.Add(sp_pw);
                cmd.Parameters.Add(sp_name);
                cmd.Parameters.Add(sp_result);
                scon.Open();
                cmd.ExecuteNonQuery();
                scon.Close();
            }
            catch { }
            return sp_name.Value.ToString();
        }

        private static void RegTest()
        {
            Console.WriteLine(RegReq("eh", "hello", "언휴"));
            Console.WriteLine(RegReq("pub", "hello", "야휴"));
            Console.WriteLine(RegReq("eh", "hello", "강휴"));
            Console.WriteLine(RegReq("jejutour", "hello", "후휴"));
        }

        private static bool RegReq(string id, string pw, string name)
        {
            int re = 0;
            try
            {
                SqlConnection scon = new SqlConnection(constr);
                string text = string.Format("insert into EHMember(ID,PW,MNAME,Status) values('{0}','{1}','{2}',0);", id, pw, name);
                SqlCommand cmd = new SqlCommand(text, scon);
                scon.Open();
                re = cmd.ExecuteNonQuery();
                scon.Close();
            }
            catch { }
            return re == 1;
        }
    }
}