I am trying to select some values in my table but when Invoicedate is null I got exception please help me!
my code :
query="select vend_name,vend_no from account where inv_date = '"+Invoicedate+"' or vend_no = "+Vendorno+" LIMIT 500";
please give any possible answer to me.
That's because in your code it will become inv_date = 'null' not inv_date is null.
You need to do inv_date "+(Invoiceddate==null?"is null":"= '"+Invoiceddate+"'")+" or
In general this is a bad way to do things though as you are open to SQL injection attacks and all sorts of other similar problems.
Use a PreparedStatement and all this will be handled for you:
PreparedStatement query = connection.prepareStatement("select vend_name,vend_no from account where inv_date = ? or vend_no = ? LIMIT ?");
query.setDate(1, Invoicedate);
... etc
Note also that you should follow the Java style conventions in variable naming etc, it will help people work with your code.
Related
I have a requirement. The technology is quite old doesn't support spring at all . It is pure java application with jdbc connection.
Requirement is :
Suppose
select * from employee where empid = <<empid>> and designation = 'Doctor'
I am trying to replace <> with actual int value in java . How I can do it ?
String query = "select * from employee where empid = <<empid>> and designation = 'Doctor'";
if(query.contains("<<empid>>"))
/// Here I want to replace <<empid>> with actual int value in java
Any leads will be helpful
The code you didn't paste, that actually executes the SQL is either [A] a massive security leak that needs serious rewrites, or [B] is using PreparedStatement.
Here's the problem: SQL injection. Creating the SQL string by mixing a template or a bunch of string constants together with a bunch of user input is a security leak. For example, if you try to make SELECT * FROM users WHERE email = 'foo#bar.com' by e.g. String sql = "SELECT * FROM users WHERE email = '" + email + "'";, the problem is, what if the user puts in the web form, in the 'email' field: whatever#foo.com'; DROP TABLE users CASCADE; EXEC 'FORMAT C: /y /force'; --? Then the SQL becomes:
SELECT * FROM users WHERE email = 'whatever#foo.com'; DROP TABLE users CASCADE; EXEC 'FORMAT C: /y /force'; --';
That is legal SQL and you really, really, really don't want your DB engine to execute it.
Each DB engine has its own ideas on what's actually legal, and may do crazy things such as treating curly quotes as real quotes, etc. So, there is no feasible blacklist or whitelist technology you can think of that will properly cover all the bases: You need to ask your DB engine to do this for you, you can't fix this hole yourself.
Java supports this, via java.sql.PreparedStatement. You instead always pass a fully constant SQL string to the engine, and then fill in the blanks, so to speak:
PreparedStatement ps = con.prepareStatement("SELECT * FROM users WHERE email = ?");
ps.setString(1, "foo#whatever.com");
ps.query();
That's how you do it (and add try-with-resources just like you should already be doing here; statements and resultsets are resources you must always close). Even if you call .setString(1, "foo#whatever.com'; DROP TABLE users CASCADE; --"), then it'll simply look for a row in the database that has that mouthful in the email field. It will not delete the entire users table. Security hole eliminated (and this is the only feasible way to eliminate it).
So, check out that code. Is it using preparedstatement? In that case, well, one way or another that code needs to be calling:
ps.setInt(1, 999);
Where ps is the PreparedStatement object created with connection.prepareStatement(...) where ... is either an SQL constant or at least your input string where the <<empid>> was replaced with a question mark and never with any string input from an untrusted source. The 1 in ps.setInt(1, 999) is the position of the question mark (1 = the first question becomes 999), and the 999 is your actual number. It may look like:
if (input instanceof String) {
ps.setString(idx++, (String) input);
} else if (input instanceof Integer) {
ps.setInt(idx++, ((Integer) input).intValue());
} ...
etcetera. If you don't see that, find the setInt invoke and figure out how to get there. If you don't see any setInt, then what you want is not possible without making some updates to this code.
If you don't even see PreparedStatement anywhere in the code, oh dear! Take that server offline right now, research if a security leak has occurred, if this server stored european data you have 72 hours to notify all users if it has or you can't reasonably figure out e.g. by inspecting logs that it hasn't, or you're in breach of the GDPR. Then rewrite that part using PreparedStatement to solve the problem.
i am trying to select tables from my mysql database , and the tables names may be any thing unsafe, since users choose them, i have tried to do it like this :
String table = "*jjs> o";
PreparedStatement stmt = conn.PrepareStatement("SELECT * FROM ? ");
stmt.setString(1,table);
stmt.executeQuery();
but seems it to throw exception due to unacceptable command, can some one help me how can i achieve that please? thanks
add a back tick(`) to table name
select * from `*jjs> o`
Ok Using BackTicks Was the Answer, Like select * from `*jjs> o` without statement.Thanks Alot
I'm having a problem I haven't encountered before: there is a stored function in a database: CC_PROC, which takes two date entries and returns a table. In other words, to call it, you type:
SELECT * FROM (TABLE( CC_PROC( DATE '2012-01-01', DATE '2012-01-15')));
This seems to work perfectly in SQLPlus and NetBeans, and the above line has been apparently been in use for some time.
Anyway, when calling it from java using a prepared statement, I get: "CC_PROC": invalid identifier on the executeQuery call.
This is with:
PreparedStatement preparedStatement =
connection.prepareStatement("SELECT * FROM (TABLE ( CC_PROC( ? , ? )))");
preparedStatement.setDate(1,firstDate);
preparedStatement.setDate(2,secondDate);
resultSet = preparedStatement.executeQuery();
I feel like maybe this is obvious and my limited experience using JDBC directly instead of Hibernate is throwing me. I'd like to not have to re-code the contents of CC_PROC in java business logic. Any ideas?
Thanks!
Aha, found the answer:
The oracle user was SALESOWN, so the fix was:
PreparedStatement preparedStatement = connection.prepareStatement(
"SELECT * FROM (TABLE ( SALESOWN.CC_PROC( ? , ? )))");
Yikes. I don't want to admit the amount of time it took to figure that out.
Apparently SQLPlus and NetBeans do attempt to help out a little...
Thanks for the help guys!
I am using an ORM (ORMlite) and all my calls are going well until I get the following error.
Exception in thread "main" org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "
SELECT * FROM ""STORIES"" WHERE ""TITLE"" = 'Deepcut case leads 'NOT FOLLOWED[*]'' "; SQL statement:
SELECT * FROM Stories WHERE title = 'Deepcut case leads 'not followed'' [42000-152]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
at org.h2.message.DbException.get(DbException.java:167)
at org.h2.message.DbException.get(DbException.java:144)
at org.h2.message.DbException.getSyntaxError(DbException.java:179)
at org.h2.command.Parser.getSyntaxError(Parser.java:480)
at org.h2.command.Parser.prepareCommand(Parser.java:229)
at org.h2.engine.Session.prepareLocal(Session.java:426)
at org.h2.engine.Session.prepareCommand(Session.java:374)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1093)
at org.h2.jdbc.JdbcPreparedStatement.(JdbcPreparedStatement.java:71)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:601)
at com.j256.ormlite.jdbc.JdbcDatabaseConnection.compileStatement(JdbcDatabaseConnection.java:83)
at com.j256.ormlite.stmt.mapped.MappedPreparedStmt.compile(MappedPreparedStmt.java:44)
at com.j256.ormlite.stmt.StatementExecutor.buildIterator(StatementExecutor.java:169)
at com.j256.ormlite.stmt.StatementExecutor.query(StatementExecutor.java:119)
at com.j256.ormlite.dao.BaseDaoImpl.query(BaseDaoImpl.java:189)
I'm confused as to whats going wrong. I am calling the search from these lines:
// get our query builder from the DAO
QueryBuilder<Story, Integer> queryBuilder = StoryDao.queryBuilder();
// the 'title' field must be equal to title (a variable)
queryBuilder.where().eq(Story.TITLE_FIELD_NAME, title);
// prepare our sql statement
PreparedQuery<Story> preparedQuery = queryBuilder.prepare();
// query for all stories that have that title
List<Story> accountList = StoryDao.query(preparedQuery);
Syntax error in SQL statement " SELECT * FROM ""STORIES"" WHERE ""TITLE""...
#bemace is correct that there seem to be quotes in the title that is screwing up the escaping of strings generated by the query.
In ORMLite, you should use the SelectArg feature which will generate a query with SQL ? arguments and then pass the string to the prepared statement directly.
See the documentation on the SelectArg. With it, you'd do something like:
QueryBuilder<Story, Integer> queryBuilder = StoryDao.queryBuilder();
SelectArg titleArg = new SelectArg();
queryBuilder.where().eq(Story.TITLE_FIELD_NAME, titleArg);
PreparedQuery<Story> preparedQuery = queryBuilder.prepare();
titleArg.setValue(title);
List<Story> accountList = StoryDao.query(preparedQuery);
I'm kind of guessing but it looks like there's a problem with the value in the title field, maybe an unescaped quote mark?
I'm not familiar with ORMLite but title = 'Deepcut case leads 'not followed'' doesn't look right. Should probably be "Deepcut case leads 'not followed'" or 'Deepcut case leads \'not followed\'' or some such.
The correct syntax for the statement would be:
SELECT * FROM Stories WHERE title = 'Deepcut case leads ''not followed'' ';
Note the duplicated single quotes inside the string literal.
You will need to tell your ORM layer to follow the ANSI SQL rules for literals.
The exception says that there is some syntactical problem with your generated SELECT statement. Can you print out the generated query? Doing that might help you pin down the exact issue here.
EDIT: Looking closely at your trace shows that string escaping is not handled properly here. Is this your own QueryBuilder? Also, as per this link, are you using SelectArg or directly setting the title?
Excerpt from code
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM sch.tab1 where col1 like lower ( 'ABZ' ) ");
preparedStatement.executeQuery();
The above code executes successfully.
But when i try to execute this
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM sch.tab1 where col1 like lower ( ? ) ");
preparedStatement.setString ( myValue );
preparedStatement.executeQuery();
It throws an exception."STRING TO BE PREPARED CONTAINS INVALID USE OF PARAMETER MARKERS"
What could be the problem here?
Answer found, see the comments
I suspect the problem is that you can't apply functions directly to parameters. Is there any particular reason why you want the lower casing to be performed at the database rather than in your code? (I can think of some potential reasons, admittedly.) Unless you really need to do this, I'd just change the SQL to:
SELECT * FROM sch.tab1 where col1 like ?
and call toLower() in Java, preferably specifying the appropriate locale in which to perform the lower-casing.
I think Carlos is on to something. Try
SELECT * FROM sch.tab1 where col1 like lower ( '' + ? )
or whatever passes for string concatenation operator in your version of SQL. Forcing a string context might get you past the error. May require extra parentheses.
For reference: I ran into the same problem while using the NORMALIZE_STRING function:
SELECT NORMALIZE_STRING(?, NFKD) FROM sysibm.sysdummy1
Error message:
THE DATA TYPE, LENGTH, OR VALUE OF ARGUMENT 1 OF NORMALIZE_STRING IS INVALID. SQLCODE=-171, SQLSTATE=42815, DRIVER=4.13.111
Using the following statement solved the problem (CONCAT). Thanks to Paul Chernoch!
SELECT search_normalize(NORMALIZE_STRING(? CONCAT G'', NFKD)) FROM sysibm.sysdummy1
Note the "G" prefix for Unicode compatibility.