企業級 .NET 應用常需封裝統一資料存取層 (DAL)。本文提供一個功能完整的 SQLDataBase 基底類別,支援三種呼叫模式:單純 SQL 字串、參數化 SQL、預存程序,每種模式均包含 執行非查詢、執行純量查詢、執行 DataReader、執行 DataSet、交易處理 五大核心方法,且完整實作 IDisposable 模式與例外處理,可直接引用專案使用。
namespace SQLDataBase
{
public class SQLDataBase
{
// 連線字串從設定檔讀取
protected static string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
#region 模式一:單純 SQL 字串 (5 方法 + 交易)
public int ExecuteSql(string SQLString) { ... }
public void ExecuteSqlTran(ArrayList SQLStringList) { ... }
public object GetSingle(string SQLString) { ... }
public DbDataReader ExecuteReader(string strSQL) { ... }
public DataSet GetDataSet(string SQLString) { ... }
#endregion
#region 模式二:參數化 SQL (5 方法 + 交易)
public int ExecuteSql(string SQLString, DbParameter[] cmdParms) { ... }
public void ExecuteSqlTran(Hashtable SQLStringList) { ... } // Key=SQL, Value=SqlParameter[]
public object GetSingle(string SQLString, DbParameter[] cmdParms) { ... }
public DbDataReader ExecuteReader(string SQLString, DbParameter[] cmdParms) { ... }
public DataSet GetDataSet(string SQLString, DbParameter[] cmdParms) { ... }
#endregion
#region 模式三:預存程序 (5 方法 + 交易)
public int RunProcedureExecuteSql(string storeProcName, DbParameter[] parameters) { ... }
public object RunProcedureGetSingle(string storeProcName, DbParameter[] parameters) { ... }
public DbDataReader RunProcedureGetDataReader(string storedProcName, DbParameter[] parameters) { ... }
public DataSet RunProcedureGetDataSet(string storedProcName, DbParameter[] parameters) { ... }
public bool RunProcedureTran(Hashtable SQLStringList) { ... } // Key=SqlParameter[], Value=SP Name
#endregion
// 內部輔助方法
private void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, string cmdText, DbParameter[] cmdParms) { ... }
private SqlCommand BuildQueryCommand(SqlConnection connection, string storedProcName, DbParameter[] parameters) { ... }
}
}
using (SqlConnection ...) 確保連線正確關閉釋放。DataReader 使用 CommandBehavior.CloseConnection 自動關閉連線。cmd.Parameters.Clear() 避免參數殘留。ArrayList 批次執行,失敗 Rollback。Hashtable (Key=SQL, Value=SqlParameter[]),逐條準備命令執行。Hashtable (Key=SqlParameter[], Value=SP Name),支援多 SP 單一交易。SqlParameter,從根源杜絕注入攻擊。DbDataReader、DbParameter[],易於未來遷移至其他 ADO.NET Provider (Oracle, PostgreSQL 等)。web.config/app.config,支援多環境部署。<connectionStrings>
<add name="ConnectionString" connectionString="Server=.;Database=MyDB;Uid=sa;Pwd=123;" providerName="System.Data.SqlClient" />
</connectionStrings>
var db = new SQLDataBase.SQLDataBase();
// 1. 參數化查詢 (推薦)
string sql = "SELECT * FROM Users WHERE UserId = @UserId AND Status = @Status";
var prms = new SqlParameter[] {
new SqlParameter("@UserId", 1001),
new SqlParameter("@Status", 1)
};
DataSet ds = db.GetDataSet(sql, prms);
// 2. 預存程序
DataSet ds2 = db.RunProcedureGetDataSet("usp_GetUserById", new SqlParameter[] {
new SqlParameter("@UserId", 1001)
});
// 3. 交易範例 (參數化)
var ht = new Hashtable();
ht.Add("INSERT INTO Log (Msg) VALUES (@Msg)", new SqlParameter[] { new SqlParameter("@Msg", "Test") });
ht.Add("UPDATE Counter SET Cnt = Cnt + 1", new SqlParameter[0]);
db.ExecuteSqlTran(ht);
using 區塊或 finally 中關閉 Reader,否則連線洩漏。ExecuteReaderAsync、ExecuteNonQueryAsync 等非同步方法。SqlConnection.RetryLogic 或 Polly 重試策略。PrepareCommand 加入 SQL 執行時間記錄 (MiniProfiler/Serilog)。