I am trying to query my database by using a Java function with another attribute defined in the database. The statement generates no error. However, the output is wrong. The result of the output is null but from my checking it is not null. Please can anyone tell me what I need to do? How can I use JAVA functions in SQl statements?
expired_rows = dbMngr.runQuery(String.format("SELECT ID FROM Student WHERE 'System.currentTimeMillis()' - ArrivalTime > (%s) ", 5000));}
if (expired_rows == null) {
System.out.println("The number of expired row is " + expired_rows);
}
if (expired_rows != null) {
System.out.println("The number of expired row is " + expired_rows.length );
}
You can't use the java function in the way you are trying to. You are just passing the String "'System.currentTimeMillis()'" to the dbms - you want to pass in the result of evaluating that function
Would
"SELECT ID FROM Student WHERE %l - ArrivalTime > (%s) ",System.currentTimeMillis(), 5000));}"
work? ( I'm unsure of the syntax for String.format and don;t have acces to the docs, but hopefully you get the picture ... )
A better solution, but a little further away from the work you have already done, would be to use a PreparedStatement as suggested by GriffeyDog.
Also, if no error is being generated, then it seems a quite likely that your dbMngr class is swallowing the exceptions without reporting them.
Related
I'm using OrientDB to represent large city maps and calculate the shortest traversal times between a pair of nodes when the need arises. I have the following method:
public void getShortestPath(int from, int to){
String query = "SELECT astar(?, ?, time, direction=OUT, customHeuristicFormula=EUCLIDEAN) FROM V";
OResultSet set = db.query(query, getNode(from).getProperty("#rid"), getNode(to).getProperty("#rid"));
}
The getNode(nodeID) method returns the OVertex object present in the database, hence we can identify the #rid. Clearly, this method serves no purpose as is.
My issue comes when trying to call the astar query on the database (i.e. line two of the method). I'm getting the following error: OCommandSQLParsingException: Error parsing query upon reaching the first ( (i.e. error encountering the open bracket). Removing the brackets entirely simply resulted in the same error occurring on the # in front of the first #rid value.
I can't seem to find any example of using this function in practice, and (at least I think) I'm using the function call as suggested by the documentation. Look forward to hearing your thoughts.
I'm using the most recent version of OrientDB: 3.2.3
Turns out the error had nothing to do with the bracket itself. Passing the "direction='OUT'" and "customHeuristicFormula='EUCLIDEAN'" parameters in as part of the string was the problem. The below block did the trick.
String sql = "SELECT ASTAR(" + getNode(from).getProperty("#rid") + ", " + getNode(to).getProperty("#rid") + ", time) FROM V";
try(OResultSet set = db.query(sql, "direction='OUT'", "customHeuristicFormula='EUCLIDEAN'")) {
// some code...
}
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 would really appreciate some help with a computed column using an expression in Birt.
I have two columns which are giving results, one gives email addresses and one gives contact numbers: telephone, mobile..
When the email result is null then the contact number column shows a number, these are separate communication methods from a table in sql.
What I would like to do is create a new computed column for both the email address and the telephone number, when emailaddress is null then replace with contactnumber = contact and when contactnumber is null replace with emailaddress.
I've looked at a few similar questions online and found that entering the below script into the birt expression builder is accepted when you click validate, but it is not loading the report in the erp software I am using.
Is the expression itself correct?
if(row["destination"] == null){
row["contact"];
}
else if(row["contactnumber"] == null){
row["contact"];
}
else{
return true;
}
Kind regards,
Stuart
No, it is not correct (syntactically valid, though).
First of all what we've got here is an expression, not a function.
So there shouldn't be a return statement.
And obviously true cannot be right. The other values are (probably) strings, so this should be a string as well.
I'm not quite sure what you actually want to achieve.
Maybe you are looking for something like COALESCE in SQL oder NVL in Oracle SQL?
I suppose you create a JS function, test it with JSfiddle or so, then place it in the initialize script and call it in the expression.
By using the following in a Birt Expression, this replaces one column with another columns value if null.
if(row["destination"] == null){
row["contactnumber"];
}
else {
row["destination"]; }
U may try this strange construction
if (!row["doc_no"] === false){
//if value is not null\NaN\empty\0
}
I have a JavaFX App where the user inputs some informations about him and then I have a class that is named DbUpdateBuilderthat allows me to create my sql resquest more easily. And then I use statement.executeUpdate(request)
The issue is that I always get this error :
java.sql.SQLSyntaxErrorException: syntax error near " line 1 So I thought something was wrong my request so I printed the request I got :
UPDATE `users` SET `users`.`first_name`=null,`users`.`last_name`=null,`users`.`age`=null,`users`.`role`=null,`users`.`gender`= 3 WHERE `users`.`id` LIKE 10
which works if I hard code it.
this do not work
// Some code
Statement stmt = con.createStatement();
String request = builder.getRequest();
System.out.println(request); // where the request in the
// working exemple comes from
if(stmt.executeUpdate(request) > 0) { // I get the error from this
// line
return UPDATE_SUCCESS;
}
return SQL_ERROR_OCCURED;
but this do work
Statement stmt = con.createStatement();
String request = builder.getRequest();
System.out.println(request);
if(stmt.executeUpdate("UPDATE `users` SET `users`.`first_name`=null,`users`.`last_name`=null,`users`.`age`=null,`users`.`role`=null,`users`.`gender`= 3 WHERE `users`.`id` LIKE 10") > 0) {
return UPDATE_SUCCESS;
}
return SQL_ERROR_OCCURED;
I must precize that the request hard coded in the working example comes from a copy & paste of the request printed in the not working example
Just a suggestion
LIKE work on string and normally is used with wild char
could be you need
if you need exact match then use equal
UPDATE `users`
SET `users`.`first_name`=null,
`users`.`last_name`=null,
`users`.`age`=null,
`users`.`role`=null,
`users`.`gender`= 3
WHERE `users`.`id` = 10
if you need a pattern match the use like and wildchar eg;
UPDATE `users`
SET `users`.`first_name`=null,
`users`.`last_name`=null,
`users`.`age`=null,
`users`.`role`=null,
`users`.`gender`= 3
WHERE `users`.`id` LIKE '%10%'
Thanks for your suggestion #scaisEdge. But I found the issue on my own : I compared the two strings (the one hard coded and the one generated by my builder) they had the same lenght so I printed char by char each string and then I found the issue ! some chars were equal to null so SQL didn't like it and generated error but when I printed it null chars were ignored...
Sometimes quotes ' are not acceptable by mysql but you can try this as simple with no qoutes
UPDATE users
SET first_name=null,
last_name=null,
age=null,
role=null,
gender='3'
WHERE id LIKE '%10%'
And make sure your datatypes are correct, also null is equal to empty you can try change it to '' like first_name=''
So I would like to do a select from an SQL database, using Java, subject to a conditional statement (less than or equal to something) subject to some loop in Java. In other words, something like the following:
for (int i=0; i< 195; i++) {
// Get the results of the SQL query
resultSet = statement.executeQuery(
"SELECT max( millisFromMid ) FROM stockInfo1 WHERE ( millisFromMid <= 34200000 + (120000)*i ) GROUP BY stockID"
);
Now Java is returning an exception here, because it doesn't want me to use "i" in this condition; however, without being able to use it here, I'm not sure how I can change this condition. The problem is this: I'm looking to retrieve data from one database, with the intent of doing some manipulation and putting the results into a new database. These manipulations depend on taking the most recent data available, which is why I'm wanting to increase the number bounding millisFromMid. Does that make sense?
Does anyone have a suggestion on how someone might do something like this? This seems like a fundamental skill to have when using Java and SQL together, so I'd very much like to know it.
The SQL statement is parsed and run in a different environment than your Java code - different language, different scope, and unless you use SQLite they run in different processes or even different machines. Because of that, you can't just refer to the Java variable i from your SQL code - you have to either inject it or use special API.
The first option - injection - is to simply put the value of i inside the string:
"SELECT max( millisFromMid ) FROM stockInfo1 WHERE ( millisFromMid <= 34200000 + (120000)*"+i+" ) GROUP BY stockID"
Personally, I prefer to do it using String.format - but that's just me.
String.format("SELECT max( millisFromMid ) FROM stockInfo1 WHERE ( millisFromMid <= 34200000 + (120000)*%d ) GROUP BY stockID",i)
The second option - via API - is more complex but also faster(especially if you combine it with transactions) - using SQL parameters. You need to create a prepared statement:
PreparedStatement preparedStatement = connection.prepareStatement("SELECT max( millisFromMid ) FROM stockInfo1 WHERE ( millisFromMid <= 34200000 + (120000)*? ) GROUP BY stockID")
Notice the ? that is replacing the i - this is your parameter. You create prepareStatement once - before the loop, and inside the loop you set the parameter every time and execute it:
for (int i=0; i< 195; i++) {
preparedStatement.setInt(1,i); //Set the paramater to the current value of i.
resultSet = preparedStatement.executeQuery(); //Execute the statement - each time with different value of the parameter.
}
The problem os that the database is not told about the value of i. Instead make Java put the value into the string and then submit it to the database.
string sql = "select * from foo where bar=" + i;
You need to remember at all times that the database only knows what you explicitly tell it, and that you are essentially writing code at runtime that will execute on another host.
You can generate an sql string and call it via jdbc, using bind variable is more correct from performance, security. It also saves you from escaping any special characters.
Since you are learning about using sql with jdbc, please read about bind variables. An example is here