PreparedStatement setString IN 傳多個參數


今天在使用PreparedStatement進行預編譯時,發現使用IN(String) 傳入一個字符串一逗號為分隔符卻失效,例如傳入"a,b,c", 查詢的不是"a" "b" "c"三個數據,而是"a,b,c"一個數據

 

SELECT d.* FROM TLK_列表_分頁 d WHERE 1=1  AND ITEM_多行文本二 IN ( ?)

這條語句中的參數在使用PrepareStatement來預編譯之后,是不可以傳入一個拼接字符串的,比如

String test="'a','b','c'";
prepareStatement.setString(1,test);

想要達到執行效果

SELECT d.* FROM TLK_列表_分頁 d WHERE 1=1  AND ITEM_多行文本二 IN ('a','b','c')

但是實際執行的sql語句是:

SELECT d.* FROM TLK_列表_分頁 d WHERE 1=1  AND ITEM_多行文本二 IN ('a'',''b'',''c')

 

它不是查詢 'a','b','c'這三個元素,而是查詢'a,b,c,'這一個元素,所以達不到預期的效果

后來想過既然它插入的字符串是逗號兩邊少了單引號的話我就replace把 ","換成" ',' "

這樣以后實際執行的sql語句是:

SELECT d.* FROM TLK_列表_分頁 d WHERE 1=1  AND ITEM_多行文本二 IN ('a'',''b'',''c')

單引號變成了雙引號,其實是sql防注入起了作用,它對單引號自動進行了轉義 ' 變成了  '' 給單引號加多一個引號進行了轉義。

於是只好使用笨辦法,

String test里面有幾個參數,那就有幾個占位符 ?

就是當 String test="'a','b','c'"; 有兩個逗號時,sql就應該是:

SELECT d.* FROM TLK_列表_分頁 d WHERE 1=1  AND ITEM_多行文本二 IN ( ?,?,?)

這樣就OK了。

添加占位符的代碼如下:

        
                String temp = "IN ( ? ";
          //判斷逗號出現的次數
int n = test.length() - test.replaceAll(",", "").length(); //根據參數的數量決定占位符的數量 if (sql.contains(temp)) {
            //循環添加占位符的次數要比逗號出現的次數多一次,即參數的數量。
for (int i = 0; i < n; i++) { sql = sql.replace(temp, temp + ",?"); temp = temp + ",?"; } } }

 這樣為sql添加了對應的占位符后,如果不把test字符串進行切割,依然會報錯,因為如果進行了添加占位符,你的sql變成了

SELECT d.* FROM TLK_列表_分頁 d WHERE 1=1  AND ITEM_多行文本二 IN ( ?,?,?)

這樣你就需要傳入三個參數,僅僅是傳入“a,b,c”的話是滿足不了條件的。

     List<Object> sqlParameters;

 if (text.contains(",")) {
                int n = text.length() - text.replaceAll(",", "").length();
                //切割參數添加到sqlParameters
                for (int i = 0; i <= n; i++) {
                    String s = text.split(",")[i];
                    sqlParameters.add(i, text.split(",")[i]);
                }
                //添加完切割的參數后刪除原來未切割的參數
                sqlParameters.remove(text);
            }

用List切割完以后就可以傳入數據了。

 for (Object sqlParameter : sqlParameters) {
                parameterIndex++;
                if (sqlParameter instanceof String) {
                    preparedStatement.setString(parameterIndex, (String) sqlParameter);
                }

這個寫法是可以滿足PG數據庫的

可以參考網站:https://blog.csdn.net/lismooth/article/details/76934980


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM