Jasper Reports is unable to call Oracle stored procedures directly, because procedures do not return standard result sets. As a solution, in Oracle, you can use a stored function to retrieve the results of a stored procedure. There are a few more steps to do this than if you were able to use a stored procedure, but it currently is the only option, if the query you need to do can’t be done with a standard SQL query.
In order to to use stored functions to retrieve the result set of a stored procedure, you will need to use a temp table to hold the results, and then return the results using types and tables of types.
Note: In this example, I have kept the function very limited. This particular query would not need to be done with a stored procedure and function, as a standard select query would be best, but is only used to demonstrated how to do it, should the need arise.
I have provided all the sql used in this demo, in this file.
Setup
For this example, the table Presidents will be used. Sample data will also need to be loaded into the table. You can use the file I provided above, with all the example’s sql to create the table and load it with sample data.
Now that there is a base table and data to work with, creation of the objects needed for the stored function can begin.
Step 1: Create a Temp Table
First, create a temp table to temporarily hold the results from the stored procedure, so the Jasper Report can query it via the stored function, with a standard select query. To create the temp table, use this sql:
CREATE GLOBAL TEMPORARY TABLE "TEMP_PRESIDENTS" ( ID NUMBER(10) not null, NAME VARCHAR(32) not null, BIRTHDATE DATE not null, PARTY char(1) not null ) ON COMMIT PRESERVE ROWS
Step 2: Create the Stored Procedure
Next, create the stored procedure which will perform the needed data gathering. In this simple example, the query will select all rows based on the party passed (R for republican, D for democrat).
CREATE PROCEDURE "LOAD_TEMP_PRESIDENTS" ( partyParam CHAR ) as begin EXECUTE IMMEDIATE 'TRUNCATE TABLE TEMP_PRESIDENTS'; COMMIT; INSERT INTO TEMP_PRESIDENTS SELECT ID, NAME, BIRTHDATE, PARTY FROM PRESIDENTS WHERE PARTY = partyParam; COMMIT; end;
Step 3: Test the Stored Procedure
Before proceeding any further, call the stored procedure and then check the temp table to be sure it behaves properly (sql below). You should get a result of all the Democrat Presidents, four of them. If not, you will need to retrace your steps.
call LOAD_TEMP_PRESIDENTS('D');
select * from TEMP_PRESIDENTS;
Step 4: Create the Return Type
This step creates the type that will be used to return the results from the temp table. This type should describe the result set you are expecting in the Jasper Report.
CREATE OR REPLACE TYPE "PRESIDENT_TYPE" AS OBJECT ( ID NUMBER(10), NAME VARCHAR2(32), BIRTHDATE DATE, PARTY CHAR(1) )
Step 5: Create a Table of the Type
In this step we create a table of the type we created in the previous step. This “table†is what we will be selecting from in the Jasper Report. It is not a real table, but instead a type or object representing the structure of the table that we will funnel the stored procedures results through.
CREATE OR REPLACE TYPE "PRESIDENT_TYPE_TABLE" AS TABLE OF "PRESIDENT_TYPE"
Step 6: Create the Stored Function
The next step is to create the stored function with the following code, to retrieve all the presidents for the party you select (R or D).
CREATE OR REPLACE FUNCTION "PRESIDENTS_FUNC" ( partyParam CHAR ) return PRESIDENT_TYPE_TABLE pipelined is PRAGMA AUTONOMOUS_TRANSACTION; TYPE ref0 is REF CURSOR; myCursor ref0; out_rec PRESIDENT_TYPE := PRESIDENT_TYPE(0, null, null, null); BEGIN LOAD_TEMP_PRESIDENTS(partyParam); open myCursor for select id, name, birthdate, party from TEMP_PRESIDENTS; LOOP FETCH myCursor into out_rec.ID, out_rec.NAME, out_rec.BIRTHDATE, out_rec.PARTY; EXIT WHEN myCursor%NOTFOUND; PIPE ROW(out_rec); END LOOP; CLOSE myCursor; RETURN; END;
Step 7: Testing and Using the Stored Function
In order to use the stored function you execute the code below:
select * from table(PRESIDENTS_FUNC('D'))
This code can now be used within a Jasper Report, as you have turned a stored procedure into a stored function accessible with a standard select. To the Jasper Report you are merely issuing a standard query.
Comment
Subscribe
Stumble
Previous
36 Responses to How to call Stored Procedures from JasperReports
Barry Klawans
August 23rd, 2006 at 3:14 pm
Hi Brian,
I just wanted to let you and your readers know that I just created a custom JasperReports query executer that supports PL/SQL stored procedures natively, so you can access the results of a stored procedure via a cursor without creating a temp table first.
You can grab the sample implementation on JasperForge – go to http://www.jasperforge.org, click on the Developer Forge tab, and the list of public projects includes one called “OracleStoredProcedures”. You can download the source and a sample report.
-Barry
Ravi Vedala
September 11th, 2006 at 4:47 pm
Hi Barry,
Can you give the same example for using the jasper reports ? My scenario is like this :
I have a function that returns a cursor from PL/SQL. I want to export the results of the function as XLS.
Thanks,
r-a-v-i
Nuruthin Ahammed
October 8th, 2006 at 2:29 am
Brian,
Open report does not support Oracle Stored procedure. We need to customize open report portal to support the stored procedure.
AKG
October 23rd, 2006 at 4:22 pm
One can write, in Oracle 9i and later, pl/sql functions that return a table. Check on table functions and pl/sql on Google.
Once you have this function you can code your sql in JasperReports thus
select col1, col2, col3 from table(my_func(param1, param2))
This is 1 of the most useful but underutilized Oracle pl/sql feature – you can have the most complicated logic inside the pl/sql but for the clients it is just a simple select.
Brian Burridge
October 24th, 2006 at 4:01 pm
AKG,
What you are describing is exactly what this tutorial demonstrated. That is, creating a stored function that returns a table.
Francisco Gomes
October 30th, 2006 at 10:44 am
I thank you people for opening this perspective which is new for me, of calling a function from within a Jasper Report.
I tested the method and it works fine.
But have anyone tried to make a call like :
select col1, col2, col3 from table(my_func($P{param1}, $P{param2})).
Is there any way to do this ?
Brian Burridge
October 30th, 2006 at 2:14 pm
Yes you can send parameters to the function put you must use $P!{paramname}, with the exclamation point.
Francisco Gomes
October 31st, 2006 at 2:40 am
Thank you for this nice step forward.
raj
May 3rd, 2007 at 5:35 am
nice idea
Leda Novatzki
May 25th, 2007 at 3:30 pm
Brian,
I tested the method and it works fine and I used parameters in function. So, I need use now a subreport with result my function and my subreport use stored procedure too. How can I do this?
My function:
select col1, col2, col3 from table(my_func($P{param1}, $P{param2})).
My subreport:
select * from table_subreport(my_func2($P!{col1))
Where:
col1 : field Result from my first select
Thanks
Oracle Guy
September 30th, 2007 at 7:05 pm
Use of autonomous transaction, global temporary table and refcursor unnecessary in this example.
CREATE OR REPLACE FUNCTION “PRESIDENTS_FUNC†(
partyParam CHAR
)
return PRESIDENT_TYPE_TABLE pipelined
is
out_rec PRESIDENT_TYPE := PRESIDENT_TYPE(0, null, null, null);
FOR out_rec IN (
SELECT ID, NAME, BIRTHDATE, PARTY FROM PRESIDENTS WHERE PARTY = partyParam)
LOOP
out_rec.ID,
out_rec.NAME,
out_rec.BIRTHDATE,
out_rec.PARTY;
PIPE ROW(out_rec);
END LOOP;
RETURN;
END;
Annie He
November 26th, 2007 at 6:36 pm
Hi,
Your codes for oracle are very helpful and clear about how to create and call stored procedure. Is this just for the oracle database? What are the syntax differences in the code between Sybse and oracle? If there are some differences, would you please give me all the information in Sybase?
Thanks,
Annie
Annie He
November 27th, 2007 at 12:30 pm
Hi,
I got all the codes in Oracle. May I have all the codes work in Sybase?
Thanks,
Annie
tom Gaderer
January 2nd, 2008 at 2:31 pm
Hi Brian, I have done all steps you decribed, and the stored function works corretly in sql. but in jasper-report I get the following error-message:
Fehler beim Füllen… Error executing SQL statement for : bauspora
net.sf.jasperreports.engine.JRException: Error executing SQL statement for : bauspora     at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:141)     at net.sf.jasperreports.engine.fill.JRFillDataset.createQueryDatasource(JRFillDataset.java:682)     at net.sf.jasperreports.engine.fill.JRFillDataset.initDatasource(JRFillDataset.java:614)     at net.sf.jasperreports.engine.fill.JRBaseFiller.setParameters(JRBaseFiller.java:1198)     at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:842)     at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:795)     at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:63)     at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:402)     at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:234)     at it.businesslogic.ireport.IReportCompiler.run(IReportCompiler.java:943)     at java.lang.Thread.run(Thread.java:595) Caused by: java.sql.SQLException: ORA-00906: missing left parenthesis      at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)     at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)     at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:582)     at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1986)     at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1144)     at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2152)     at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2035)     at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2876)     at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:609)     at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:537)     at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:135)     … 10 moreÂ
Report wurde nicht gefüllt. Versuchen Sie es mit einer leeren Datenquelle…
and this is my query:
select ans_1
,ans_2
,ans_3
,ans_4
,ans_5
,ans_6
from table(bsp_FUNC)
I hope anyone can help me
Thanks
TOM
René B.
March 27th, 2008 at 7:35 pm
OK… all right but and this….
http://www.jasperforge.org/sf/projects/oraclestoredprocedures#news
What do you have to say?
Agreed previous link, is possible to call oracle stored procedures from iReport of JasperSoft. How is possible that?
email me!!!
René B.
March 27th, 2008 at 7:39 pm
renebpr@gmail.com
Brian Burridge
March 29th, 2008 at 2:08 pm
René B,
It’s nice to see that iReport has added that functionality. Would have been nice to have that two years ago when I needed it!
Dipankar Das
June 28th, 2008 at 6:51 am
Hi, Your code is really helpful for the beginners for Jasper report like me. But I need a help from you . I want to know how I can pass a parameters into the sql query.
My query is :
select * from table(partha_TYPE(‘01/01/2007′,’01/01/2009′)) – was running fine
But I had created two parameters and change the query as
select * from table(partha_TYPE($P{StartDate},$P{EndDate}))
.
After I have executed the report it gives me the error as follows “java.sql.SQLException: ORA-22905: cannot access rows from a non-nested table item “. Can you please help me to solve this?
Thanks in advance.
abhinav
July 31st, 2008 at 12:11 am
hi all,
how we pass a collection object in function
.
Mahi
August 22nd, 2008 at 6:05 am
select * from table(EMPID(2009) – was running fine
But I had created two parameters and change the query as
select * from table(empid($P{emmpid}))
.
After I have executed the report it gives me the error as follows “java.sql.SQLException: ORA-22905: cannot access rows from a non-nested table item “.
Could anybody help how to sove this ???
Regards
Mahi
Ajith
October 1st, 2008 at 12:37 am
Hi Brian,
Will a similar solution(mentioned in this article for Oracle) work for DB2 procedures ?
Has anybody been successful in running DB2 procedures successfully from Jasper Reports or iReport. If yes, please help me by giving some pointers to the solution.
Thanks in advance
Ajith
Max
October 1st, 2008 at 10:19 am
Hi Mahi,
in iReport, try to used
select * from table(cast(your_stored_function($P{emmpid})) as your_type_table ))
Regards
Max
Shadow
October 7th, 2008 at 6:04 am
Hi ,
Great Article!!!!!!
I am new bie to Jasper reports, I want to know How to integrate with MYSQL Stored procedure.
Any Help will be greatly appreciated.
thanks in Advance.
Shadow.
Faris Zuriekat
October 9th, 2008 at 11:45 am
The usage of Oracle Store Procedure is optional , you can perform similar operation in function itself
Deepa
January 22nd, 2009 at 7:51 am
Can anyone help me for accessing image image stored in the MS-Access db from jasper reports
here’s my jrxml file
thanks in advance
Dave
January 23rd, 2009 at 11:26 am
I have an Oracle function that takes as it’s arguments 2 oracle.sql.ARRAY objects and a Date objects. I am trying to find information on how to pass the function an array. Does anyone have any experience passing an array from JasperReports to an Oracle function? Specifically I would like to define the array parameters in the report using iReports and then when the report is run via JasperServer, have it prompt the user for the values in the arrays.
Deepa
January 24th, 2009 at 12:53 pm
I am trying to access image stored in the form of OLE object in MS-access db and image exp in jasper report is as follows-
when i am trying to run this jasper report in ireport it is throwing an exception at filling time
Error filling print… Error evaluating expression :     Source text : JRImageLoader.loadImage(((byte[])$F{picture}))
net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression :     Source text : JRImageLoader.loadImage(((byte[])$F{picture}))     at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:197)     at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:537)     at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:505)     at net.sf.jasperreports.engine.fill.JRFillElement.evaluateExpression(JRFillElement.java:826)     at net.sf.jasperreports.engine.fill.JRFillImage.evaluateImage(JRFillImage.java:890)     at net.sf.jasperreports.engine.fill.JRFillImage.evaluate(JRFillImage.java:871)     at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:275)     at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:426)     at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand(JRVerticalFiller.java:1380)     at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:692)     at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:255)     at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:113)     at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:879)     at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:782)     at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:63)     at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:402)     at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:234)     at it.businesslogic.ireport.IReportCompiler.run(IReportCompiler.java:947)     at java.lang.Thread.run(Unknown Source) Caused by: net.sf.jasperreports.engine.JRException: Image read failed.     at net.sf.jasperreports.engine.util.JRJdk14ImageReader.readImage(JRJdk14ImageReader.java:77)     at net.sf.jasperreports.engine.util.JRImageLoader.loadImage(JRImageLoader.java:274)     at classic_1232815871906_748933.evaluate(classic_1232815871906_748933:182)     at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:186)     … 18 moreÂ
Print was not filled. Try using an EmptyDataSource…
Can anyone help me to solve this problem..
Thanks in advance
Praveen
March 4th, 2009 at 4:52 pm
I am abale to run db2 procedure using iReport. But not with Jasper reports/Java. Let me know
If any one able to do call jasper report using stored procedure query.
Thanks
Praveen
Praveen
March 4th, 2009 at 5:20 pm
Ajith,
Following is the code to run the procedure/sql from Jasper Reports.
/**
* Takes 1 parameters: reportFileLocation
* connects to the database and prepares and views the report.
* @param reportFile holds the location of the Jasper Report file (.jrxml)
*/
public void runReport(String reportFile) throws SQLException
{
try
{
System.out.print(“Loading report”);
JasperDesign jasperDesign = JRXmlLoader.load(reportFile);
System.out.print(“Compiling report2″);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
Connection jdbcConnection = getConnection();
Map parameters = new HashMap();
parameters.put(“storeNo”,260);
System.out.print(“Filling report”);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, jdbcConnection);
byte[] bytes = JasperRunManager.runReportToPdf(jasperReport, parameters, jdbcConnection);
JasperExportManager.exportReportToPdfFile(jasperPrint, “simple_report.pdf”);
//JasperExportManager.exportReportToPdfFile(jasperPrint, “TEST.pdf”);
System.out.print(“View report”);
JasperViewer.viewReport(jasperPrint);
System.out.print(“Done report”);
}
catch(Exception ex)
{
ex.printStackTrace();
String connectMsg = “Could not create the report ” + ex.getMessage() + ” ” + ex.getLocalizedMessage();
System.out.println(connectMsg);
}
}
marco
March 11th, 2009 at 11:30 am
Is it possible use this solution with a multiple call to a different function? Example:
select * from
table(report_r2a_02($P{a},$P!{b})),
table(report_r2a_03($P{a},$P!{b}))
?? It doesn’t work! Error: ORA-6553:PLS-306
jigar
January 29th, 2010 at 1:35 am
Gr8 explanation
jigar
January 29th, 2010 at 1:35 am
Can anyone provide how to change the height and width of report element dynamically.
Code if any appreciated
jigar
January 29th, 2010 at 1:36 am
Hi Brian,
Can i Have some idea or code to pass oracle array to stored function
igwrite
January 29th, 2010 at 1:36 am
Folks,
Do you know how to create the same report but without pipelined function?
We are using enterpriseDB. There is no such option as pipelined out there.
Thank you in advance!
Kuhin
January 29th, 2010 at 1:37 am
Brian,
I tested the method of stored procesdure by passing parameter within a function and it is not working for me. If I hard code the parameter values in the function and call within the query it returns my values. Help please!
My Oracle stored procedure function:
my_data(param1, param2, param3, param4, param5, param6);
My query in iReport:
select * from table(my_data($P{param1}, $P{param2}, $P{param3}, $P{param4}, $P{param5}, $P{param6}))
iReport Error:
Error: SQL problems:ORA-06553:PLS-306:wrong number or types of arguments in call to ‘my_data’
Thanks
Kuhin
faizan
March 11th, 2010 at 6:34 am
While doing this:
call LOAD_TEMP_PRESIDENTS(‘D’);
i got the error this:
ORA-00911: invalid character
i am using oraclexe plz help me out plz plz