int b, c;
char c1[12], c2[12];
GetDlgItem(IDC_EDIT1)->GetWindowText(c1, 12);
GetDlgItem(IDC_EDIT5)->GetWindowText(c2, 12);
b = atoi(c1); c = atoi(c2);
CString SQL = "select * from employees where 爐號 >= b and 爐號 <= c";
// 錯誤:SQL 字串中直接寫變數名 b, c,資料庫不認識
C++ 字串字面值中不會自動展開變數值,b、c 被視為 SQL 中的字面字串或識別碼,導致「參數未指定值」或語法錯誤。
CString SQL;
SQL.Format(_T("select * from employees where 爐號 >= %d and 爐號 <= %d"), b, c);
// %d 對應 int 型別,自動轉為字串插入
_CommandPtr pCmd(__uuidof(Command));
pCmd->ActiveConnection = m_Ado.m_pConnection;
pCmd->CommandText = _T("select * from employees where 爐號 >= ? and 爐號 <= ?");
pCmd->CommandType = adCmdText;
pCmd->Parameters->Append(pCmd->CreateParameter(_T("@min"), adInteger, adParamInput, 0, b));
pCmd->Parameters->Append(pCmd->CreateParameter(_T("@max"), adInteger, adParamInput, 0, c));
_RecordsetPtr pRs = pCmd->Execute(NULL, NULL, adCmdText);
// 後續處理 pRs...
| 方法 | SQL 注入風險 | 型別安全 | 執行計畫重用 | 適用場景 |
|---|---|---|---|---|
| CString.Format 拼接 | 高 (若輸入含引號) | 靠開發者 | 否 | 簡單整數/受控輸入 |
| ADO 參數化命令 | 無 | 強型別 | 是 | 所有生產環境查詢 |
/、#、空格)作為欄位名。[爐號] 包裹。furnace_no),並建立視圖或別名供中文介面顯示。使用 CString.Format(_T("... %d ..."), var) 可快速修正變數注入問題;長期專案強烈建議改用 ADO 參數化命令,確保安全與效能。