How do I set a parameter to a list of values in a BIRT report?

前端 未结 4 841

I have a DataSet with a query like this:

select s.name, w.week_ending, w.sales 
from store s, weekly_sales_summary w 
where s.id=w.store_id and s.id = ?
         


        
4条回答
  •  星月不相逢
    2020-12-03 04:26

    I created a more general solution, which handles optional/required parameters behaviour too. When parameter is not required and user doesn't select any value, the IN-clause gets disabled. It also allows the user to select both real values and null value.

    In report initialize script I add this code:

    /** Fullfill IN-clause in a data set query,
     *  using a List box report parameter.
     *  Placeholder must be the parentheses after IN keyword with wathever you want inside.
     *  If required is false then the whole IN-clause in the query 
     *  must be surrounded by parentheses.
     *  dataType and required refers to the parameter, they must be passed, 
     *  but should be better to find a way to retrieve them inside this function
     *  (given parameter name).
     */
    function fulfillInClause(dataSet, placeholder, param, dataType, required) {
    
        if (dataSet.queryText.indexOf(placeholder)>=0) {
    
            var paramValue = params[param].value;
            var emptyParam = (paramValue==null || paramValue.length<=0);
    
            //build the list of possible values
            //  paramValue==null check in ternary operators 
            //  will prevent exceptions when user doesn't select any value
            //  (it will not affect the query if param is optional, 
            //  while we will never arrive here if it is required)
            var replacement = " (";
            if (dataType == "string")
                replacement += (emptyParam ? "''" : createList(paramValue, ",", "'", "varchar(10)") );
            else if (dataType == "integer")
                replacement += (emptyParam ? "0"  : createList(paramValue, ",", "" , "int"        ) );
            else
                //TODO implement more cases
                return;
            replacement += ") ";
    
            //if param is not required and user doesn't select any value for it
            //then nullify the IN clause with an always-true clause
            if (!required && emptyParam)
                replacement += " or 0=0 ";
    
            //put replacement in the query
            dataSet.queryText = dataSet.queryText.replace( placeholder, replacement );
            //DEBUG
            params["debug" + dataSet.name + "Query"]=dataSet.queryText;        
        }
    }
    
    /** Create a string list of array values,
     *  separated by separator and each of them surrounded by a pair surrounders
     */
    function createList(array, separator, surrounder, sqlDataType){
        var result = "";
    
        for(var i=0; i0)
                result += separator;
    
            if(array[i]!=null)
                result += surrounder + array[i] + surrounder;
            else
                result += "cast(null as " + sqlDataType + ")";
        }
        return result;
    }
    

    Usage example

    In dataset query put your special IN-clause:

    select F1, F2
    from T1 
    where F3='Bubi'
      and ( F4 in (''/*?customers*/) )
    

    In beforeOpen script of the dataset with the IN-clause write:

    fulfillInClause(this, "(''/*?customers*/)", "customers", "string", false);
    

    Note that I used a placeholder which allows the query to run also before the replacement (eg. it has quotes as F4 is a varchar). You can build a placeholder that fits your case.

提交回复
热议问题