我們最近將基礎(chǔ)框架升級到了 springboot 3.3.5 和其他相關(guān)庫。
測試期間向我報告了一個錯誤。使用 jsqlparser 5.0 時某些查詢會失敗。
這是一個簡單的演示:
public class test { public static void main(string[] args) throws jsqlparserexception { string sql = "select convert(if(bill_type = 2, id, ''), char) from dual"; statement statement2 = ccjsqlparserutil.parse(sql); system.out.println(statement2.tostring()); } }
問題在于 jsqlparser 5.0 不支持 mysql 風格的 convert 語法 convert(expr, type)。它僅支持:
sql server 風格:convert(type, expr)
字符集轉(zhuǎn)換:convert(expr using charset)
這會影響使用 mysql 的 convert 函數(shù)的查詢,尤其是當表達式很復雜時(例如使用 if 語句)。
jsqlparser 中的當前語法:
{ <k_convert> "(" ( lookahead(coldatatype() ",") ( coldatatype = coldatatype() "," expression = expression() [ "," style = <s_long> ] ) | ( expression = expression() <k_using> transcodingname=identifierchain() ) ) ")" }
這個問題有兩種解決方案:
-
使用 cast 而不是 convert
只需將 convert(expr, type) 替換為 cast(expr as type) 即可。如果您使用 mysql -
修改 jsqlparser 語法以支持 convert(expr, type)
需要修改語法規(guī)則以支持mysql語法。但是,請小心 transcodingfunction.appendto 方法。當前實現(xiàn)生成 convert(type, expr),這在 sql server 中是合法的,但在 mysql 中是非法的
,這是最簡單的解決方案
public StringBuilder appendTo(StringBuilder builder) { if (isTranscodeStyle) { return builder .append("CONVERT( ") .append(expression) .append(" USING ") .append(transcodingName) .append(" )"); } else { return builder .append("CONVERT( ") .append(colDataType) .append(", ") .append(expression) .append(transcodingName != null && !transcodingName.isEmpty() ? ", " + transcodingName : "") .append(" )"); } }