C# ADO.NET SqlDataAdapter로 저장 프로시저를 호출해 DataSet 채우기
이전 장에서는 SqlDataReader로 앞으로만 읽는 스트림 방식으로 데이터를 읽었습니다. 이번에는 SqlDataAdapter를 사용해 저장 프로시저의 조회 결과 전체를 DataSet(메모리 내 오프라인 데이터 테이블)에 불러옵니다. 주로 DataGridView 같은 컨트롤에 직접 바인딩할 때 활용합니다.SqlCommand(저장 프로시저 정의) → SqlDataAdapter.SelectCommand → adapter.Fill(DataSet)로 데이터 자동 가져오기
예제 코드
string connectionString = "Data Source=.;Initial Catalog=db;Integrated Security=SSPI;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand sqlCom = new SqlCommand();
sqlCom.Connection = conn;
sqlCom.CommandText = "myProc";
// 저장 프로시저 실행으로 지정
sqlCom.CommandType = CommandType.StoredProcedure;
// 저장 프로시저 입력 매개변수 전달
SqlParameter param = new SqlParameter("@id", SqlDbType.Int, 8);
param.Value = 4;
param.Direction = ParameterDirection.Input;
sqlCom.Parameters.Add(param);
// 데이터 어댑터
SqlDataAdapter sqlDA = new SqlDataAdapter();
sqlDA.SelectCommand = sqlCom;
DataSet ds = new DataSet();
// 데이터 채우기, 두 번째 인수는 DataSet 내부 테이블 이름
sqlDA.Fill(ds, "sdfdsf");
// WinForms 그리드 컨트롤 바인딩
this.dataGridView1.DataSource = ds.Tables[0];
}Code language: C# (cs)
더 권장하는 예제
string connectionString = "Data Source=.;Initial Catalog=db;Integrated Security=SSPI;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
string procName = "myProc";
using (SqlCommand sqlCom = new SqlCommand(procName, conn))
{
sqlCom.CommandType = CommandType.StoredProcedure;
// 매개변수 간결하게 설정
sqlCom.Parameters.Add("@id", SqlDbType.Int).Value = 4;
SqlDataAdapter sqlDA = new SqlDataAdapter(sqlCom);
DataSet ds = new DataSet();
// 결과 채우기, 테이블 별칭 ArticleResult
sqlDA.Fill(ds, "ArticleResult");
// 컨트롤 바인딩
dataGridView1.DataSource = ds.Tables["ArticleResult"];
// 인덱스 접근도 가능:ds.Tables[0]
}
}Code language: JavaScript (javascript)
설명
SqlDataAdapter.Fill() 동작 특징
- 연결 자동 관리:
Fill호출 시 연결이 Open() 상태가 아니면 어댑터가 자동으로 연결을 열고 작업이 끝나면 닫습니다.
예제 코드에서
conn.Open()을 직접 호출했는데 작동은 하지만 필수는 아닙니다.
Fill(ds, "테이블이름"):메모리에 적재되는 DataTable에 이름을 지정해 이름으로 조회할 수 있습니다. 지정하지 않으면 기본 이름은Table입니다.- 저장 프로시저가여러 결과 집합을 반환하면
Fill이 여러 DataTable을 자동 생성합니다:ds.Tables[0]、ds.Tables[1]...
DataSet vs SqlDataReader 핵심 비교
| 객체 | 작동 모드 | 연결 점유 | 적용 시나리오 |
|---|---|---|---|
| SqlDataReader | 연결 유지 스트림 읽기 | 데이터베이스 연결 계속 점유 | 대량 데이터, 전체 캐시 불필요, 행 단위 처리 |
| DataSet(DataAdapter) | 오프라인 메모리 캐시 | Fill 완료 후 연결 해제 | UI 컨트롤 바인딩, 소규모 데이터셋, 반복 읽기 |
저장 프로시저 실행 필수 설정
sqlCom.CommandType = CommandType.StoredProcedure;
이 줄이 없으면 ADO.NET은 myProc을 일반 SQL 텍스트로 처리하고 오류를 발생시킵니다.
컨트롤 바인딩
dataGridView1.DataSource = ds.Tables[0];
WinForms DataGridView는 DataTable을 직접 바인딩하며 열을 자동 생성합니다.
데이터를 수정한 뒤 DB에 반영해야 한다면 SqlDataAdapter.Update()로 대량 갱신을 처리할 수 있습니다.
연결을 수동으로 열지 않는 방식
using(SqlConnection conn=new SqlConnection(connectionString))
using(SqlCommand cmd=new SqlCommand("myProc",conn))
{
cmd.CommandType=CommandType.StoredProcedure;
cmd.Parameters.Add("@id",SqlDbType.Int).Value=4;
SqlDataAdapter da=new SqlDataAdapter(cmd);
DataSet ds=new DataSet();
da.Fill(ds,"Article"); // 연결 자동 열기·닫기
}Code language: JavaScript (javascript)
위 예제는 using 구문으로 연결 리소스를 관리합니다
SqlDataAdapter
Previous: SqlDataReader
Next: 저장 프로시저 Return