반응형

안녕하세요~ 코딩 연습생입니다

 

코로나 사태 여러분 괜찮으신가요??

 

언제쯤 잠잠해질지 참...얼른 백신이나 대책이 나왔으면 좋겠는데 마스크 때문에 숨도 잘 안쉬어지네요~

 

그래도 할건 해야겠죠?ㅎㅎ

 

그래서 저는 매일 출근합니다;;;ㅋ

 

오늘 포스팅 주제는 MSSQL 쿼리인데요

 

MSSQL을 접해보신 분들한데는 참 쉬운 정보일수 있지만 혹시 모르시는 분들을 위해서 포스팅 합니다

 

프로그램을 작성하다가 DB와 Data를 주고 받을때 이미 있는 데이터를 처리하기 위해서 SELECT를 한번 더 해야 하고

 

중복인지 아닌지를 체크해서 중복이면 UPDATE를 신규이면 INSERT 뭐 이런식으로 프로그램을 많이 했습니다

 

그런데 이 MERGE라는 함수를 알게 되고 부턴 한번의 쿼리로 INSERT / UPDATE가 조건에 의해 한번에 처리가 되니

 

참 편하더라구요

 

그래서 이 MERGE함수 사용하는 방법을 포스팅 하겠습니다

 

일단 쿼리 작성을 위해서 MSSQL을 접속합니다

 

접속을 하신뒤 새쿼리를 눌러 쿼리를 작성합니다

 

저의 경우 USER_MAST라는 테이블을 생성하였습니다

 

*USER_MAST 테이블

  - 컬럼정보 : USER_ID, USER_NAME, USER_PSWD

 

이렇게 3개의 컬럼이 존재합니다

 

그럼 조회를 한번 해보겠습니다

 

 

보시는거와 같이 USER_MAST라는 테이블에는 TEST라는 정보가 이미 존재하고 있습니다

 

그럼 MERGE 쿼리를 작성해 볼께요

 

*Query

MERGE USER_MAST
      USING (SELECT 'x' AS DUAL) AS B
         ON [USER_ID] = 'TEST'
       WHEN MATCHED THEN
            UPDATE SET [USER_NAME] = 'TEST111111'
       WHEN NOT MATCHED THEN
            INSERT([USER_ID], [USER_NAME], USER_PSWD) VALUES('TEST', 'TEST', '');

 

쿼리의 내용을 말로 설명하자면 이렇게 됩니다

 

USER_MAST라는 테이블에 [USER_ID]가 'TEST'인 테이터가 존재하면

 

UPDATE문으로 [USER_NAME] 컬럼에 'TEST111111'을 UPDATE하고

 

존재하지 않으면 INSERT문으로 [USER_ID]가 'TEST'이고 [USER_NAME]가 'TEST'인 DATA를 생성해라

 

이렇게 됩니다 어렵지 않죠? 

 

그럼 MERGE 쿼리를 실행해 보겠습니다

 

※ 아래 이미지는 USER_PSWD가 빠져있는데 쿼리 자체게 문제는 없습니다 참고하세요

 

 

실행했으면 USER_MAST 테이블을 다시 조해해보겠습니다

 

위에서 보았듯이 이미 USER_MAST 테이블에는 TEST라는 데이터가 존재했습니다

 

그래서 USER_NAME 컬럼에 TEST111111을 UPDATE한 결과를 확인 할 수 있습니다

 

 

그럼 다음 조건을 테스트하기 위해서 USER_MAST 테이블의 값을 지워 볼께요

 

 

DELETE문을 실행했습니다

 

 

이제 USER_MAST 테이블에는 'TEST'라는 데이터는 존재하지 않습니다

 

다시 MERGE문을 실행해 보겠습니다

 

 

그럼 저희는 예측할수가 있죠

 

USER_MAST 테이블에 USER_ID컬럼이 'TEST'이고 USER_NAME컬럼이 'TEST'인 데이터가 생성되어야 합니다

 

조회 해보겠습니다

 

예상했던 결과값이 보여지네요

 

이렇게 INSERT와 UPDATE를 하나의 쿼리에서 동작할 수 있는 방법을 알아봤습니다

반응형
반응형

안녕하세요

 

코딩연습생입니다~

 

오늘 포스팅은 저번 시간 포스팅에 이어서 진행 하고자 합니다

 

저번 시간 포스팅에서 자마린 Cross-Platform을 사용해서 로그인 화면을 만들어 봤습니다

 

정보는 아래 링크를 참고해 주세요

 

https://codingman.tistory.com/96

 

[Xamarin Forms] 자마린으로 간단한 로그인 앱 만들기

안녕하세요. 코딩연습생입니다 비쥬얼스튜디오 Xamarin을 이용한 로그인 창 만들기 입니다 저도 처음 접해보는 부분이라 많이 헷갈리고 연습을 하고 있습니다~ 음..일단 시작에 앞서 비쥬얼스튜디오의 Cross-Platf..

codingman.tistory.com

 

저번 시간에 만들었던 로그인 앱에서 로그인 인증 시도 할때 

 

MSSQL과 연동시켜 인증처리 되도록 구현을 해볼려고 합니다

 

앱에서 MSSQL과 연동 할때 여러가지 방법이 있다고 합니다

 

하지만 저는 C# 개발자였기에;; 기존과 비슷한 벙법으로 MSSQL에 접속을 구현해 봤습니다

 

자마린에서 MSSQL에 접속을 하기 위해서는 몇가지 사전 준비가 필요한데요

 

Nuget을 사용해서 필요한 패키지를 설치 하면 됩니다 어렵지는 않아요

 

1. Nuget을 사용하기

    - C# 프로젝트 위치에서 Nuget 패키지 관리를 클릭 합니다

 

2. System.Data.SqlClient 설치 하기

   - Nuget  패키지 관리창에서 System.Data.SqlClient를 검색하여 설치 합니다

 

3. using문 선언

   - SQL 클래스 사용을 위한 using문을 선업합니다

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

 

4. 로그인 인증을 위한 단계 구성

   - 기존 로그인 앱에서 Login 버튼이 활성화 되는 위치에서 DB 정보를 불러오도록 할겁니다

 

*LiginPage.xaml.cs

 ① 해당 위치에서 로그인 버튼 클릭이 일어는 위치를 다음과 같이 수정 합니다 Connet();만 추가했습니다

 ② Connet() 구문을 추가 했습니다

async void OnLoginButtonClicked (object sender, EventArgs e)
		{
			var user = new User {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text
			};

            Connet();

            var isValid = AreCredentialsCorrect (user);
			if (isValid) {
				App.IsUserLoggedIn = true;
				Navigation.InsertPageBefore (new MainPage (), this);
				await Navigation.PopAsync ();
			} else {
				messageLabel.Text = "Login failed";
				passwordEntry.Text = string.Empty;
			}
		}
public void Connet()
        {
            DataRowCollection Rs = null;

            SqlConnectionStringBuilder sqlConnectionStringBuilder = new SqlConnectionStringBuilder();
            sqlConnectionStringBuilder.DataSource = "서버IP주소";
            sqlConnectionStringBuilder.InitialCatalog = "DB명";
            sqlConnectionStringBuilder.UserID = "계정ID";
            sqlConnectionStringBuilder.Password = "계정 비밀 번호";
            sqlConnectionStringBuilder.IntegratedSecurity = false;
            SqlConnection conn = new SqlConnection(sqlConnectionStringBuilder.ConnectionString);
            conn.Open();

            try
            {
                SqlDataAdapter adapter = new SqlDataAdapter();
                string Query = "SELECT [USER_ID], USER_PSWD";
                Query += "        FROM USER_MAST";
                Query += "       WHERE 1=1";
                Query += "         AND [USER_ID] = '" + usernameEntry.Text + "'";
                adapter.SelectCommand = new SqlCommand(Query, conn);
                DataSet ds = new DataSet();
                adapter.Fill(ds);
                DataTable table = ds.Tables[0];
                Rs = table.Rows;

                if (Rs != null && Rs.Count > 0)
                {
                    Constants.Username = Rs[0]["USER_ID"].ToString();
                    Constants.Password = Rs[0]["USER_PSWD"].ToString();
                }
            }
            catch (Exception Ex)
            {
                conn.Close();
            }
            finally
            {
                if (Rs != null) { Rs.Clear(); Rs = null; }
                conn.Close();
            }
        }

 

*LoginPageCS.cs

 위와 동일하게 적용해 줍니다

async void OnLoginButtonClicked (object sender, EventArgs e)
		{
			var user = new User {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text
			};

            Connet();

            var isValid = AreCredentialsCorrect (user);
			if (isValid) {
				App.IsUserLoggedIn = true;
				Navigation.InsertPageBefore (new MainPageCS (), this);
				await Navigation.PopAsync ();
			} else {
				messageLabel.Text = "Login failed";
				passwordEntry.Text = string.Empty;
			}
		}
public void Connet()
        {
            DataRowCollection Rs = null;

            SqlConnectionStringBuilder sqlConnectionStringBuilder = new SqlConnectionStringBuilder();
            sqlConnectionStringBuilder.DataSource = "서버IP주소";
            sqlConnectionStringBuilder.InitialCatalog = "DB명";
            sqlConnectionStringBuilder.UserID = "계정ID";
            sqlConnectionStringBuilder.Password = "계정 비밀 번호";
            sqlConnectionStringBuilder.IntegratedSecurity = false;
            SqlConnection conn = new SqlConnection(sqlConnectionStringBuilder.ConnectionString);
            conn.Open();

            try
            {
                SqlDataAdapter adapter = new SqlDataAdapter();
                string Query = "SELECT [USER_ID], USER_PSWD";
                Query += "        FROM USER_MAST";
                Query += "       WHERE 1=1";
                Query += "         AND [USER_ID] = '" + usernameEntry.Text + "'";
                adapter.SelectCommand = new SqlCommand(Query, conn);
                DataSet ds = new DataSet();
                adapter.Fill(ds);
                DataTable table = ds.Tables[0];
                Rs = table.Rows;

                if (Rs != null && Rs.Count > 0)
                {
                    Constants.Username = Rs[0]["USER_ID"].ToString();
                    Constants.Password = Rs[0]["USER_PSWD"].ToString();
                }
            }
            catch (Exception Ex)
            {
                conn.Close();
            }
            finally
            {
                if (Rs != null) { Rs.Clear(); Rs = null; }
                conn.Close();
            }
        }

 

이렇게 하시면 MSSQL에 접속하여 인증을 받아 로그인 성공/실패가 됩니다

 

다음시간에는 SignUpPageCS.cs부분인 회원가입 부분을 수정해서 MSSQL와 연동한

 

계정 등록 방법에 대해 포스팅 해보도록 할께요~

반응형
반응형

안녕하세요

 

C# 컨텐츠로 블로그를 운영중인 코딩 연습생입니다

 

이번 포스팅에서는 C#으로 MSSQL를 접속하고 쿼리문을 전송시켜 연동시키기까지 한번 해보도록 하겠습니다

 

일반적인 방법으로는 

1) 접속정보 생성

2) SqlConnection 생성

3) SqlDataAdapter 생성

4) SqlCommand 실행

5) DataSet 실행

6) DataTable 데이터 받기

 

이런 순서로 직접 날코딩하여 사용을 했었습니다

 

그런데 프로젝트에서 DB 통신을 자주해야 하는경우 매우 귀찮아지게 됩니다

 

그래서 쉽게 MSSQL과 통신하고 내가 원하는 방식으로 FeedBack 받을수 있는 클래스 생성도 같이 설명해보

 

도록 하겠습니다

 

첫번째로 일반 방식입니다

string source = string.Empty;
string SYS_TIME = string.Empty;

//콜렉션 생성
DataRowCollection Rs2 = null;
//접속정보 생성
source = @"User Id=계정ID;Password=패스워드;Server=tjqjIP;Initial Catalog=DB명";

//컨넥션 생성
SqlConnection Con = new SqlConnection(source);
Con.Open();
SqlDataAdapter adapter = new SqlDataAdapter();
string query = "쿼리";
adapter.SelectCommand = new SqlCommand(query, Con);
DataSet ds = new DataSet();
adapter.Fill(ds);
DataTable table = ds.Tables[0];
Rs2 = table.Rows;

if (Rs2 != null && Rs2.Count > 0)
{
	for (int i = 0; i < Rs2.Count; i++)
	{
		//쿼리에서 FeedBack 받은 값 사용
        SYS_TIME = Rs2[0]["시간"].ToString();
	}
}
Con.Close();

 

단순한 SELECT문 하나 사용하더라도 참 많은 구문을 작성해야 합니다

 

두번째 방법으로는 클래스로 DB 명령를 미리 생성해놓고 호출하여 사용하는 방식으로 구현해 볼께요

1) DB에서 사용될 명령를 미리 생성합니다

   - Database.cs라는 구성 요소 클래스 파일 생성

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

namespace db_conn
{
    public partial class Database : Component
    {
        public Database()
        {
            InitializeComponent();
        }

        public Database(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }

        private db_conn.BaseDB.DBTypeEnum m_DbType = BaseDB.DBTypeEnum.JDE;

        public db_conn.BaseDB.DBTypeEnum DbType
        {
            get { return m_DbType; }
            set { m_DbType = value; }
        }

        /// <summary>
        /// SELECT처럼 결과가 있는 쿼리를 실행한다
        /// </summary>
        /// <param name="query">쿼리</param>
        /// <returns>데이터테이블</returns>
        public DataTable ExcuteQuery(string query)
        {
            return ExcuteQuery(m_DbType.ToString(), query);
        }
        /// <summary>
        /// SELECT처럼 결과가 있는 쿼리를 실행한다
        /// </summary>
        /// <param name="dbName">DB명</param>
        /// <param name="query">쿼리</param>
        /// <returns>데이터테이블</returns>
        public DataTable ExcuteQuery(string dbName, string query)
        {
            db_conn.BaseDB db = BaseDB.GetDB(dbName.ToUpper());
            return db.ExcuteQuery(query);
        }
        /// <summary>
        /// insert, update처럼 조작하는 쿼리를 실행한다.
        /// </summary>
        /// <param name="query">쿼리</param>
        /// <returns>결과</returns>
        public int ExcuteNonQuery(string query)
        {
            return ExcuteNonQuery(m_DbType.ToString(), query);
        }
        // <summary>
        /// insert, update처럼 조작하는 쿼리를 실행한다.
        /// </summary>
        /// <param name="dbName">DB명</param>
        /// <param name="query">쿼리</param>
        /// <returns>결과</returns>
        public int ExcuteNonQuery(string dbName, string query)
        {
            db_conn.BaseDB db = BaseDB.GetDB(dbName.ToUpper());
            return db.ExcuteNonQuery(query);
        }
        /// <summary>
        /// 대량의 데이터를 인서트한다.
        /// </summary>
        /// <param name="toTbName">인서트할 테이블</param>
        /// <param name="dt">데이터테이블</param>
        /// <returns>오류메세지</returns>
        public string BulkInsert(string toTbName, System.Data.DataTable dt)
        {
            return BulkInsert(m_DbType.ToString(), toTbName, dt);
        }
        /// <summary>
        /// 대량의 데이터를 인서트한다.
        /// </summary>
        /// <param name="dbName">DB명</param>
        /// <param name="toTbName">인서트할 테이블</param>
        /// <param name="dt">데이터테이블</param>
        /// <returns>오류메세지</returns>
        public string BulkInsert(string dbName, string toTbName, System.Data.DataTable dt)
        {
            db_conn.BaseDB db = BaseDB.GetDB(dbName.ToUpper());
            return db.BulkInsert(toTbName, dt);
        }

        /// <summary>
        /// 1:1매칭되는 테이블을 넘겨 Dictionary로 받는다.
        /// </summary>
        /// <param name="dbName">DB명</param>
        /// <param name="query">쿼리(KEY_COL,VAL_COL이 반드시 있어야한다)</param>
        /// <returns>결과</returns>
        public Dictionary<string, string> GetDic1To1(string dbName, string query)
        {
            Dictionary<string, string> ret = new Dictionary<string, string>();
            DataTable dt = ExcuteQuery(dbName, query);
            string key = "";
            string val = "";
            for (int row = 0; row < dt.Rows.Count; row++)
            {
                key = dt.Rows[row]["KEY_COL"].ToString();
                val = dt.Rows[row]["VAL_COL"].ToString();
                if (!ret.ContainsKey(key))
                {
                    ret.Add(key, val);
                }
            }
            return ret;
        }
        /// <summary>
        /// 테이블을 넘겨 Dictionary(row)
        /// </summary>
        /// <param name="dbName">DB명</param>
        /// <param name="query">쿼리(KEY_COL은 반드시 있어야한다)</param>
        /// <returns>결과</returns>
        public Dictionary<string, DataRow> GetDicRow(string dbName, string query)
        {
            Dictionary<string, DataRow> ret = new Dictionary<string, DataRow>();
            DataTable dt = ExcuteQuery(dbName, query);
            string key = "";
            for (int row = 0; row < dt.Rows.Count; row++)
            {
                key = dt.Rows[row]["KEY_COL"].ToString();
                if (!ret.ContainsKey(key))
                {
                    ret.Add(key, dt.Rows[row]);
                }
            }
            return ret;

        }

        /// <summary>
        /// 데이터테이블을 딕셔너리에 넣는다.
        /// </summary>
        /// <param name="keyCols">키값을 가지는 컬럼들(:로 연결한다)</param>
        /// <param name="dt">넘길 테이블</param>
        /// <returns>결과</returns>
        public Dictionary<string, DataRow> GetDicRow(string keyCols, DataTable dt)
        {
            Dictionary<string, DataRow> ret = new Dictionary<string, DataRow>();

            string key = "";
            string[] spKeys = keyCols.Split(':');
            for (int row = 0; row < dt.Rows.Count; row++)
            {
                key = "";
                for (int i = 0; i < spKeys.Length; i++)
                {
                    key += dt.Rows[row][spKeys[i]].ToString();
                }
                if (!string.IsNullOrEmpty(key) && !ret.ContainsKey(key))
                {
                    ret.Add(key, dt.Rows[row]);
                }
            }
            return ret;
        }

        /// <summary>
        /// 데이터테이블을 딕셔너리에 넣는다.
        /// </summary>
        /// <param name="keyCols">키값을 가지는 컬럼들(:로 연결한다)</param>
        /// <param name="sumCols">SUM할 컬럼들(:로 연결한다)</param>
        /// <param name="dt">넘길 테이블</param>
        /// <returns>결과</returns>
        public Dictionary<string, DataRow> GetDicRow(string keyCols, string sumCols, DataTable dt)
        {
            Dictionary<string, DataRow> ret = new Dictionary<string, DataRow>();

            string key = "";
            string[] spKeys = keyCols.Split(':');
            string[] spSums = sumCols.Split(':');
            for (int row = 0; row < dt.Rows.Count; row++)
            {
                key = "";
                for (int i = 0; i < spKeys.Length; i++)
                {
                    key += dt.Rows[row][spKeys[i]].ToString();
                }

                if (!ret.ContainsKey(key))
                {   //INSERT
                    ret.Add(key, dt.Rows[row]);
                }
                else
                {   //UPDATE
                    for (int i = 0; i < spSums.Length; i++)
                    {
                        ret[key][spSums[i]] = Convert.ToDouble(ret[key][spSums[i]]) + Convert.ToDouble(dt.Rows[row][spSums[i]]);
                    }
                }
            }
            return ret;
        }

        /// <summary>
        /// 딕셔너리를 DataTable로 변환
        /// </summary>
        /// <param name="dic">딕셔너리</param>
        /// <returns>테이블</returns>
        public DataTable ConvertDicToDT(Dictionary<string, DataRow> dic)
        {
            DataTable dt = new DataTable();
            int cnt = 0;
            foreach (KeyValuePair<string, DataRow> pair in dic)
            {
                if (cnt == 0)
                {
                    dt = pair.Value.Table.Clone();
                }

                DataRow dr = dt.NewRow();
                for (int col = 0; col < pair.Value.ItemArray.Length; col++)
                {
                    dr[col] = pair.Value[col];
                }
                dt.Rows.Add(dr);

                cnt++;
            }

            return dt;
        }

    }
}

 

2) 접속 DB에 대한 속성 클래스 생성

   - BaseDB 클래스 파일 생성

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Reflection;
using System.Data.Common;

namespace db_conn
{
    
    public abstract class BaseDB 
    {
        #region 열거형
        /// <summary>
        /// 매출타입(OES/OEM)
        /// </summary>
        public enum DBTypeEnum
        {
            TEST            
        }
        #endregion

        private DBTypeEnum m_DBType = DBTypeEnum.TEST;

        public BaseDB(DBTypeEnum dbType)
        {
            m_DBType = dbType;
            
        }

        /// <summary>
        /// 쿼리를 실행한다(결과 있을때)
        /// </summary>
        /// <param name="query">쿼리</param>
        /// <returns>실행결과</returns>
        public abstract DataTable ExcuteQuery(string query);

        /// <summary>
        /// 쿼리를 실행한다(결과 없을때)
        /// </summary>
        /// <param name="query">쿼리</param>
        /// <returns>적용행수</returns>
        public abstract int ExcuteNonQuery(string query);


        /// <summary>
        /// 대량의 데이터를 Insert한다
        /// </summary>
        /// <param name="toTbName">저장할테이블</param>
        /// <param name="dt">데이터</param>
        /// <returns>에러메세지</returns>
        public abstract string BulkInsert(string toTbName, DataTable dt);

        /// <summary>
        /// DB연결자생성
        /// </summary>
        /// <returns>DB연결자</returns>
        protected abstract DbConnection DBConnection();

        

        /// <summary>
        /// SQL파일을 실행한다.
        /// </summary>
        /// <param name="path">SQL파일</param>
        /// <param name="args">인자(:)으로 구분</param>
        /// <returns>결과</returns>
        public DataTable ExcuteFileQuery(string path, string args)
        {
            string query = System.IO.File.ReadAllText(path);
            query = query.Replace("\r\n", " "); //강제개행
            query = query.Replace("\t", " "); //탭키
            query = query.Replace(";", " "); //탭키
            string[] spArgs = args.Split(':');
            for (int i = 0; i < spArgs.Length; i++)
            {
                query = query.Replace("{" + i.ToString() + "}", spArgs[i]);
            }
            return this.ExcuteQuery(query);
        }

        
        /// <summary>
        /// 줄리안데이트
        /// </summary>
        /// <param name="yyyymmdd">년월일</param>
        /// <returns>줄리안</returns>
        public int GetJulianDate(string yyyymmdd)
        {
            int yyyy = Convert.ToInt32(yyyymmdd.Substring(0, 4));
            int mm = Convert.ToInt32(yyyymmdd.Substring(4, 2));
            int dd = Convert.ToInt32(yyyymmdd.Substring(6, 2));
            DateTime lDate = new DateTime(yyyy, mm, dd);
            DateTime rDate = new DateTime(yyyy, 1, 1);

            string date1;
            string date2;
            date1 = "1" + yyyymmdd.Substring(2, 2);
            TimeSpan span = lDate.Subtract(rDate);

            date2 = Convert.ToString(Convert.ToUInt32(span.Days) + 1).PadLeft(3, '0');

            return Convert.ToInt32(date1 + date2);
        }

        public static BaseDB GetDB(string dbType)
        {
            BaseDB db = null;
            switch (dbType)
            {
                case "TEST":
                    db = new TEST();
                    break;
            }
            return db;
        }
    }
}

 

3) DB타입에 따른 세부 명령어 지정

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;

namespace db_conn
{
    public class MssqlDB:BaseDB
    {
        public MssqlDB(string ip, string uid, string pwd, string db)
            : base(DBTypeEnum.MSSQL)
        {
            m_DB_IP = ip;
            m_DB_ID = uid;
            m_DB_PWD = pwd;
            m_DB_Name = db;
        }

        #region 멤버필드

        private string m_DB_IP = "";
        private string m_DB_ID = "";
        private string m_DB_PWD = "";
        private string m_DB_Name = "";

        #endregion

        #region 상수        
        private const string CN_DB_TIME = "600";    //300초까지 타임아웃한다.
        #endregion

        #region 공개메소드

        /// <summary>
        /// 대량의 DataTable을 인서트한다
        /// </summary>        
        /// <param name="toTbName">삽입할 테이블명</param>
        /// <param name="dt">데이터테이블</param>
        public override string BulkInsert(string toTbName, DataTable dt)
        {
            string ret = "";
            try
            {
                SqlBulkCopy bulk = new SqlBulkCopy(DBConnection().ConnectionString);
                bulk.DestinationTableName = toTbName;
                bulk.WriteToServer(dt);
                bulk.Close();
            }
            catch (Exception exLog)
            {
                ret = exLog.Message;
                throw new Exception(exLog.Message);

            }
            return ret;
        }

        /// <summary>
        /// 결과가 있는 쿼리를 실행
        /// </summary>
        /// <param name="query">쿼리</param>
        /// <returns>결과</returns>
        public override DataTable ExcuteQuery(string query)
        {
            DataTable dt = new DataTable();
            try
            {
                SqlDataAdapter adpt = new SqlDataAdapter(query, (SqlConnection)DBConnection());
                adpt.SelectCommand.CommandTimeout = Convert.ToInt32(CN_DB_TIME);
                adpt.Fill(dt);
            }
            catch (Exception eLog)
            {
                throw eLog;
            }
            return dt;
        }

        /// <summary>
        /// 결과가 없는 쿼리를 실행
        /// </summary>
        /// <param name="query">쿼리</param>
        /// <returns>영향받은 Row수</returns>
        public override int ExcuteNonQuery(string query)
        {
            int ret = 0;
            try
            {
                SqlConnection connect = (SqlConnection)DBConnection();
                connect.Open();
                SqlTransaction tran = connect.BeginTransaction();

                try
                {

                    SqlCommand com = new SqlCommand(query, connect, tran);
                    ret = com.ExecuteNonQuery();

                    tran.Commit();
                    connect.Close();
                }
                catch (Exception ineLog)
                {
                    tran.Rollback();
                    throw ineLog;
                }
            }
            catch (Exception eLog)
            {
                throw eLog;
            }
            return ret;
        }

        protected override DbConnection DBConnection()
        {
            string connectStr = "Server=" + m_DB_IP;
            connectStr = connectStr + ";" + "User ID = " + m_DB_ID;
            connectStr = connectStr + ";" + "Password = " + m_DB_PWD;
            connectStr = connectStr + ";" + "Initial Catalog = " + m_DB_Name;
            connectStr = connectStr + ";" + "Connection Timeout= " + CN_DB_TIME;
            SqlConnection ret = new SqlConnection(connectStr);
            return ret;
        }


        public int InsertUpdateImage(string _SQL, System.Drawing.Image _Image, string _ImageFieldName, System.Drawing.Imaging.ImageFormat _ImageFormat)
        {
            int _SqlRetVal = 0;

            try
            {
                SqlConnection con = (SqlConnection)this.DBConnection();
                con.Open();

                System.Data.SqlClient.SqlCommand _SqlCommand
                    = new System.Data.SqlClient.SqlCommand(_SQL, con);


                System.IO.MemoryStream _MemoryStream = new System.IO.MemoryStream();
                _Image.Save(_MemoryStream, _ImageFormat);


                System.Data.SqlClient.SqlParameter _SqlParameter
                    = new System.Data.SqlClient.SqlParameter("@" + _ImageFieldName, SqlDbType.Image);

                _SqlParameter.Value = _MemoryStream.ToArray();
                _SqlCommand.Parameters.Add(_SqlParameter);


                _SqlRetVal = _SqlCommand.ExecuteNonQuery();


                _SqlCommand.Dispose();
                _SqlCommand = null;
            }
            catch (Exception eLog)
            {
                throw eLog;
            }

            return _SqlRetVal;
        }

        #endregion

       
    }
}

 

이렇게 준비가 다 되시면 본문에서 DB 연결과 명령어 사용이 훨씬 간편해 집니다

 

[사용방법]

1. 사용하는 프로젝트에 빌드를 통해 생성된 구성요소클래스 파일을 참조에 넣어준다

 

2. 본문에서 db_conn을 사용하기 위한 선언문

 

3. 다음과 같은 형태로 DB 연동 사용

string SYS_TIME = string.Empty;

string Sql = " SELECT 시간";
       Sql += "  FROM A ";
TEST db = new TEST();
DataTable dt = db.ExcuteQuery(Sql);

if (dt.Rows.Count > 0)
{
	for (int i = 0; i <= dt.Rows.Count - 1; i++)
	{
		SYS_TIME = dt.Rows[i]["시간"].ToString());
	}
}

 

이렇게 하면 첫번째 방식과 동일한 결과 값을 얻을수 있습니다

 

가장 큰 차이점은 첫번째 방식은 쿼리를 종류 SELECT, INSERT, UPDATE, DELETE의 구문에 따라 방식이 조금 바뀝니다

 

그렇기 때문에 사용할때마다 코딩이 구문에 맞게 맞춰야하지요

 

하지만 두번째 방식의 경우 db의 변환 타입만 맞춰 사용하면 구문에 따른 코딩이 단순화가 된다는 점이 있습니다

 

두개 모두 구현하셔서 테스트 해보시기 바랍니다

 

감사합니다~

반응형
반응형

안녕하세요

 

코딩하는남자 코딩연습생입니다

 

MSSQL에서 ROW_NUMBER 함수를 이용해서 중복 데이터를 제외한 MAX의 데이만 추출 하는 방법을 설명

 

해볼려고 합니다

 

먼저 무정리된 ROW 데이터를 조회 해 볼꼐요

중요 정보는 흑백 처리 했습니다

 

이 조회된 데이터를 보시면 HOPPER_CART에 중복으로 많은 데이터가 있습니다

 

여기에 ROW_NUMBER 함수를 써서 HOPPER_CART의 데이터중에 HOPPRE_TIME의 값이 가장 높은것을이

 

나오도록 쿼리문 짜보겠습니다

 

SELECT HOPPER_CODE, HOPPER_SEQ,
       HOPPER_CART, HOPPER_LOTNO,
       HOPPER_JAJIL, PCARD_NO, HOPPER_TIME
  FROM (
         SELECT HOPPER_CODE, HOPPER_SEQ,
       			HOPPER_CART, HOPPER_LOTNO,
       			HOPPER_JAJIL, PCARD_NO, HOPPER_TIME
           		ROW_NUMBER() OVER(PARTITION BY HOPPER_CODE ORDER BY HOPPER_SEQ DESC) AS ROWIDX
           FROM MIX_HOPPER_RFID_RESULT_TEMP WITH(NOLOCK)
       ) A
WHERE ROWIDX = 1

자, 이렇게 쿼리문을 작성한뒤 조회를 하면

 

 

다음과 같은 결과 값이 나오네요

 

HOPPER_CART별 HOPPER_TIME가 가장 높은 값으로 조회가 됩니다

 

물론 GROUPBY를 서브쿼리로 짜서도 같은 결과값을 만들수 있지만 서브에 서브 쿼리를 많이 다는것보다

 

row_number() 함수를 활용해서 좀 간결한(?) 쿼리로 GROUP BY와 같은 효과를 나타낼수 있습니다

 

반응형
반응형

안녕하세요

 

코딩하는 남자의 코딩연습생입니다

 

이번 중국 프로젝트를 진행하면서 알게된 내용입니다만 혹시 모르시는 분들이 계실까봐

 

한번 올려 봅니다ㅎㅎ

 

일반적으로 varcahr은 가변 문자열이라고 하고 nvarchar은 가변 유니코드 문자열이라고 하네요

 

그래서 프로그램 개발시에 다국어를 염두하고 있다면 MSSQL 연동시에 필드를 nvarchar를 사용해야 한다고 합니다

 

보통 영문이나 숫자는 1바이트이고 한글이나 중국 간체 등은 2바트로 구성되어지는데

 

varchar과 nvarchar의 차이가 바로 이 문자 저장 바이트 크기 차이 라고 합니다

 

소소하지만 저는 모르고 있었던 내용입니다ㅎ

 

아마 저와 같이 별거 아니지만 모르고 계셨던 분들은 이 블로그를 읽으시고 적용하시면

 

도움이 되지 않을까 싶습니다~

 

[테스트 Query 결과]

 

 

 

varchar(3)에 테스트라는 문자열을 넣었는데 길이가 1바이트 밖에 되지 않아 한자리만 출력되고 있습니다

 

그에 반면 nvarchar(3)은 3자리가 모두 출력되는 결과가 나오네요

 

무조껀 SQL 작성할때 저는 nvarchar을 사용하려고 합니다

 

반응형
반응형

안녕하세요

 

코딩하는 남자의 코딩연습생입니다

 

MSSQL에서 Split 제공 함수가 없습니다

 

그래서 사용자 Function으로 만들어 두시면 프로시져 내부에서 사용하시가 편합니다

 

CREATE FUNCTION arr_split(
    @sText VARCHAR(500), -- 대상 문자열
    @str CHAR(1) = '|', -- 구분기호(Default '|')
    @idx INT -- 배열 인덱스

 )

 

RETURNS VARCHAR(20)
AS
BEGIN
     DECLARE @word CHAR(20), -- 반환할 문자
     @sTextData VARCHAR(600), 
     @num SMALLINT;

      SET @num = 1;
      SET @str = LTRIM(RTRIM(@str));
      SET @sTextData = LTRIM(RTRIM(@sText)) + @str; 

      WHILE @idx >= @num
      BEGIN

             IF CHARINDEX(@str, @sTextData) > 0
             BEGIN
                   -- 문자열의 인덱스 위치의 요소를 반환
                   SET @word = SUBSTRING(@sTextData, 1, CHARINDEX(@str, @sTextData) - 1);
                   SET @word = LTRIM(RTRIM(@word));

                   -- 반환된 문자는 버린후 좌우공백 제거 
                   SET @sTextData = LTRIM(RTRIM(RIGHT(@sTextData, LEN(@sTextData) - (LEN(@word) + 1))))
             END

             ELSE

             BEGIN
                   SET @word = NULL;
             END
             SET @num = @num + 1
      END
   RETURN(@word);
END
반응형
반응형
--서버등록

exec sp_addlinkedserver

@server='', --링크서버이름

@srvproduct='', --OLEDB 데이터 원본 제품이름

@provider='SQLOLEDB', --공급자고유식별자

@datasrc='', --가져올 DB서버 주소

@provstr='', --OLEDB공급자연결문자열

@catalog='' --가져올 db서버 데이터베이스명

go

 

 

--서버등록확인

select * from master.dbo.sysservers

 

 

--연결계정등록

exec sp_addlinkedsrvlogin

@rmtsrvname='' --서버이름

@useself='false' --로그인이름사용유무

@locallogin=NULL, --로컬서버로그인여부

@rmtuser='SA', --사용자이름

@rmtpassword='12345' --사용자암호

 

--원하는 테이블 확인

select * from ssuyastory.KBbank.dbo.employee

 

--연결계정삭제

exec sp_droplinkedsrvlogin

@rmtsrvname = 'ssuyastory',

@locallogin = NULL

 

--연결서버삭제

exec sp_dropserver

@server='ssuyastory'

반응형
반응형

1) alter table A alter column name char(10) not null

    -- char(10) 은 기존 컬럼의 크기 그대로 설정

 

 

 

 

2) alter table A alter column price money not null

    =====================

    보라색 부분들은 필수 구문이고요

    초록색 부분은 해당 테이블, 컬럼 명 넣는 부분

    파랑색부분은 타입 및 , null 설정 부분입니다.

 

>>> ALTER 명령어 정리 <<<<<

alter table 테이블명 add 컬럼명 타입 null설정

>> 해당 컬럼을 해당 타입과 해당 null 설정으로 추가

 

 

alter table 테이블명 drop column 컬럼명

>> 해당 컬럼 삭제

 

 

 

alter table 테이블명 alter column 컬럼명 타입 null설정

>> 해당 컬럼을 해당 타입과 NULL 설정으로 변화

 

반응형

+ Recent posts