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 與 SqlDataReader 核心比較
| 物件 | 模式 | 連線佔用 | 適用場景 |
|---|---|---|---|
| SqlDataReader | 連線式串流讀取 | 持續佔用資料庫連線 | 大量資料、不需要完整快取、逐筆處理 |
| DataSet(DataAdapter) | 離線記憶體快取 | Fill 完成就釋放連線 | UI控制項繫結、小量資料集、重複讀取資料 |
執行預存程序必要設定
sqlCom.CommandType = CommandType.StoredProcedure;
少了這一行,ADO.NET 會把 myProc 當成一般 SQL 文字執行,直接拋出錯誤。
控制項繫結
dataGridView1.DataSource = ds.Tables[0];
WinForms 的 DataGridView 可直接繫結 DataTable,自動產生資料行;
如果後續要修改資料並寫回資料庫,可以搭配 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