본문 바로가기
Study/C#

C# Windows Forms 강의 85편: 데이터베이스 연동 애플리케이션 - SQL Server를 활용한 CRUD 구현

by wawManager 2025. 4. 30.

 

1. 강의 개요

이번 강의에서는 SQL Server 데이터베이스와 연동하여
CRUD(Create, Read, Update, Delete) 기능을 구현하는 애플리케이션을 제작합니다.
Windows Forms와 데이터베이스 간 연결을 설정하고,
데이터를 조회하고 추가, 수정, 삭제하는 과정을 실습합니다.
ADO.NET을 활용하여 SQL Server와의 데이터 연동을 처리합니다.


2. 학습 목표

  • SQL Server 데이터베이스와 Windows Forms 연동
  • 데이터 추가, 조회, 수정, 삭제 기능 구현
  • ADO.NET을 활용한 SQL 쿼리 실행
  • DataGridView를 사용한 데이터 시각화

3. 기능 요구사항

필수 기능

1️⃣ 데이터 조회:

  • 데이터베이스의 데이터를 DataGridView에 표시

2️⃣ 데이터 추가:

  • 사용자 입력을 통해 새로운 데이터를 추가

3️⃣ 데이터 수정:

  • 선택한 데이터를 수정

4️⃣ 데이터 삭제:

  • 선택한 데이터를 삭제

5️⃣ UI 구성 및 동작:

  • DataGridView와 입력 필드로 직관적인 데이터 관리

4. 실습: 데이터베이스 연동 애플리케이션 제작

1️⃣ 사전 준비

  1. SQL Server 데이터베이스 생성:
    • SQL Server Management Studio(SSMS)를 사용하여 데이터베이스와 테이블 생성
    • 예제 테이블(SQL 스크립트):
    • CREATE DATABASE SampleDB; USE SampleDB; CREATE TABLE Employees ( EmployeeID INT IDENTITY(1,1) PRIMARY KEY, Name NVARCHAR(100), Position NVARCHAR(100), Salary FLOAT );
  2. ADO.NET NuGet 패키지 확인:
    • ADO.NET은 .NET Framework 또는 .NET Core에 기본 포함되어 있습니다.
    • 별도의 패키지 설치는 필요하지 않습니다.

2️⃣ 폼 구성

  • 폼(Form) 이름: Form1
  • 컨트롤 배치:

컨트롤 타입 이름 위치 크기

DataGridView dgvEmployees 폼 상단 전체 (600 x 300)
TextBox txtName 폼 하단 왼쪽 1행 (150 x 30)
TextBox txtPosition 폼 하단 왼쪽 2행 (150 x 30)
TextBox txtSalary 폼 하단 왼쪽 3행 (150 x 30)
Button btnAdd 폼 하단 중앙 1행 (100 x 30)
Button btnUpdate 폼 하단 중앙 2행 (100 x 30)
Button btnDelete 폼 하단 중앙 3행 (100 x 30)

📌 폼 디자인 예시:

--------------------------------------------------
|         [DataGridView - 직원 목록 표시]        |
--------------------------------------------------
| [Name TextBox]  [Add Button]                  |
| [Position TextBox]  [Update Button]           |
| [Salary TextBox]  [Delete Button]             |
--------------------------------------------------

3️⃣ 코드 작성

(1) 데이터베이스 연결 및 데이터 조회

using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace WindowsFormsApp_DB
{
    public partial class Form1 : Form
    {
        private const string ConnectionString = "Server=YOUR_SERVER_NAME;Database=SampleDB;Trusted_Connection=True;";

        public Form1()
        {
            InitializeComponent();
            LoadData();
        }

        // 데이터 조회
        private void LoadData()
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                var query = "SELECT * FROM Employees";
                var adapter = new SqlDataAdapter(query, connection);
                var dataTable = new DataTable();
                adapter.Fill(dataTable);

                dgvEmployees.DataSource = dataTable;
            }
        }
    }
}

(2) 데이터 추가

        // 데이터 추가
        private void btnAdd_Click(object sender, EventArgs e)
        {
            string name = txtName.Text.Trim();
            string position = txtPosition.Text.Trim();
            if (!double.TryParse(txtSalary.Text.Trim(), out double salary))
            {
                MessageBox.Show("올바른 급여를 입력하세요.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            using (var connection = new SqlConnection(ConnectionString))
            {
                var query = "INSERT INTO Employees (Name, Position, Salary) VALUES (@Name, @Position, @Salary)";
                var command = new SqlCommand(query, connection);
                command.Parameters.AddWithValue("@Name", name);
                command.Parameters.AddWithValue("@Position", position);
                command.Parameters.AddWithValue("@Salary", salary);

                connection.Open();
                command.ExecuteNonQuery();
            }

            LoadData();
            MessageBox.Show("직원이 추가되었습니다.", "완료", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

(3) 데이터 수정

        // 데이터 수정
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            if (dgvEmployees.SelectedRows.Count == 0)
            {
                MessageBox.Show("수정할 직원을 선택하세요.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            string name = txtName.Text.Trim();
            string position = txtPosition.Text.Trim();
            if (!double.TryParse(txtSalary.Text.Trim(), out double salary))
            {
                MessageBox.Show("올바른 급여를 입력하세요.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            int employeeId = Convert.ToInt32(dgvEmployees.SelectedRows[0].Cells["EmployeeID"].Value);

            using (var connection = new SqlConnection(ConnectionString))
            {
                var query = "UPDATE Employees SET Name = @Name, Position = @Position, Salary = @Salary WHERE EmployeeID = @EmployeeID";
                var command = new SqlCommand(query, connection);
                command.Parameters.AddWithValue("@Name", name);
                command.Parameters.AddWithValue("@Position", position);
                command.Parameters.AddWithValue("@Salary", salary);
                command.Parameters.AddWithValue("@EmployeeID", employeeId);

                connection.Open();
                command.ExecuteNonQuery();
            }

            LoadData();
            MessageBox.Show("직원 정보가 수정되었습니다.", "완료", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

(4) 데이터 삭제

        // 데이터 삭제
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (dgvEmployees.SelectedRows.Count == 0)
            {
                MessageBox.Show("삭제할 직원을 선택하세요.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            int employeeId = Convert.ToInt32(dgvEmployees.SelectedRows[0].Cells["EmployeeID"].Value);

            var confirmResult = MessageBox.Show("선택한 직원을 삭제하시겠습니까?", "확인", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (confirmResult == DialogResult.Yes)
            {
                using (var connection = new SqlConnection(ConnectionString))
                {
                    var query = "DELETE FROM Employees WHERE EmployeeID = @EmployeeID";
                    var command = new SqlCommand(query, connection);
                    command.Parameters.AddWithValue("@EmployeeID", employeeId);

                    connection.Open();
                    command.ExecuteNonQuery();
                }

                LoadData();
                MessageBox.Show("직원이 삭제되었습니다.", "완료", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

(5) Designer 코드

        private void InitializeComponent()
        {
            this.dgvEmployees = new DataGridView();
            this.txtName = new TextBox();
            this.txtPosition = new TextBox();
            this.txtSalary = new TextBox();
            this.btnAdd = new Button();
            this.btnUpdate = new Button();
            this.btnDelete = new Button();

            // DataGridView 설정
            this.dgvEmployees.Location = new System.Drawing.Point(10, 10);
            this.dgvEmployees.Size = new System.Drawing.Size(600, 300);
            this.dgvEmployees.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

            // Name TextBox 설정
            this.txtName.Location = new System.Drawing.Point(10, 320);
            this.txtName.Size = new System.Drawing.Size(150, 30);
            this.txtName.PlaceholderText = "Name";

            // Position TextBox 설정
            this.txtPosition.Location = new System.Drawing.Point(10, 360);
            this.txtPosition.Size = new System.Drawing.Size(150, 30);
            this.txtPosition.PlaceholderText = "Position";

            // Salary TextBox 설정
            this.txtSalary.Location = new System.Drawing.Point(10, 400);
            this.txtSalary.Size = new System.Drawing.Size(150, 30);
            this.txtSalary.PlaceholderText = "Salary";

            // Add Button 설정
            this.btnAdd.Location = new System.Drawing.Point(200, 320);
            this.btnAdd.Size = new System.Drawing.Size(100, 30);
            this.btnAdd.Text = "Add";
            this.btnAdd.Click += new EventHandler(this.btnAdd_Click);

            // Update Button 설정
            this.btnUpdate.Location = new System.Drawing.Point(200, 360);
            this.btnUpdate.Size = new System.Drawing.Size(100, 30);
            this.btnUpdate.Text = "Update";
            this.btnUpdate.Click += new EventHandler(this.btnUpdate_Click);

            // Delete Button 설정
            this.btnDelete.Location = new System.Drawing.Point(200, 400);
            this.btnDelete.Size = new System.Drawing.Size(100, 30);
            this.btnDelete.Text = "Delete";
            this.btnDelete.Click += new EventHandler(this.btnDelete_Click);

            // Form 설정
            this.ClientSize = new System.Drawing.Size(640, 450);
            this.Controls.Add(this.dgvEmployees);
            this.Controls.Add(this.txtName);
            this.Controls.Add(this.txtPosition);
            this.Controls.Add(this.txtSalary);
            this.Controls.Add(this.btnAdd);
            this.Controls.Add(this.btnUpdate);
            this.Controls.Add(this.btnDelete);
            this.Text = "데이터베이스 연동 애플리케이션";
        }

3️⃣ 실행 결과

1️⃣ 데이터 조회

  • 애플리케이션 실행 시 DataGridView에 데이터베이스의 직원 목록 표시

2️⃣ 데이터 추가

  • Name, Position, Salary 입력 후 "Add" 버튼 클릭 → 새 직원 추가

3️⃣ 데이터 수정

  • DataGridView에서 직원 선택 → 수정 내용 입력 → "Update" 버튼 클릭

4️⃣ 데이터 삭제

  • DataGridView에서 직원 선택 → "Delete" 버튼 클릭

5. 주요 개념 요약

  • SqlConnection: SQL Server와의 연결을 관리
  • SqlCommand: SQL 쿼리 실행을 위한 객체
  • SqlDataAdapter: 데이터 조회 및 채우기 작업 수행
  • DataGridView: 데이터를 시각적으로 표시 및 편집

 

 

 

📌 #CSharp #WindowsForms #SQLServer #CRUD #ADO.NET #DataGridView