動態 SQL、預存程序參數、字串常值中出現單引號時,SQL Server 使用雙單引號 ('') 作為逃脫字元,而非反斜線。本文說明正確寫法與常見錯誤。
-- 錯誤:單引號直接巢狀,解析器誤判字串結束
@condition = 'ROOMTYPE LIKE ''%標準間%''' -- 紅色部分會報錯
-- 正確:單引號內部用兩個單引號代表一個單引號字元
@condition = 'ROOMTYPE LIKE ''''%標準間%'''''
-- 解析後實際傳遞給執行的字串:
-- ROOMTYPE LIKE '%標準間%'
DECLARE @sql NVARCHAR(MAX), @name NVARCHAR(50) = N'張三''s Book'; -- 變數宣告也用雙單引號
SET @sql = N'SELECT * FROM Books WHERE Author = ''' + REPLACE(@name, '''', '''''') + N'''';
-- @sql 內容: SELECT * FROM Books WHERE Author = '張三''s Book'
EXEC sp_executesql @sql;
'It''s OK' → 實際字串 It's OK。REPLACE(@var, '''', '''''') 將變數內單引號加倍。sp_executesql) 完全避免拼接。DECLARE @sql NVARCHAR(MAX) = N'SELECT * FROM Books WHERE Author = @author';
EXEC sp_executesql @sql, N'@author NVARCHAR(50)', @author = @name;
-- 無需任何逃脫處理,最安全、效能最佳 (計畫重用)
| 情境 | 輸入 | SQL 中寫法 | 實際值 |
|---|---|---|---|
| 字串常值含單引號 | O'Reilly | 'O''Reilly' | O'Reilly |
| 動態 SQL 字串拼接 | 變數 @v = 'O''Reilly' | REPLACE(@v, '''', '''''') | O''Reilly (在動態 SQL 中再次逃脫) |
| 預存程序字串參數 | EXEC sp 'O''Reilly' | 呼叫端加倍 | O'Reilly |
牢記:SQL Server 單引號逃脫 = 雙單引號,拒絕反斜線、拒絕雙引號,動態 SQL 首選參數化查詢徹底消除注入與逃脫風險。