How can handle reserved character in SQL query - java

I want to read data from a table but I got a error because the value I want to compare may contain a word like this: abcd l'jdmd
I try it like this:
String s = "select ref(ad) from adresse_tab ad where ad.ort='"+rs.getString(11)+"' and ad.plz='"+rs.getString(13)+"' and ad.land='"+rs.getString(14)+"'";
PreparedStatement stmt5 = nsdCon.prepareStatement(s);
ResultSet rs5 = stmt5.executeQuery();
The query could look like this:
select ref(ad)
from adresse_tab ad
where ad.ort='Frankfurt am Main'
and ad.plz='65301'
and ad.land='Deutschland'
and ad.strasse='almundo l'tare '
So the problem in this query is this comparison:
ad.strasse='almundo l'tare '
How can I handle reserved character in SQL query?

Please avoid creating a SQL query with supplied parameters using string concatenation. Instead you can continue using PreparedStatement, but use placeholders for the actual param values, and use the statement's set<X>() methods for setting params. Here's official Oracle docs on this.
You must supply values in place of the question mark placeholders (if
there are any) before you can execute a PreparedStatement object. Do
this by calling one of the setter methods defined in the
PreparedStatement class. The following statements supply the two
question mark placeholders in the PreparedStatement named updateSales:
updateSales.setInt(1, e.getValue().intValue());
updateSales.setString(2, e.getKey()); The first argument for each of
these setter methods specifies the question mark placeholder. In this
example, setInt specifies the first placeholder and setString
specifies the second placeholder.
For your case:
String s = "select ref(ad) from adresse_tab ad where ad.ort=? and ad.plz=? and ad.land=?";
PreparedStatement stmt5 = nsdCon.prepareStatement(s);
stmt5.setString(1, rs.getString(11));
... and so on

Use a prepared statement (and for added clarity of named bind variables you can use an OraclePreparedStatement):
String s = "select ref(ad) from adresse_tab ad where ad.ort=:ort and ad.plz=:plz and ad.land=:land";
PreparedStatement st5 = nsdCon.prepareStatement(s);
OraclePreparedStatement ost5 = (OraclePreparedStatement) st5;
ost5.setStringAtName("ort",rs.getString(11))
ost5.setStringAtName("plz",rs.getString(13))
ost5.setStringAtName("land",rs.getString(14))
ResultSet rs5 = st5.executeQuery();

You should not add your query parameters directly to the query string. Use a Prepared Statement instead and pass the query parameters there. See also Does the preparedStatement avoid SQL injection?

The whole point of prepared statements is to use parameters within your query so values can be automatically escaped:
String s = "select ref(ad) from adresse_tab ad where ad.ort=? and ad.plz=? and ad.land=?";
PreparedStatement stmt5 = nsdCon.prepareStatement(s);
stmt5.setString(1, rs.getString(11));
stmt5.setString(2, rs.getString(13));
stmt5.setString(3, rs.getString(14));
ResultSet rs5 = stmt5.executeQuery();

ad.strasse='almundo l'''tare '

Related

How to replace table name in sql query with regex in Java?

I want to replace table name in a sql query string. I only want to change table name. How can I do that in java with regex?
I do not want to use any dependencies.
For example,
Input:
select ... from table1 where/etc ....
expected output:
select ... from UPDATED_TABLE_NAME where/etc ....
If you mutate the query explicitly you open yourself to SQL injection. What you could do is use a PreparedStatement with a parameterized query to provide the table name safely.
try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM ?")) {
statement.setString(1, "my_table");
try (ResultSet results = statement.executeQuery()) {
}
}
If you're insistent on using regex you can just use the query above and replace ? with the table name. I would not do this in a production environment.
String query = "SELECT * FROM ?";
String queryWithTable = query.replaceAll("?", "my_table");

Passing BIT in query as a parameter in Prepared Statement

I want to pass a bit as one of the parameters in Prepared Statement. My query should look like this :
query = select * from tbl_security_details('user',O::BIT)
I am framing the query as :
query = select * from tbl_security_details(?,?)
PreparedStatement ps = connection.prepareStatement(query);
ps.setString(1,"user")
ps.setString(2,"0::BIT")
However, this throws an error.
Can someone explain how I can pass 0::BIT from the prepare statement without it appending the single quote by itself and getting converted to String ?
Write the prepared statement so that the cast is part of the query:
String query = "select * from tbl_security_details(?, ?::bit)";
java.sql.PreparedStatement ps = connection.prepareStatement(query);
ps.setString(1, "user");
ps.setString(2, "0");
That is necessary, because you can only pass a constant value to the prepared statement, not an SQL expression.

why we use setInt with select query instead of using getInt when value is already there in database

why we use setInt with select query instead of using getInt when value is already there in database?
try {
conn = getConnection();
ps = conn.prepareStatement("SELECT * FROM circle where id =?");
ps.setInt(1, circleId);
Circle circle = null;
rs = ps.executeQuery();
if (rs.next()) {
//String s = rs.getString(circleId);
circle = new Circle(circleId, rs.getString("name"));
}
You're setting the value of the parameter to be used in the query. The ? in the SQL represents the parameter, and here you're giving it a value.
When you call getString() later, that's getting a value from the results of the query, which are very different from the parameters sent as part of the query.
Parameterized SQL allows safe inclusion of values into queries, without needing to escape them to prevent SQL injection attacks, or worrying about data type conversions. You should read the JDBC PreparedStatement tutorial for more details.

Prepared statement with quotes in query

I was writing a prepared statement and for the table name I passed user obtained variable string.
So this works,
String m_table_variable = "blah"; // get from request object
PreparedStatement ps = conn.prepareStatement("select * from "+m_table_variable+"");
While this does not,
PreparedStatement ps = conn.prepareStatement("select * from '+m_table_variable+'")
What triviality am I missing here?
PreparedStatement ps = conn.prepareStatement("select * from " +m_table_variable)
try this
of course if the m_table_variable is a String with name of a table
Your problem is quite straight forward, the first example concatenates three Strings namely "select * from ", "blah" and "" together.
The second example uses one String which literally is "select * from '+m_table_variable+'" and the variable is not concatenated to the final String. Personally I wouldn't dynamically allow the table name to be injected into the SQL statement, read up on SQL injection.
Your first one will not even compile, you need to use \" to insert a quote into a string literal.
You need to escape " from String using \, otherwise it will not compile.
PreparedStatement ps
= conn.prepareStatement("select * from \"m_table_variable\"");

Sql query with bind variables execution in Jdbc

I have a sql query like this.
select "DEPT"."DEPTNO" as "DEPTNO1",
"DEPT"."DNAME" as "DNAME1",
"DEPT"."LOC" as "LOC1",
"EMP"."COMM" as "COMM1",
"EMP"."EMPNO" as "EMPNO1",
"EMP"."ENAME" as "ENAME1",
"EMP"."HIREDATE" as "HIREDATE1",
"EMP"."JOB" as "JOB1",
"EMP"."MGR" as "MGR1",
"EMP"."SAL" as "SAL1"
from "EMP" , "DEPT" where "DEPT"."DEPTNO" in (:DeptNo)
//This is the Jdbc code
Class.forName(DB_DRIVER);
dbConnection = DriverManager.getConnection(DB_CONNECTION, DB_USER, DB_PASSWORD);
Statement statment = dbConnection.createStatement();
result = statment.execute(query);//query is above sql query
When i run above query in Oracle sql developer works perfectly.But when i run it with above jdbc code it is throwing Not all variables bound exception.
How to run above query in JDBC
replace :deptno in your query with a ?.
and instead of instantiating statement use the following:
PreparedStatement stmt=con.prepareStatement(query);
stmt.setInt(1,deptno); //1 is for the first question mark
where deptno holds the value for which you want to execute the query.
Through PrepredStatement interface we can use parametrized query which is compiled only once and has performance advantage in comparison to the Statement interface.
You created a Query with bind variable and you never set it.
Use OraclePreparedStatement and its method setStringAtName()
statement.setStringAtName("DeptNo","<<your Value>>");
If not OraclePreparedStatement, you can just put it as ?1 in your Query string
and use,
statement.setString(1,"<<your Value>>");
If in case, you don't know how many bind variables you get, you have capture the bind variables in a map and prepare a list and set it accordingly!
Else your requirement is unachievable!
Get the query dynamically from the report.
From this query we need to split querystring to get number of bind variables and placing those bind variables in a HashMap.HashMap is like
{DeptName =1, Job =1, DeptNo =1}
From this hashmap,need to replace the query bind variable with ?.For this we need to do like
bindkey = entry1.getKey().toString();
String bindkeyreplace =":".concat(bindkey).trim();
String bindkeyreplacestring = "?";
query = query.replace(bindkeyreplace, bindkeyreplacestring);
Then we will get dynamic query coming from the report with ? instead of :bindvariable
PreparedStatement prestmt = dbConnection.prepareStatement(query);
for (int i = 0; i < bindParamMap.size(); i++) {
prestmt.setInt(i + 1, 0);//Setting default value to check the query is running successfully or not
}
result = prestmt.execute();
If in case, we don't know how many bind variables we get then this approach is running successfully for me.
Use this syntax,EMP.DNAME as DNAME1. I mean your dot and as must be inside the double quotes.
The variable DeptNo must be bound to a value before you execute the statement like below.
DriverManager.getConnection(DB_CONNECTION, DB_USER, DB_PASSWORD);
Statement statment = dbConnection.createStatement();
//Bind deptno to a value
statment.setParameter("DeptNo",5);
result = statment.execute(query);
You must set values for all the variables in your prepared statement othwerise you cannot execute the statement. If you receive the query to execute itself as an input then you should also get the parameters and its values also as input. Something like below
public <returnType> executeQuery(String queryStr, Map<String,Object> params) {
//Code to create connecitno and statment from queryStr.
//Bind deptno to a value
for(int i=0;i<params.size(),i++) {
//Get entry set from map
statment.setParameter(entryset.getKey(),entryset.getValue());
}
result = statment.execute(query);
//return or work on the result
}

Categories

Resources