首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQL Server 單引號處理兩大絕招:轉義函數與參數化查詢實戰對比

     編輯:MySQL 資料庫相關知識

SQL 拼接中單引號導致語法錯誤是經典坑。本文對比 VB/ADO 環境下字符串轉義函數與 ADODB.Command 參數化查詢兩大方案的原理、代碼實現與性能差異。

方案一:字符串轉義函數 (VB 實現)


Function ProcessStr(str As String) As String
    Dim pos As Integer, result As String
    pos = InStr(str, "'")
    While pos > 0
        str = Left(str, pos) & "'" & Mid(str, pos + 1)  ' 在單引號前插入單引號
        pos = InStr(pos + 2, str, "'")
    Wend
    ProcessStr = str
End Function

' 使用
sql = "SELECT * FROM users WHERE name = '" & ProcessStr(txtName.Text) & "'"

缺陷:

  • CPU 額外開銷 (字符串操作、內存分配)
  • 僅解決單引號,無法防禦其他注入向量 (註釋、批次、UNION 等)
  • 維護成本高:每個拼接點都必須調用,漏一處即漏洞

方案二:ADODB.Command 參數化查詢 (推薦)


Dim cmd As New ADODB.Command
Dim param As ADODB.Parameter
Set cmd.ActiveConnection = cnn1
cmd.CommandText = "SELECT * FROM employee WHERE fname = ?"
cmd.CommandType = adCmdText

' 創建參數:名稱、類型、方向、大小、值
Set param = cmd.CreateParameter("p_fname", adVarChar, adParamInput, 50, txtName.Text)
cmd.Parameters.Append param

Set rst = cmd.Execute
' 結果集處理...

核心優勢:

  • 徹底分離代碼與數據:驅動層處理類型轉換、轉義、引號包裹
  • 預編譯緩存:同一 SQL 重複執行時避免解析優化開銷
  • 類型安全:參數強類型綁定,防止隱式轉換錯誤
  • 存儲過程加持:cmd.CommandType = adCmdStoredProc + 參數 → 預編譯 + 執行計劃緩存 + 網絡傳輸最小化

實戰對比測試 (PUBS 庫 employee 表)


' 測試數據含單引號:'Paolo''f'、'Paolo'f'
' 方案一:轉義函數 + 拼接 SQL
' 方案二:Command 參數化
' 方案三:存儲過程 + 參數化 (最高效)

結論:方案二/三在安全性、性能、可維護性上全面碾壓方案一。現代開發原則:永不拼接 SQL,永遠使用參數化查詢/ORM。

現代技術棧映射

平台參數化 APIORM 推薦
.NET (ADO.NET)SqlCommand.Parameters.Add()Entity Framework Core / Dapper
Java (JDBC)PreparedStatement.setString()MyBatis / JPA (Hibernate)
PHP (PDO)$stmt->bindParam()Laravel Eloquent / Doctrine
Python (DB-API)cursor.execute(sql, params)SQLAlchemy / Django ORM
Go (database/sql)db.QueryContext(ctx, sql, args...)GORM / sqlx
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved