使用 PreparedStatement 參數化查詢 SQL Server 2008 資料庫
撰寫 Database 相關的應用程式最大的安全性問題,莫過於 SQL Injection 造成的傷害。
網路上也有一堆相關的文章,參考如下:
- SQL Injection (資料隱碼)– 駭客的 SQL填空遊戲(上)
- SQL Injection (資料隱碼)– 駭客的 SQL填空遊戲(下)
- 游擊式的SQL Injection攻擊
- ASP.NET 防駭指南
- 你的網站正在裸奔嗎?
- [SQL] 淺談SQL Injection發生後
- (Demo)利用SQL Injection將惡意連結寫入資料庫
- 介紹幾款好用的 SQL Injection 偵測與防禦工具
- 避免 SQL Injection(資料隱碼攻擊)的幾種入門方法
點部落關於 SQL Injection 文章也相當的多,解決方案也有下篇文章,將各種資料參數化存取資料庫技巧整理,值得一看:
[C#][Linq to Entity][Entity SQL][ADO.net] 別再說老師沒教你用 “參數查詢法” ,今天一次通通教給你各種查詢技巧 !!!
上篇「使用 Microsoft SQL Server JDBC Driver 3.0 讀取 SQL Server 2008 資料庫」文章中,
我們已經利用 JDBC Driver 3.0 來查詢 SQL Server 2008 資料庫,並讀取結果。
而本篇文章,則是進一步撰寫參數化的 SQL 查詢語法。
參數化查詢的程式碼,修改後如下:
在 57 行,我們的 sql 語法如果需要加入參數化查詢,則是使用 ? 來表示,
例如: 「WHERE ProductID > ?」表示 ProductID 大於某一個值我們才要查詢出來。
在 58 行,conn.createStatement 改為 conn.prepareStatement 建立一個 PreparedStatement 參數化查詢物件 ps。
在 59 行,我們則是利用 ps.setXXX( columnIndex, value ) 的方式,將我們的查詢參數放入 sql 語法參數中。
ps.setInt 表示我們寫入的參數的資料型態為 int;
columnIndex 表示第 columIndex 參數 (由 1 開始);
value 則是傳入 int 型態的資料數值
在 60 行,PreparedStatement 物件與 Statement 物件一樣,呼叫 executeQuery() 方法。
如果我們將 productId 以 10 代入,則執行結果如下:
我們將 sql 語法再進一步修改,讓我們的查詢可以支援多參數,並以 Like 語法模糊查詢作為範例,程式碼如下:
在 88 行,我們的 sql 語法如果需要加入參數化查詢,則是使用 ? 來表示,
例如: 「WHERE ProductID > ? AND ProductName Like ?」表示 ProductID 大於某一個值而且 ProductName 進行模糊查詢。
在 91 行,一樣使用 setInt() 方法,將 int 資料型態的 productId 變數寫入 PreparedStatement 參數物件 ps 中。
在 92 行,則是 ps.SetString( 2, “%” + productName + “%”) 寫入 PreparedStatement 參數物件 ps ,
而且是以 String 資料型態的 productname 變數寫入第 2 個參數中。
字串比對查詢則可以使用,如下:
- prefix match: productName + “%”
- suffix match:“%” + productName
- substring match:“%” + productName +“%”
- exact match :productName
如果我們將 productId 以 10 並且 productName 以 “eso”代入,則執行結果如下:
寫程式其實不難,重要的是遇到問題常查文件,例如對於 PreparedStatement 不懂則可以到官方網站查詢:
PreparedStatement 相關 setXXX() 方法擷取如下: