이번에는 C#에서 MSSQL과 연동하는 방법에 대하여 알아보겠습니다.
MSSQL은 Visual Studio와 같이 MS에서 만들어서 그런것인지는 모르겠으나
프로젝트 생성 시 System.Data가 참조 추가 되어있다면 별도의 dll 파일은 참조하지 않아도 됩니다.
그리고 해당 글에서 설명드리는 부분은 Winform과 WPF에 상관없이 똑같이 적용이 가능합니다.
MSSQL과 연동하는 기능을 사용하기 위하여 다음 코드를 using문에 추가해줍니다.
using System.Data.SqlClient;
MSSQL과 연동을 위해서는 먼저 접속을 해야 하므로 접속 방법에 대하여 알아보겠습니다.
다음은 MSSQL 접속에 대한 코드입니다.
string connectionString = string.Format("Data Source={0},{1};Initial Catalog={2};uid={3};pwd={4};Integrated Security={5};Connection Timeout=1",
"127.0.0.1", "1433", "TestDB", "sa", "1", false);
SqlConnection sourceConn = new SqlConnection(connectionString);
sourceConn.Open();
SqlConnection 클래스를 이용하여 먼저 Connection을 생성해줍니다.
코드에서는 DB에 접속하기 위한 정보를 connectionString 변수에 먼저 지정한 후 conn 생성 시 할당하고 있습니다.
아래는 connectionString의 내용에 대한 의미입니다.
- Data Source : 접속하는 서버의 정보입니다. (보통 IP,Port 형태의 값이 들어갑니다.)
- Initial Catalog : 접속하는 DB의 이름입니다.
- uid : 로그인 시 사용자 ID 입니다. MSSQL은 sa가 기본으로 존재하기 때문에 예시로 sa를 사용했습니다.
- pwd : 로그인 시 사용자 비밀번호입니다.
- Integrated Security : true로 설정하면 Windows 인증 모드로 진행, false로 하면 SQL Server 인증 모드로 진행합니다. 기본 값은 false입니다. 아래의 SSMS에서의 화면이 Integrated Security 옵션에 해당하는 부분입니다.
- Connection Timeout : 연결을 시도하는동안 몇 초를 대기할지 설정합니다. 1이면 1초로 설정됩니다. 그러나 1로 설정했는데 실제로는 더 오래 걸리는 느낌이 들어 찾아보니 1~4의 값으로 설정하면 28초 이상의 값으로 설정되어 버린다는 경우가 있다고 합니다. 그래서 해당 내용을 적용해보면 가장 짧은 시간 값은 실질적으로 5초가 됩니다.
SqlConnection을 생성하였다면 Open 메서드로 연결을 시작합니다.
반환 값이 없기 때문에 상태를 Open이 잘 되었는지 확인이 필요할 경우에는 아래와 같이 해주어야 합니다.
if (sourceConn.State != ConnectionState.Open)
{
MessageBox.Show("연결 실패");
}
ConnectionState가 Open 되었다면 연결에 성공한 것입니다.
연결한 이후에는 데이터를 가져오거나 넣는 작업을 진행하게 될 것이므로 해당 방법에 대하여 알아보겠습니다.
먼저 데이터를 가져오는 방법에 대하여 확인해 보겠습니다.
다음은 데이터를 가져오는 코드입니다. 위의 2번 항목 코드가 있어야 동작합니다.
string query = "select name from sys.tables";
SqlCommand sourceCommand = new SqlCommand(query, sourceConn);
SqlDataReader sourceReader = sourceCommand.ExecuteReader();
while (sourceReader.Read())
{
cb_SourceTable.Items.Add(sourceReader.GetString(0));
}
sourceReader.Close();
현재 접속한 DB에 있는 모든 테이블을 가져오는 쿼리문을 사용하여
SqlCommand 클래스의 변수를 생성하면서 query 변수와 DB 연결 시 사용한 conn 변수를 적용한 후
SqlDataReader 클래스의 변수를 생성하면서 sourceCommand 변수를 통해 ExecuteReader 메서드를 사용하여
conn으로 접속한 DB에 query문을 적용시켜 얻어낸 결과를 저장합니다.
그 다음 저장한 결과를 Read() 를 통하여 1개씩 읽어나가면서 ComboBox에 Item을 반복적으로 추가시킵니다.
꺼낼때는 sourceReader.Get***()을 사용하는데 DB에 저장되어 있는 값에 따라서 GetInt32을 사용할 수도 있고, GetBoolean을 사용할 수도 있습니다. 종류가 다양하므로 상황에 따라서 사용하시면 되며,
예를 들어 "Test"라고 저장되어있는 값을 불러왔다면, GetInt32()로 꺼낼 경우 예외를 발생시키므로 주의하시기 바랍니다.
GetString(0)의 0이라는 의미는 몇 번째 Column인지를 나타낸 것입니다.
Index처럼 0부터 시작하고, 위의 쿼리문으로 실행해보면 1개의 Column 밖에 나오지 않으므로 저렇게 한 것입니다.
그리고 만약 sourceReader에 값이 없다면 while문을 타지 않으므로 사용 시 참고해주세요.
마지막으로 sourceReader를 닫아줌으로써 데이터 가져오는 기능이 종료됩니다.
Reader를 닫아주지 않을 경우 문제가 생길 수 있으니 추가로 읽는 것이 아니라면 반드시 닫아주는 것이 좋습니다.
다음은 데이터를 1개씩 DB에 저장하는 방법입니다.
아래 코드에서 데이터를 1개씩 DB에 저장하는 기능에 대해서 구현하고 있습니다.
위의 2번 항목 코드가 있어야 동작합니다.
// 변수 생성
int insertedRowsCount = 0;
List<string[]> list = new List<string[]>();
// 넣을 데이터 추가
list.Add(new string[] { "TestID1", "TestPass1", "TestName1" });
list.Add(new string[] { "TestID2", "TestPass2", "TestName2" });
list.Add(new string[] { "TestID3", "TestPass3", "TestName3" });
// DB에 데이터 삽입
for (int i = 0; i < list.Count; i++)
{
string query = string.Format("INSERT INTO UserInfo VALUES ('{0}', '{1}', '{2}')", list[i][0], list[i][1], list[i][2]);
SqlCommand command = new SqlCommand(query, sourceConn);
insertedRowsCount += command.ExecuteNonQuery();
}
// 삽입 성공한 Row 개수를 메시지 박스로 띄우기
MessageBox.Show(insertedRowsCount.ToString());
- 처음에 변수를 생성해서 넣을 데이터를 담고, 결과 값을 누적할 준비를 합니다.
- 그 다음 넣을 데이터를 List에 추가합니다.
- DB에 데이터를 반복문을 이용하여 삽입합니다.
SqlCommand 클래스의 변수를 만들면서 쿼리문과 앞에서 DB 접속 시 사용했던 sourceConn 변수를 활용합니다.
sourceConn변수를 사용하는 이유는 해당 쿼리문이 어떤 DB에 접근해서 동작해야 하는지를 알려주기 위함입니다.
그리고 ExecuteNonQuery 메서드를 이용해서 쿼리문을 DB에 적용합니다.
반환 값은 꼭 활용할 필요는 없지만 설명해드리는 차원에서 변수에 누적시키도록 하였습니다.
1 Row씩 삽입하기 때문에 Count 값이 1씩 누적됩니다.
단, ExecuteNonQuery 메서드는 성공적으로 적용된 Row 개수를 반환하기 때문에,
삽입이 정상적으로 이루어지지 않으면 Count가 누적되지 않습니다.
- 마지막으로 누적된 Count를 메시지 박스로 띄워줍니다.
아래는 코드의 결과입니다.
데이터를 1 Row 씩 꺼내고 넣는 방법에 대해서는 알아보았으니,
전체를 한 번에 꺼내고, 한 번에 넣는 방법에 대하여 알아보겠습니다.
다음 코드는 DataTable을 생성한 후 SourceTable의 데이터를 통째로 가져와서 DataTable에 넣은 다음
TargetTable에 통째로 데이터를 넣는 방법입니다.
using (DataTable innerSourceTable = new DataTable())
{
// Source Table 데이터 가져오기
string query = "SELECT * FROM SourceTable";
SqlCommand sourceCommand = new SqlCommand(query, sourceConn);
SqlDataAdapter sourceAdapter = new SqlDataAdapter(sourceCommand);
sourceAdapter.Fill(innerSourceTable);
// Target Table에 Source Table 데이터 넣기
using (SqlBulkCopy bulk = new SqlBulkCopy(targetConn))
{
bulk.DestinationTableName = "TargetTable";
bulk.WriteToServer(innerSourceTable);
}
}
DataTable은 C#에서 사용하는 클래스이고, DB의 Table처럼 사용할 수 있는 기능을 제공합니다.
using문 안에 넣어서 해당 구간이 끝나면 메모리 관리를 위하여 자동적으로 데이터를 비워주도록 해놓았습니다.
그리고 SourceTable에서 모든 데이터를 가져오는 의미의 쿼리문을 생성 후
SqlCommand변수를 생성하면서 쿼리문과 sourceConn 변수를 넣고,
SqlDataAdapter라는 클래스의 변수를 만들면서 앞에서 만든 sourceCommand 변수를 사용합니다.
앞에서 사용했던 SqlDataReader 클래스가 데이터를 가져온 이후에도 따로 연결을 닫지 않는다면
지금 사용하는 SqlDataAdapter 클래스는 데이터를 가져온 후 연결을 자동으로 닫아줍니다.
연결을 닫는다는 의미가 DB와의 접속을 끊는 것이 아니고 쿼리문을 실행하면서 연결된 부분을 닫는다는 의미입니다.
그 다음 Fill 메서드에 SourceTable에서 가져온 데이터를 담을 DataTable 변수를 인자로 넣고 실행하면
innerSourceTable 변수에 DB의 SourceTable에서 가져온 모든 데이터가 저장됩니다.
그 다음 SqlBulkCopy라는 클래스를 using 형태로 변수를 생성하여 자동으로 객체가 해제되도록 합니다.
생성시의 인자는 데이터를 삽입할 DB의 Connection 변수를 넣어줍니다.
bulk 변수의 DestinationTableName 속성에 데이터를 삽입할 테이블 이름을 지정한 후
WriteToServer 메서드에 삽입할 데이터가 들어있는 DataTable 변수를 인자로 담아 적용하면
innerSourceTable에 있는 모든 데이터가 TargetTable에 삽입됩니다.
위 소스의 동작을 한 줄로 요약하면 SourceTable의 모든 데이터를 TargetTable로 복사한 것입니다.
따라서 여러 가지로 활용될 수 있는 여지가 충분할 것으로 보입니다.
이상으로 C#에서 MSSQL을 연동하는 방법에 대하여 알아보았습니다.
C# MSSQL 데이터 변경 시 바로 확인하는 방법 (0) | 2023.05.22 |
---|---|
C# PropertyGrid에서 enum 적용 시 숫자 형태의 값 사용하기 (0) | 2023.04.10 |
C# MELSECNET-G로 Mitsubishi PLC와 연동하기 (0) | 2022.10.12 |
C# .Net Core에 대하여 알아보기 (2) | 2022.09.30 |
C# 읽은 문자열 줄 수 구하는 방법 (0) | 2022.09.14 |
댓글 영역