Discussions
Categories
Groups
Community Home
Categories
INTERNAL ENABLEMENT
POPULAR
PUBLIC CLOUD
PRIVATE CLOUD
Quick Links
MY LINKS
HELPFUL TIPS
Back to website
Home
Intelligence (Analytics)
complete dynamic report
birtprofi
Hello,<br />
<br />
I have to build a completely dynamic report. This is a really challenge for me. But if it done I think it would be something for DevShare maybe.<br />
<br />
Lets talk about my first problem.<br />
<br />
for example:<br />
Dataset1: (no problem, I handle this with property binding)<br />
I run the report from an application and within the link I use a parameter called ID=4<br />
Then I have to run the first dataset query like: <span class='bbc_underline'>"Select NUMBERS from mytable where ID=4"</span><br />
<br />
Then I get this values: <em class='bbc'>"(xx,xy,xz,zz)</em>" (these are the names of colums of another table)<br />
This values I have to use in a new Data-Set Query like:<br />
<br />
Dataset2: (problem)<br />
Then I have to build a new SQL like this:<br />
<span class='bbc_underline'>"Select NAME, STREET, <em class='bbc'>>> xx,xy,xz,zz <<</em> from ADRESS</span><br />
<br />
So I have to run Dataset1 and then build in the result of dataset1 into the query of Dataset2<br />
<br />
After this is solved I will come back with the next step.<br />
<br />
kind regards<br />
Rafael
Find more posts tagged with
Comments
SNX2012
You want to do this in just one call of the report?
birtprofi
if it?s possible yes of course
SNX2012
i think i should be possible with more then one call. if you write the results of the first querry to parameters and call the second run with the new parameters. but all in one call, i dont have an idear... iam sorry.
Tubal
One way to do it would be to connect to your db and run your first query in your report beforeFactory event, store the value returned to a global variable, and then in your dataset's beforeOpen event, replace the pertinent part of your sql statement with your global variable.<br />
<br />
So you wouldn't actually have a premade first dataset. You would do all this in script.<br />
<br />
I do something similar in the attached report. In this report, I call the database to get my column names and widths, store them in an array, and then dynamically create my table from this array. The beforeFactory event is where the database query takes place. The only difference is you would also need to fetch the parameter (ID=4) from your url before you created your dataset. You could do that with something like this:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>importPackage( Packages.javax.servlet.http );
var request = reportContext.getHttpServletRequest();
id=request.getParameter("__id");</pre>
birtprofi
Hi tubal,
thanks for your support. It looks really good.
I will make some tests and come back early next week.
best regards
rafael
birtprofi
so, I have made some test and have actually following question or problem. <br />
On initialize or before factory I run following script:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>var odaDataSet = new OdaDataSetDesign( "Tmp Data Set" ); //making our new Data Set
odaDataSet.setDataSource( odaDataSource.getName( ) ); //setting our Data Source
odaDataSet.setExtensionID( "org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet" );
var OENR = " where OEPERM_NR = " + params["ID"];
var strSQL = "select OEPERM_SALDEN_SP from OEPERM" + OENR; //this is the query to our new data set
odaDataSet.setQueryText( strSQL );
de.defineDataSource( odaDataSource );
de.defineDataSet( odaDataSet );
queryDefinition = new QueryDefinition( );
queryDefinition.setDataSetName( odaDataSet.getName() );</pre>
<br />
as value I get only one field/row back with data like this: "[2,5,7,8,9,10]"<br />
<br />
Now I have to run a dataset with property binding with this data field. Do you have any Idea, how I could make this? Could I save the result of my tmp data set as variable, so that I could use this within the next query?
Tubal
You can store this data in a variable for later use.<br />
<br />
You don't say where you are putting this data you are getting, but lets assume it's stored in a variable called myData. You may need to do some string modification to your data before you pass it to your query, but that should be easy enough using javascript.<br />
<br />
You can put this final data into a global variable that's accessible in other areas of the report.<br />
<br />
Something like:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>reportContext.setGlobalVariable("myGlobalVariable", myData);</pre>
<br />
I'm not exactly sure what your query set up is, but if it was something like:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>SELECT myField
FROM myTable
WHERE myField2 IN (1,2,3,4,5);</pre>
<br />
Then you could edit your query to be something like:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>SELECT myField
FROM myTable
WHERE myField2 IN (000000);</pre>
<br />
And then in the beforeOpen script of the dataset you want to use this data in, you'd do something like:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>this.queryText = this.queryText.replace("000000",reportContext.getGlobalVariable("myGlobalVariable"));</pre>
<br />
This will replace any instance of '000000' with your variable.
birtprofi
Hi,<br />
<br />
thanks for your answer. I will try to explain my problem better. You wrote:<br />
<blockquote class='ipsBlockquote' ><p>You don't say where you are putting this data you are getting</p></blockquote>
This is actually myproblem. Your sample report is my example. <br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>var odaDataSource = new OdaDataSourceDesign( "Tmp Data Source" ); //this is our new data source
var strSQL = "select ABC from XYZ//this is the query to our new data set
</pre>
The result data from strSQL will be stored in Data Set "Tmp Data Source". Is this right?<br />
<br />
Accepted the result is "(DEF)". How could I store this result or the data content of "Tmp Data Source" into a variable? Is in your report the values stored in this variables below?<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>var pq = de.prepare( queryDefinition );
var qr = pq.execute( null );
var ri = qr.getResultIterator( );
var rsmd = qr.getResultMetaData( );</pre>
<br />
Sorry, for my questions, but I try to understand your report and could take efforts and improve myself.<br />
<br />
best regards
Tubal
Yes, ri and rsmd is where the data is returned.<br />
<br />
<br />
ri basically holds how many rows you get from your query, and rsmd holds the data (rsmd = result set meta data) returned.<br />
<br />
So depending on how your data is being returned (if it's one row, or multiple rows) you would cycle through your result set using ri to put your data in whatever format you want.<br />
<br />
In my sample, I need to get 3 columns from each row, and my query generally returns multiple rows. So I create a 3 column array called 'columns', and store the 3rd, 5th, and 7th fields from my query into that array.<br />
<br />
You can see how I cycle through each row returned (ri) and pull the data out (ri.getValue(rsmd.getColumnName(3)) to get the 3rd column from that row, etc). So by the time I'm done, say my query returns 10 rows, i'll have an array with 10 rows and 3 columns.<br />
<br />
If your query only returns 1 row, and you only need 1 field, obviously you wouldn't need an array. You could just store this value into a string variable.<br />
<br />
Something like:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>var myVariable = ri.getValue(rsmd.getColumn(1));</pre>
<br />
If you return multiple rows, you'd have to cycle through each row like I did, and build your string however you need. If you need comma delimited, you might do something like:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>
var myVariable;
while ( ri.next( ) )
{
myVariable = myVariable + "," + ri.getValue(rsmd.getColumnName(1));
}</pre>
birtprofi
@tubal
: thanks for your excellent description. I will make some tests now and come back.
Thanks a lot.
best regards
birtprofi
Hi, ok I had time to make some test and now it works nearly perfect.<br />
But there is one Problem. So I get the correct Data with this script:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>var Spalten = ri.getValue(rsmd.getColumnName(1));</pre>
the data of "Spalten" = [1,5,52,58] <br />
<br />
now I work with this script to make my new SQL (also in initialise or before factory script):<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>var i, Wert, Newsql;
Wert = Spalten;
Wert = Wert.substring(1, Wert.length - 1).split(",");
Wert.length = 10;
for (i = 0; i < 10; i += 1) {
if (Wert[i]) {
Wert[i] = "SP" + Wert[i] + " as ZE" + (i + 1);
} else {
Wert[i] = "ZE999 as SP" + (i + 1);
}
}
Newsql = Wert.join();</pre>
<br />
If I run the script above outside BIRT I get this values: SP1 as ZE1,SP5 as ZE2,SP52 as ZE3,SP58 as ZE4,ZE999 as SP5,ZE999 as SP6,ZE999 as SP7,ZE999 as SP8,ZE999 as SP9,ZE999 as SP10<br />
<br />
but if I run this within birt I get a failure:<br />
<blockquote class='ipsBlockquote' ><p>Cannot convert NaN to java.lang.Integer (/report/method[
@name="
;initialize"]#38) (Element ID:1)</p></blockquote>
<br />
The #38 =<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>Wert = Wert.substring(1, Wert.length - 1).split(",");</pre>
<br />
What can I do?<br />
best regards
Tubal
That error is saying that it's trying to use a null value as an integer.<br />
<br />
I'm not really good in javascript, but it might have something to do with:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>Wert.length = 10;</pre>
<br />
I wasn't aware this was a value you could set.
birtprofi
Hi,
no this is not the problem. I tested it also without lenght and is the same problem. I dont know why, how this script not works within birt.
Maybe Birt interprets the string as integer?
sharder
Tubal, first I want to say thanks for the great example. Secondly, I was wondering if you could help me with with your example. I am doing things slightly different. I am building the whole query in beforeFactory prior to replacing the dataset query. The initial query builds the dataset query by doing some logic on each row fetch, then I add a where clause. The issue that I am having is that it appears the query is running(progress bar), but there isn't any data shown. It shows the header and footer, but white space in between. Do you know what might be happening?<br />
<br />
<blockquote class='ipsBlockquote' data-author="'Tubal'" data-cid="99896" data-time="1335972669" data-date="02 May 2012 - 08:31 AM"><p>
One way to do it would be to connect to your db and run your first query in your report beforeFactory event, store the value returned to a global variable, and then in your dataset's beforeOpen event, replace the pertinent part of your sql statement with your global variable.<br />
<br />
So you wouldn't actually have a premade first dataset. You would do all this in script.<br />
<br />
I do something similar in the attached report. In this report, I call the database to get my column names and widths, store them in an array, and then dynamically create my table from this array. The beforeFactory event is where the database query takes place. The only difference is you would also need to fetch the parameter (ID=4) from your url before you created your dataset. You could do that with something like this:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>importPackage( Packages.javax.servlet.http );
var request = reportContext.getHttpServletRequest();
id=request.getParameter("__id");</pre></p></blockquote>
birtprofi
Hi sharder,
there are more possibilities.
-> Your query don?t return data. Try your sql query in a query tool direct on your database. Do yout get some data back?
-> Maybe the Coloum Names (Data Set Binding) of your "new" query is different.
rf
sharder
Hi birtprofi,
I figured it out, I had to create a dynamic detail row as well.
Thanks