Jasper Reports Fill Parameters in SQL Query - java

I have a web application which generates reports based off an SQL query. These SQL queries have Jasper Report parameters (i.e. $P{Param}).
In my Java code, I'm using PreparedStatement to execute the query and return a result set. I use this result set and change it into a JRResultSetDataSource to pass into JasperFillManager.fillReport(JasperReport, parameters, dataSource).
The reason I'm using a data source and not a connection is so that I can use setQueryTimeout on my PreparedStatement.
My problem is that I need a way to fill in the query's parameters with the parameter map values. Is there a built in way to do this?
Ex.
rawSqlString = "SELECT * FROM TABLE WHERE ROW1 = $P{Param}";
filledSqlString = somefunction(sqlString);
ResultSet rs = sqlStatement.executeQuery(filledSqlString);
I can't use the "rawSqlString" since it has $P{Param}.
Alternatively, is there a type of datasource which simply stores the unfilled SQL query which I can pass to JasperFillManager?
Normally JasperFillManager handles this but I want my query to timeout, so I need to use setQueryTimeout, and somehow convert this into a format Jasper can handle.

Related

Query returning sql string with wrong parameters

I am currently working on fixing some SQL injection bugs in my project.
Here is my current sql string:
String sql = "select * from :table order by storenum";
Here is how I am setting the parameters:
SQLQuery query = sess.createSQLQuery(sql).setParameter("table", table);
(table is a string that is passed in through a method)
Whenever I run the program I get something like this:
select * from ? order by storenum
You can't dynamically bind table names, only values, so you'll have to resort to string manipulation/concatenation to get the table name dynamically. However, you would probably want to escape it to avoid SQL Injections.

jOOQ problems with limit..offset - no values sets

I am trying to build a query using jOOQ, this is my test code:
DSLContext create = DSL.using(SQLDialect.DERBY);
String query = create.select().from(TABLE).limit(1).offset(0).getSQL()
I get as query:
select field1, field2...fieldN etc from TABLE offset ? rows fetch next ? rows only
the problem is ? in ? rows fetch next ? rows only it seems to ignore the values that i used in limit and offset to build the query, why?
I am trying to select the first row from the results and I am using jooq 3.4.1
Thanks for the help
Query.getSQL() returns your SQL string with ? as placeholders for your bind variables. The idea is that you can feed this statement to a PreparedStatement and then explicitly bind all variables, which are available through Query.getBindValues().
You can also have jOOQ inline all your bind variables, by calling Query.getSQL(ParamType) as such:
String sql = query.getSQL(ParamType.INLINED);

How to create sqlite prepared statement in OrmLite?

Is it possible to create a sqlite prepared statement in OrmLite?
If so, how to bind the query values which may change across different queries.
Is it possible to create a sqlite prepared statement in OrmLite?
You need to RTFM since ORMLite's online documentation is pretty extensive. If you look in the index for "prepared statement" you find out about the QueryBuilder which #Egor pointed out.
how to bind the query values which may change across different queries.
A little further in that section you learn about select arguments which is how you bind query values that change across queries. This is in the index under "arguments to queries".
To quote from the docs here's how you prepare a custom query:
QueryBuilder<Account, String> queryBuilder = dao.queryBuilder();
Where<Account, String> where = queryBuilder.where();
SelectArg selectArg = new SelectArg();
// define our query as 'name = ?'
where.eq("name", selectArg);
// prepare it so it is ready for later query or iterator calls
PreparedQuery<Account> preparedQuery = queryBuilder.prepare();
When you are ready to run the query you set the select argument and issue the query:
selectArg.setValue("foo");
List<Account> accounts = dao.query(preparedQuery);
Later, you can set the select argument to another value and re-run the query:
selectArg.setValue("bar");
accounts = accountDao.query(preparedQuery);

Error with simple Parameterized Query - Java/ SQL

Following on from one of my previous questions to do with method design I was advised to implemented my SQL queries as a parameterized query as opposed to a simple string.
I've never used parameterized queries before so I decided to start with something simple, take the following Select statement:
String select = "SELECT * FROM ? ";
PreparedStatement ps = connection.prepareStatement(select);
ps.setString(1, "person");
This gives me the following error: "[SQLITE_ERROR] SQL error or missing database (near "?": syntax error)"
I then tried a modified version which has additional criteria;
String select = "SELECT id FROM person WHERE name = ? ";
PreparedStatement ps = connection.prepareStatement(select);
ps.setString(1, "Yui");
This version works fine, in the my first example am I missing the point of parameterized queries or am I constructing them incorrectly?
Thanks!
Simply put, SQL binds can't bind tables, only where clause values. There are some under-the-hood technical reasons for this related to "compiling" prepared SQL statements. In general, parameterized queries was designed to make SQL more secure by preventing SQL injection and it had a side benefit of making queries more "modular" as well but not to the extent of being able to dynamically set a table name (since it's assumed you already know what the table is going to be).
If you want all rows from PERSON table, here is what you should do:
String select = "SELECT * FROM person";
PreparedStatement ps = connection.prepareStatement(select);
Variable binding does not dynamically bind table names as others mentioned above.
If you have the table name coming in to your method as a variable, you may construct the whole query as below:
String select = "SELECT * FROM " + varTableName;
PreparedStatement ps = connection.prepareStatement(select);
Parameterized queries are for querying field names - not the table name!
Prepared statements are still SQL and need to be constructed with the appropriate where clause; i.e. where x = y. One of their advantages is they are parsed by the RDMS when first seen, rather than every time they are sent, which speeds up subsequent executions of the same query with different bind values.

Passing parameters to JasperReports SQLl statement from Java

I'm using JasperReports engine, and one of the reports gets data from database executing SQL statement. Is there a way to pass parameters to that query?
Thanks in advance!
First, create a new parameter in your report. Then insert the parameter in your query, for example:
SELECT name, department FROM employees WHERE employee_id = $P{employeeId}
Make sure your parameter types matches the data type of the columns in your database. Finally, simply pass your parameters to the JasperReports engine. An example would be:
parameters.put("employeeId", Long.valueOf(14309));
JasperRunManager.runReportToPdf(reportFile, parameters, connection);

Categories

Resources