基本呼叫模式
SqlCommand cmd = new SqlCommand("StoredProcName", conn);
cmd.CommandType = CommandType.StoredProcedure;
案例一:無參數預存程序
-- SQL
CREATE PROC SelectAll AS SELECT * FROM StudentInf
// C#
SqlCommand selectCmd = new SqlCommand("SelectAll", conn);
selectCmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = selectCmd;
DataSet ds = new DataSet();
da.Fill(ds); // 結果集自動填入 DataSet
案例二:帶參數預存程序
-- SQL
CREATE PROC andSelect
@StudentId VARCHAR(10),
@StudentName VARCHAR(10)
AS
SELECT * FROM StudentInf WHERE StudentId = @StudentId AND StudentName = @StudentName
// C# 方式一:逐一加入參數
SqlCommand cmd = new SqlCommand("andSelect", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@StudentId", SqlDbType.NVarChar, 10).Value = "S001";
cmd.Parameters.Add("@StudentName", SqlDbType.NVarChar, 10).Value = "王小明";
// 方式二:建立參數物件後指派值 (適合複雜邏輯)
SqlParameter p1 = cmd.Parameters.Add("@StudentId", SqlDbType.NVarChar, 10);
p1.Value = "S001";
// ...
關鍵注意事項
- 參數名稱必須與 SP 定義完全一致 (含 @ 符號)。
- 資料型別與長度需匹配:
SqlDbType.NVarChar 對應 NVARCHAR,長度設定避免截斷。
- 輸出參數/傳回值:使用
ParameterDirection.Output 或 ReturnValue 捕獲。
- 防止 SQL 注入:參數化查詢本身即防注入,嚴禁字串拼接 SQL。
- 連線管理:使用
using 區塊確保連線正確關閉釋放。
完整範本 (含輸出參數)
using (SqlConnection conn = new SqlConnection(connStr)) {
using (SqlCommand cmd = new SqlCommand("GetStudentCount", conn)) {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@DeptId", SqlDbType.Int).Value = 101;
SqlParameter ret = cmd.Parameters.Add("@TotalCount", SqlDbType.Int);
ret.Direction = ParameterDirection.Output;
conn.Open();
cmd.ExecuteNonQuery();
int total = (int)ret.Value;
Console.WriteLine("學生總數: " + total);
}
}