반응형

김종열


Query는 집합적으로 처리하지만 순차적으로 처리하고 있는 구조입니다. 예를 들어 세개의 테이블에 데이터를 넣는다고 가정하면 (물론 순서는 필요없고아마도 쿼리는 대략 이러할 것입니다.

INSERT INTO t1 (c1, c2) VALUES (v1, v2)

INSERT INTO t2 (c1, c2) VALUES (v1, v2)

INSERT INTO t3 (c1, c2) VALUES (v1, v2)

그런데 위와 같은 쿼리를 동시에 처리하는 구조를 가지면 어떨까요?

이런 취지로 Procedure를 하나 개발해봤습니다. Procedures는 구분자(세미콜론을 사용했다.)를 기준으로 명령을 배열화 시키고 thread로 처리하는 형식입니다보통 쿼리문은 실행했을 때 리턴이 없는 형식이 있는가 하면 리턴 형식이 존재하는 것이 있는데, 이 구조는 리턴을 무시하는 구조입니다.
또한
병렬 구문중 하나가 에러가 나는 구조라면 그 구문만 에러가 나며 다른 건 실행이 됩니다.


다음은 C# 소스입니다.

using System;

using System.Data;

using System.Data.SqlClient;

using System.Data.SqlTypes;

using Microsoft.SqlServer.Server;

using System.Threading;

 

 

public partial class StoredProcedures

{

    public class thWorker

    {

        private string wName;

        public SqlPipe p = SqlContext.Pipe;

        public thWorker(string name)

        {

 

            wName = name;

            p.Send("Start : " + wName);

 

            SqlConnection c = new SqlConnection("context connection=true");

            c.Open();

            SqlCommand db_cmd;

 

            try

            {

                db_cmd = new SqlCommand(wName, c);

                db_cmd.ExecuteNonQuery();

            }

            catch (Exception e)

            {

                p.Send(e.ToString());

            }

            finally

            {

                c.Close();

                p.Send("Finish : " + wName);

            }

 

 

        }

 

        public void mDmy()

        {

            SqlPipe p = SqlContext.Pipe;

            p.Send(wName);

        }

    }

   

    [Microsoft.SqlServer.Server.SqlProcedure]

    public static int USP_Thread_Proc(string cmd)

    {

        Thread t = null;

        thWorker wth = null;

        string[] strCmd = cmd.Split(';');

        int cmdCount = strCmd.Length;

        Object[] obj = new object[cmdCount];

       

 

        for (int i = 0; i < cmdCount; i++)

        {

 

            wth = new thWorker(strCmd[i]);

 

            t = new Thread(new ThreadStart(wth.mDmy));

            t.Name = "Thread -" + i.ToString() + ":";

            t.Start();

            obj[i] = t;

        }

        for (int i = 0; i < cmdCount; i++)

        {

            t = (System.Threading.Thread)obj[i];

            t.Join();         

        }

        return 0;

    }

 

 

};

위의 코드를 한번 테스트는 아래의 쿼리로 가능합니다.

IF OBJECT_ID('t1') IS NOT NULL

        DROP TABLE t1

 

CREATE TABLE t1 (a INT, b DATETIME)

GO

 

IF OBJECT_ID('t2') IS NOT NULL

        DROP TABLE t2

IF OBJECT_ID('t3') IS NOT NULL

        DROP TABLE T3

       

SELECT * INTO t2 FROM t1

SELECT * INTO t3 FROM t1

GO

 

 

SELECT * FROM t1

SELECT * FROM t2

SELECT * FROM t3

 

 

--이게 우리가 주목해야 부분

EXEC usp_thread_proc 'truncate table t1;truncate table t2;truncate table t3'

EXEC usp_thread_proc 'insert into t1 values(1, getdate());insert into t2 values(1, getdate());insert into t3 values(1, getdate())'

 

 

--시간의차이를확인해주자..

SELECT * FROM t1

SELECT * FROM t2
SELECT * FROM t3

수고하십시오..


반응형

'연구개발 > CLR' 카테고리의 다른 글

CLR - Windows Event Log  (0) 2011.08.27
CLR - 누적합 구하기  (0) 2011.08.27
CLR-이전행가기 udf_lag  (0) 2011.08.27
WMI 객체를 쿼리로 읽어오기  (0) 2010.08.10
파일리스트 불러오기  (0) 2009.06.22

+ Recent posts