본문 바로가기
Dotnet

저장 프로시저 및 C# 사용

by 잘먹는 개발자 에단 2025. 2. 20.

저장 프로시저는 데이터베이스에서 여러 SQL 쿼리를 하나의 함수처럼 묶어두고,

이를 필요할 때마다 호출하여 실행할 수 있도록 하는 기능이다.

 

이를 통해서 코드의 재사용성을 높이고, 네트워크 부하를 줄이고, 데이터 무결성을 유지할 수 있다. 

 

 

예시

1. 단순한 데이터 조회 프로시저

CREATE PROCEDURE GetAllEmployees
AS
BEGIN
	SELECT * FROM Employees;
END;

 

 

2. 매개변수를 사용하는 프로시저

- 특정 부서의 직원들을 조회하는 프로시저로, 부서 ID를 매개변수로 받는다.

CREATE PROCEDURE GetEmployeesByDepartment
	@DepartmentID INT
AS
BEGIN
	SELECT * FROM Employees
    WHERE DepartmentID = @DepartmentID
END;

 

 

3. 데이터 삽입 프로시저

- 새로운 직원을 테이블에 추가

CREATE PROCEDURE AddNewEmployee
	@FirstName = NVARCHAR(50),
    @LastName NVARCHAR(50),
    @DepartmentID INT
AS
BEGIN
	INSERT INTO Employees ( FirstName, LastName, Department )
    VALUES (@FirstName, @LastName, @Department );
END;

 

 

3. 데이터 삽입 프로시저

CREATE PROCEDURE AddNewEmployee
	@FirstName NVARCHAR(50),
    @LastName NVARCHAR(50),
    @DepartmentID INT
AS
BEGIN
	INSERT INTO Employees (FirstName, LastName, DepartmentID)
    VALUES (@FirstName, @LastName, @DepartmentID);
END;

 

 

4. 이후 C#에서는 다음과 같이 사용한다. 

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

class Program
{
    static void Main()
    {
        // 데이터베이스 연결 문자열
        string connectionString = "Server=서버이름;Database=데이터베이스이름;User Id=사용자이름;Password=비밀번호;";

        // 저장 프로시저 이름
        string storedProcedureName = "GetEmployeesByDepartment";

        // 매개변수 값 설정
        int departmentId = 1;

        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            using (SqlCommand command = new SqlCommand(storedProcedureName, connection))
            {
                command.CommandType = CommandType.StoredProcedure;

                // 매개변수 추가
                command.Parameters.AddWithValue("@DepartmentID", departmentId);

                try
                {
                    connection.Open();

                    // 데이터 읽기
                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            Console.WriteLine($"ID: {reader["EmployeeID"]}, Name: {reader["FirstName"]} {reader["LastName"]}");
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"오류 발생: {ex.Message}");
                }
            }
        }
    }
}

 

 

5. 클래스에서 정적 메서드로 놓고 쓰려면, GET 프로시저밖에 쓸 수없다. 파라미터는 가변적이라 INSERT나 UPDATE에는 적절하지 않다.  그리고 UI 단에서 코드가 이렇게나 가벼워진다. 

 

 public static DataTable ExecuteMSsqlGetProcedure(string procedureName) 
 {
     string connString = "Server=비밀;Database=HRDB2;Trusted_Connection=True;TrustServerCertificate=True";

     using (SqlConnection connection = new SqlConnection(connString))
     {
         using (SqlCommand command = new SqlCommand(procedureName, connection))
         {
             command.CommandType = CommandType.StoredProcedure;

             try
             {
                 connection.Open();

                 using(SqlDataReader reader = command.ExecuteReader())
                 {
                     DataTable dt = new DataTable();
                     dt.Load(reader);

                     return dt;
                 }   
             }catch(Exception e)
             {
                 // 에러났을 때 보통 UI에서 보여줘야 하기 때문에 여기서는 스레드 크로싱 때문에 던져야함. 
                 throw e;
             }
         }
     }
 }

 

이렇게 놓고 사용하면 UI 단에서 사용할 코드는 이게 다다!!

그리고 따로 호출 없이 바로 SSMS에서 바로바로 테스트할 수 있으니 

이게 개발 속도도 빠르고 간편하다. 

 

 DataTable dt = Util.ExecuteMSsqlGetProcedure("GetAllEmployees");
 
 foreach (DataRow row in dt.Rows)
 {
     ListBox.Items.Add(row["EmpName"]);
 }