欄位 Title、Content 含單引號(如 O'Reilly),直接拼接 SQL 會語法錯誤:
INSERT INTO myBBS (Title, Content) VALUES ('O'Reilly', '...') -- 語法錯誤
// C# 範例
string title = txtTitle.Text.Replace("'", "''");
string content = txtContent.Text.Replace("'", "''");
string sql = $"INSERT INTO myBBS (Title, Content) VALUES ('{title}', '{content}')";
✅ 簡單快速修補舊代碼
❌ 仍屬拼接 SQL,無法防禦所有注入變體、效能差(無計劃重用)
CREATE PROCEDURE InsertMyBBSProc
@Title CHAR(160),
@Author CHAR(20),
@Content NTEXT
AS
INSERT INTO myBBS (Title, Author, Content) VALUES (@Title, @Author, @Content);
DECLARE @title CHAR(160) = 'test title',
@author CHAR(20) = 'david',
@content NTEXT = 'content with '' quote';
EXEC InsertMyBBSProc @title, @author, @content;
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand("InsertMyBBSProc", conn) { CommandType = CommandType.StoredProcedure })
{
cmd.Parameters.Add("@Title", SqlDbType.Char, 160).Value = txtTitle.Text;
cmd.Parameters.Add("@Author", SqlDbType.Char, 20).Value = "David Euler";
cmd.Parameters.Add("@Content", SqlDbType.NText).Value = txtContent.Text;
conn.Open();
int rows = cmd.ExecuteNonQuery(); // 回傳影響行數
}
| 維度 | 轉義法 | 參數化存儲過程 |
|---|---|---|
| 防注入 | 部分 | 徹底 |
| 計劃重用 | 否 | 是 |
| 型別安全 | 否 | 是 |
| 維護性 | 低 | 高(邏輯在資料庫端) |
| 適用場景 | 舊系統快速修補 | 新開發、核心業務 |
string sql = "INSERT INTO myBBS (Title, Content) VALUES (@Title, @Content)";
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@Title", txtTitle.Text);
cmd.Parameters.AddWithValue("@Content", txtContent.Text);
// ...
}
結論:新專案請直接使用 參數化 SQL 命令,存儲過程保留給極高效能/邏輯封裝需求。拼接 SQL + 轉義僅為歷史包袱暫時方案。