USE Northwind;
GO
CREATE PROCEDURE Employees_Sel_Fuzzy
@LastName NVARCHAR(20)
AS
BEGIN
SET NOCOUNT ON;
SELECT EmployeeID, LastName, FirstName, Title, HireDate
FROM Employees
WHERE LastName LIKE '%' + @LastName + '%';
END
GO
using System;
using System.Data;
using System.Data.SqlClient;
namespace DalLibrary
{
public class EmployeeDAL
{
private readonly string _connStr;
public EmployeeDAL(string connStr) => _connStr = connStr;
public DataSet SearchByLastName(string lastName)
{
using (SqlConnection conn = new SqlConnection(_connStr))
using (SqlCommand cmd = new SqlCommand("Employees_Sel_Fuzzy", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@LastName", SqlDbType.NVarChar, 20).Value = lastName;
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}
}
}
}
}
<%@ Page Language="C#" %>
<%@ Import Namespace="DalLibrary" %>
| 措施 | 說明 |
|---|---|
| 參數化查詢 | 存儲過程 + `SqlParameter` 徹底防止 SQL Injection |
| 最小權限帳號 | 資料庫登入僅授予 `EXECUTE` 特定存儲過程權限,拒絕直接表操作 |
| 輸入驗證 | 長度、格式、字元白名單 (Regex) 驗證 |
| 輸出編碼 | GridView 自動 HTML 編碼,但 `TemplateField` 手工輸出需 `HttpUtility.HtmlEncode` |
| 錯誤處理 | DAL 捕獲 `SqlException` 包裝為自訂例外,不洩漏堆疊資訊給前端 |
CREATE PROCEDURE Employees_Sel_Fuzzy_Paged
@LastName NVARCHAR(20), @PageSize INT, @PageNumber INT, @TotalCount INT OUTPUT
AS
BEGIN
-- 計算總數
SELECT @TotalCount = COUNT(*) FROM Employees WHERE LastName LIKE '%' + @LastName + '%';
-- 分頁查詢 (SQL 2012+)
SELECT EmployeeID, LastName, FirstName, Title, HireDate
FROM Employees
WHERE LastName LIKE '%' + @LastName + '%'
ORDER BY LastName
OFFSET (@PageNumber - 1) * @PageSize ROWS
FETCH NEXT @PageSize ROWS ONLY;
END
存儲過程封裝模糊查詢邏輯,配合參數化 `SqlCommand`、三層架構 (DAL/BLL/UI)、最小權限資料庫帳號,構建安全、可維護、高效能的查詢功能。現代開發建議搭配 Dapper/EF Core 簡化 DAL 程式碼。