Insert query in jasper reports - jasper-reports

Is it possible to execute "insert query" in IReports/jasper reports during report generation?

Yes, the idea you need is parameters using this syntax: $P!{PARAM_NAME}.
So your entire SQL query (or other type of query) could be simply $P!{SQL}. Then you pass in exactly the dynamic SQL that you need.
UPDATE:
After reading Sharad's comment, I realized that my answer above is not good. What I wrote is true... but it fails to address the core question.
No, your report cannot really execute an insert statement. Strictly speaking, I'm sure it's not impossible. You could add a scriptlet or custom function in a .jar file that makes a connection and does an insert. But realistically speaking... a report will execute one or more queries. The JR framework is not intended to execute inserts or updates.

Yes you can. You can execute the query when you want to display the report. Here is a sample that works for me.
try {
Map parameters = new HashMap();
connectionString ="jdbc:mysql://localhost/myDb", "myUsername", "myPassword"
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(connectionString);
PreparedStatement stmt = conn.prepareStatement(query);
ResultSet rs = stmt.executeQuery();
JRResultSetDataSource rsdt = new JRResultSetDataSource(rs);
JasperPrint jp;
jp = JasperFillManager.fillReport("sourceFileName.jasper", parameters, rsdt);
JasperViewer jv = new JasperViewer(jp, false);
jv.setVisible(true);
} catch (ClassNotFoundException | SQLException | JRException ex) {
ex.printStackTrace();
}

Related

How to get a DataAdapter for or from an existing modified strongly-typed DataSet?

I have about 10 tables that I load into a DataSet using a single DataAdapter in a sequence. During the load, I use only one DataAdapter, and I replace the table names and SELECT statements as required. I replace the table name and the SQL select statement and successively fill tables in the DataSet. Everything is done inside of two nested "using" statements to dispose of the connection and DataAdapter objects as shown below.
using (OleDbConnection conn = new OleDbConnection (Db.DbConnGet ())) {
using (var da = new OleDbDataAdapter (sql, conn)) {
tablename = "Table1";
da.SelectCommand.CommandText = $"Select * from {tablename}";
try {
da.Fill (hsdset, tablename);
} catch (Exception ex) {
...
}
tablename = "Table2";
da.SelectCommand.CommandText = $"Select * from {tablename}";
try {
da.Fill (hsdset, tablename);
} catch (Exception ex) {
...
}
}}
As you can see, the DataAdapter is disposed of once the loading is done, and I pass the DataSet around my application as necessary for reading data.
But now I have a need to update or extend the data in the dataset and get it back into the database. Updating the DataTables inside the dataset is not a problem - there are many examples on the net. I regenerated a new Connection and DataAdapter to do the update with a table in the existing, modified, strongly-typed DataSet, as follows.
using (OleDbConnection conn = new OleDbConnection (Db.DbConnGet ())) {
using (var da = new OleDbDataAdapter ("", conn)) {
// this is required; I don't know if it is used by Update
da.SelectCommand.CommandText = $"Select * from " + tablename;
try {
// build special update commands from the table->db differences
var cbuilder = new OleDbCommandBuilder (da);
da.Update (dset, "Layers");
} catch (Exception ex) {
...
}
}
}
}
My first question is, "Does the Update operation actually use the original SELECT statement to retrieve info from the database? If not, why is it required? I thought the DataSet kept track of modified rows, new rows, deleted rows, and so on. I thought updating could be done without reading the whole data table again? Or maybe it reads only the records that are marked as modified in the DataTable?
My second question is what is the best (or normal) way of working with DataSets and DataAdapters this way? Is it best practice to always save the original DataAdapters for later use, or is it good practice to create new ones like I did above? (Does the original DataAdapter keep any state information during the load that the newly-created DataAdapter would not have?) Thank you.

how to use db name as input control/parameter in jasper report

I am using jasper reports and want to give user to select the db name as input control and want to use that in query.
tool used is ireport /jasper soft studio 6.x
Got the solution for above question I used list of input control and then used the parameter value as
$P!{parametername}
Same as usage of table name as parameter/input control in jasper.
If I am understanding correctly, following code might help you.
Ofcourse "foo DB" and "baz DB" should have same tables.
Connection conn;
// Change the DB depend on input value.
if (userInput.equals("foo")){
conn = DriverManager.getConnection("jdbc:mysql://localhost/foo", "user", "password");
}
else if (userInput.equals("baz")){
conn = DriverManager.getConnection("jdbc:mysql://localhost/baz", "user", "password");
}
else{
// error
}
JasperReport jasper = (JasperReport)JRLoader.loadObject(your_jasper_filePath);
Map paramMap = new HashMap();
paramMap.put("param1", "some_param1");
paramMap.put("param2", "some_param2");
JasperPrint print = JasperFillManager.fillReport(jasper, paramMap, conn);
JasperExportManager.exportReportToPdfFile(print, PdfPath);

Getting "The SqlParameter is already contained by another SqlParameterCollection." error while using SqlQuery command

I am trying to parameterize a dynamic query and run it using SqlQuery method in Entity Framework code first.
The first time I execute SqlQuery it works as expected so I am sure there is nothing wrong with query or parameters but immediately I execute the same command with the same parameters second time and I get this error
"The SqlParameter is already contained by another SqlParameterCollection."
Since I am already using ToList() method here, I have no idea what the cause could be!
Here is the simulated code.
using (var context = Common.GetDbContext())
{
var parameters = new List<SqlParameter>();
//populating parameters here...
var sqlQuery = "Select * from MyTable where UserId=#p1 and And Active=#p2";
// first time
var result = context.Database.SqlQuery<ResultType>(sqlQuery, parameters.ToArray()).ToList();
//second time
result = context.Database.SqlQuery<ResultType>(sqlQuery, parameters.ToArray()).ToList();
}
Any idea?
Hi SqlParameter is clonable. Try this:
result = context.Database.SqlQuery<ResultType>(sqlQuery, parameters.Select(x => x.Clone()).ToArray()).ToList();
See https://msdn.microsoft.com/en-us/library/vstudio/bb338957%28v=vs.100%29.aspx

Getting 3 mins to Generate the Jasper Report

I am developing the Invoice printing System using the Jasper report, Now I have can print the report but it will take 2000ms to load the report, also 2000ms take to start the printing,
These are I am using the JAR FILES,
commons-beanutils-1.4
commons-digester-1.7
commons-logging-1.0.3
commons-beanutils-1.4
groovy-all-1.7.5
batik-all-1.7
barcode4j-2.1
itextpdf-5.1.0
jasperreports-6.0.3
xercesImpl-2.11.0
xml-apis-ext-1.3.04
preparedStatement = conn.prepareStatement(sqlString);
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
HashMap<String, Object> hm = new HashMap<>();
JasperDesign jasperDesign = JRXmlLoader.load(new File(
"C:/Invoice/Invoice.jrxml"));
JRDesignQuery designQuery = new JRDesignQuery();
designQuery.setText(sqlString);
jasperDesign.setQuery(designQuery);
JasperReport jasperReport = JasperCompileManager
.compileReport(jasperDesign);
JasperPrint jasperPrint = JasperFillManager.fillReport(
jasperReport, null, conn);
for (int i = 0; i < copies; i++) {
JasperPrintManager.printReport(jasperPrint, false);
}
JasperViewer.viewReport(jasperPrint);
The above code I used to print the report but, getting too much time to load the report. Please suggest my fault and some other idea...
I guess the SQL query could be the problem. Have you tried executing it in a sql query tool and check how long it runs? Optimizing it should yield a performance win.
You are also running the query twice: before the report and when you are filling it via the JasperFillManager.fillReport() call.
If there are no specific reasons to check wheter the query contains any records, I would recommand to let JasperReports handle the query and the case that no record is found. You can determine a specific behaviour in that case via the "When No Data Type" property in the reportdesign.

App hangs when executing the query in prepared statement

I am trying to select rows which are older than 7 days from current date. Database used is DB2 version 9.
Can you please tell me how exactly can I use the datetime in the query? The date table field is of type timestamp.
I am able to manually run the query without issues. However, when I am using in the prepared statement,
The app hangs when executing the query result = pselect.executeQuery(); as a result of which we need to restart db2 instance in order to clear it.
Can you please help what might be the issue? I do not see any exceptions at all. Other parts of the code works fine if I remove the select_query part.
try{
String select_query = "SELECT URL_ID ,URLVAL FROM URL_TAB WHERE " +
"UPDATED_DATE < TIMESTAMP(CURRENT_DATE - 7 DAYS, '00.00.00')";
System.out.println("select_query=" + select_query);
conn = JDBCDataObjectFactoryManager
.getConnection("JDBCConnectionFactory-SDE");
pselect = conn.prepareStatement(select_query);
System.out.println("pselect=" + pselect);
try{
System.out.println("inside try");
result = pselect.executeQuery();
System.out.println("result=" + result);
}catch(Exception e){
System.out.println("inside catch");
System.out.println("error message==============>"+e.getMessage());
}
if ((result != null) && (result.next())) {
System.out.println("3 >>>>>>>>>>>>>>>>>>>>>>>>>");
url_id = result.getInt(1);
url = result.getString(2);
}//end if
There are two possibilities: either the query is in a lock wait, or it runs for so long that it appears to be hung.
Check what is the value of LOCKWAIT database configuration parameter --by default it is -1, which means infinity, and you normally want to set it to a more reasonable value, typically 30 or 60 seconds. If it is the lock wait that causes your application to "hang", you would get an exception instead, which will help you to debug further.
If the issue is caused by the poor query performance, you'll need to work with your DBAs to figure out the root cause and resolve it.