不带PreparedStatements标准API的SQL转义

问题描述

我必须转义参数以避免SQL注入问题。我有一个很大的CriteriaBuilder SQL,可以在其中找到下一个:

Expression<Integer> containsFunction = cb.function("CONTAINS",Integer.class,joinParty.get(MyEntity_.name),cb.literal(sb.toString())
);

此“ sb”是SQLi所在的StringBuilder。无论如何,在此“ DEFINEMERGE”歌剧中有一个不常见的句子(对我来说是未知的),它带有以下自变量:

StringBuilder sb = new StringBuilder("DEFINEMERGE(((NEAR((");
for (int i = 0; i < nameValues.length; i++) {
    sb.append("{").append(nameValues[i]).append("}");
    if(i + 1 < nameValues.length) {
        sb.append(",");
    }
}
sb.append("),0)),(").append(nameValues[0]).append(" AND {").append(nameValues[1]).append("})");
if(nameValues.length > 3) {
    sb.append(",(").append(nameValues[1]).append(" AND {").append(nameValues[2]).append("})");
    if(nameValues.length == 4) {
        sb.append(",(").append(nameValues[2]).append(" AND {").append(nameValues[3]).append("})");
    }
}
sb.append("),AND,MIN)");

问题在于,某些nameValue的内部带有“(”,这会破坏SQL。在这种情况下,我不确定什么是最佳化此值的最佳方法,因为此CONTAINS使用SQL String文字而不是条件对象。

这是预期的生成的SQL:

CONTAINS(
    table.name,'DEFINEMERGE (
        (
            (NEAR( (?,{?},{?}),FALSE)),(? AND {?} and {?})
        ),min 
    )',1
)

这是生成的查询的示例(为公司隐私和安全起见,表和字段的隐藏真实名称)也具有参数bind数组:

SELECT 
    COUNT(t0.<VALUE>) 
FROM 
    SCHEME.<TABLE_NAME> t0 
    LEFT OUTER JOIN SCHEME.<TABLE_NAME> t2 ON (t2.<VALUE> = t0.<VALUE>) 
    LEFT OUTER JOIN SCHEME.<TABLE_NAME> t6 ON (t6.<VALUE> = t2.<VALUE>) 
    LEFT OUTER JOIN SCHEME.<TABLE_NAME> t7 ON (t7.<VALUE> = t6.<VALUE>) 
    LEFT OUTER JOIN SCHEME.<TABLE_NAME> t8 ON (t8.<VALUE> = t7.<VALUE>) 
    LEFT OUTER JOIN SCHEME.<TABLE_NAME> t3 ON (t3.<VALUE> = t2.<VALUE>) 
    LEFT OUTER JOIN SCHEME.<TABLE_NAME> t4 ON (t4.<VALUE> = t3.<VALUE>) 
    LEFT OUTER JOIN SCHEME.<TABLE_NAME> t5 ON (t5.<VALUE> = t4.<VALUE>),SCHEME.<TABLE_NAME> t11,SCHEME.<TABLE_NAME> t10,SCHEME.<TABLE_NAME> t9,SCHEME.<TABLE_NAME> t1 
WHERE 
    ((((((((((((((((t0.<VALUE> IN (?)) AND (t0.<VALUE> IN (?))) AND (t6.<VALUE> = ?)) AND (t3.<VALUE> IN (?))) AND ((t2.<VALUE> IS NULL) OR (t2.<VALUE> = t9.<VALUE>))) AND (t0.<VALUE> = ?)) AND (CONTAINS(t1.<VALUE>,?) > ?)) AND (t0.<VALUE> IN (?))) AND (t1.<VALUE> = ?)) AND t0.<VALUE> IN (SELECT t12.<VALUE> FROM SCHEME.<TABLE> t14 LEFT OUTER JOIN SCHEME.<TABLE> t16 ON (t16.<VALUE> = t14.<VALUE>),SCHEME.<TABLE> t13,SCHEME.<TABLE> t12,SCHEME.<TABLE> t15 WHERE ((((((t13.<VALUE> IN (?)) AND (t14.<VALUE> IN (?))) AND (t14.<VALUE> <= ?)) AND ((t14.<VALUE> IS NULL) OR (t14.<VALUE> >= ?))) AND (t16.<VALUE> = ?)) AND (((t14.<VALUE> = t13.<VALUE>) AND (t12.<VALUE> = t13.<VALUE>)) AND (t15.<VALUE> = t14.<VALUE>))))) AND (t9.<VALUE> IN (?))) AND (t11.<VALUE> IN (?))) AND (t0.<VALUE> = t11.<VALUE>)) AND (t9.<VALUE> <= ?)) AND ((t9.<VALUE> IS NULL) OR (t9.PARO_DA_END_VALIDITY >= ?))) AND (((t9.<VALUE> = t0.<VALUE>) AND (t1.<VALUE> = t0.<VALUE>)) AND (t10.<VALUE> = t9.ROTY_ID_ENGAGED_ROLE_SPEC)))

    bind => [1,INDI,1,DEFINEMERGE(((NEAR(({(name},{name)}),((name AND {name)})),MIN),2020-09-07 00:00:00.0,2020-09-07 00:00:00.0]

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)