带有参数的IBM Mobilefirst SQL适配器,用于选择IN语句

时间:2015-06-17 15:49:42

标签: oracle ibm-mobilefirst mobilefirst-adapters

调用MobileFirst SQL适配器从Oracle Select-where-IN语句中检索结果时遇到问题。

我的环境是MobileFirst v7.0

适配器定义是:

sqlGetResultsStatement = WL.Server.createSQLStatement ("select * from table where field IN (?)");

function getResults(param) {
    return WL.Server.invokeSQLStatement({
        preparedStatement : sqlGetResultsStatement,
        parameters : [param]
    });
}

如果我在参数中使用单个值调用适配器(例如'0001'),则一切正常,我获得结果。但是,如果我用这种类型的参数调用适配器:"'0001','0002','0003'"我得到一个像这样的空结果集(没有错误)响应

{
   "isSuccessful": true,
   "resultSet": [
   ]
}

通话中有什么问题吗?

1 个答案:

答案 0 :(得分:1)

您不能将一组值传递给单个预准备语句参数。准备语句的一个关键特性是它有助于防止SQL注入攻击,因此当语句中有一个参数被认为是单个值时,这是有道理的,这就是为什么它用引号括起你传入的值"'0001','0002','0003'"。此外,MobileFirst不允许您在JS适配器中的函数内部创建预准备语句,因此在调用过程时无法修改参数数量。有了这个说法,你可以采取两种方法来实现这一目标。

Javascript适配器 确定您将传递给此过程的最大参数数,并事先将参数添加到预准备语句中。假设你永远不会传递超过10个参数,那么我会使用类似的东西:

    var MAX_PARAMS = 10;

    sqlGetResultsStatement = WL.Server.createSQLStatement ("select * from table where field IN (?,?,?,?,?,?,?,?,?,?)");

    function getResults(param) {
        /*
         * (arguments) is an array of parameters passed to the procedure
         */
        return WL.Server.invokeSQLStatement({
            preparedStatement : sqlGetResultsStatement,
            parameters : fillVars(arguments)
        });
    }
    // helper function to fill all the values for the SQL Statement Parameters
    function fillVars(vars) {
        var list = [];

        for(var i = 0; i < MAX_PARAMS; i++) {
            if(vars.length >= i + 1) {
                list.push(vars[i]);
            } else {
                // some value that will not be in your db
                list.push(null);
            }
        }

        return list;
    }

Java Adapter 另一种选择是使用Java Adapter并直接连接到您的DB并编写自己的查询/预备语句。 仅供参考:此选项将为您提供更大的灵活性,但您必须包含数据库驱动程序jar文件并编写所有数据库连接/查询逻辑等。