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=''
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 stuck with Oracle store procedure calling. The code looks simple, but I seriously don't know how to make it work.
This is my code for creating the procedure
DELIMITER ##
CREATE OR REPLACE PROCEDURE updateAward(_total_amount in Number, _no_of_sales in Number, _agent in NUMBER, _id in NUMBER) AS
BEGIN
update Award set total_amount = _total_amount, no_of_sales = _no_of_sales, agent_id = _agent where ID = _id ##
commit ##
So, when I execute it through NetBean (it is the only tool I have at this moment), the code run well.
I also tried to run the compile statement
alter PROCEDURE updateAward compile;
and then, use
select *
from user_errors
where name = 'ORG_SPGETTYPE'
The select return empty, proving that the compile process is ok. However, when I trigger the procedure
call updateAward(1,1,1,1);
It returns the error
Package or function UPDATEAWARD is in an invalid state
and the command
SELECT object_name FROM user_objects WHERE status='INVALID';
return the name of the procedure. How can I solve this problem ?
Update 1:
if I use
BEGIN
updateAward(1,1,1,1);
End;
I got error
Error code 6550, SQL state 65000: ORA-06550: line 2, column 20:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
:= . ( % ;
Update 2:
The reason I put the deliminator is because i got error with ";" when working through some vpn to the other network (still not sure why). So, i updated the code like your answer, but then, with the End; in the end of the procedure and then, get the Invalid SQL statement1. If i remove it and execute (through Netbean), the procedure is created successfully. However, after compiling and check the user_errors, it got the
"PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: ; "
First things first, your procedure syntax looks wrong. Don't use DELIMITER as that syntax is specific to MySQL. Instead, try something like the following.
CREATE OR REPLACE PROCEDURE updateAward(_total_amount in Number, _no_of_sales in Number, _agent in NUMBER, _id in NUMBER) AS
BEGIN
update Award set total_amount = _total_amount, no_of_sales = _no_of_sales, agent_id = _agent where ID = _id;
commit;
END;
Firstly, there are a couple of things wrong with your procedure:
You're not using delimiters correctly. Delimiters should be used to terminate the whole procedure, not each line.
The NetBeans SQL window doesn't know SQL very well so it cannot tell when the procedure ends and something else begins. Normally, it uses semicolons (;) to tell when one statement ends and another begins, but stored procedures can contain semicolons within them so that wouldn't work. Instead, we change the delimiter to something else so that the NetBeans SQL window sends the entire stored procedure to the database in one go.
Variable names are not allowed to begin with an underscore (_). In particular, rule 5 in the list of Schema Object Naming Rules at this Oracle documentation page states that
Nonquoted identifiers must begin with an alphabetic character from your database character set.
Underscores are not alphabetic characters.
I've taken your procedure, fixed the use of delimiters and added an extra p onto the front of each parameter name (p for 'parameter'), and I got the following, which ran successfully in NetBeans and created a procedure without errors:
delimiter $$
CREATE OR REPLACE PROCEDURE updateAward(p_total_amount in Number, p_no_of_sales in Number, p_agent in NUMBER, p_id in NUMBER) AS
BEGIN
update Award set total_amount = p_total_amount, no_of_sales = p_no_of_sales, agent_id = p_agent where ID = p_id;
commit;
END;
$$
delimiter ;
Secondly, you write
[...] and then, use
select *
from user_errors
where name = 'ORG_SPGETTYPE'
The select return empty, proving that the compile process is ok.
Um, no. This proves that there are no errors in the procedure ORG_SPGETTYPE (or no procedure with that name exists). Your procedure is named updateAward, which Oracle will capitalise to UPDATEAWARD. Try
select *
from user_errors
where name = 'UPDATEAWARD';
instead.
I can't understand what wrong with it, i spent many hours trying to get my String object from method queryForList(..) and all for nothing. So here this stupid sql query:
String GET_EMAIL_BY_LDAP = "select ld.LDAP_EMAIL1 from IPS.ldap ld where ld.ldap_login = ?"
I have tried this also without '?' parameter and it is works perfectly.
Here is the way, how I use the method:
List<String> email = jdbcTemplate.queryForList(GET_EMAIL_BY_LDAP, String.class, userId.toUpperCase());
And this version of method also returns empty List:
List<String> email = jdbcTemplate.queryForList(GET_EMAIL_BY_LDAP, new Object[]{userId.toUpperCase()}, String.class);
P.S. getEmailById("DN270391RKA") - this is my user id parameter that passed. It hasn't spaces.
Type of ld.LDAP_EMAIL1 field in table is : NVARCHAR2(381 CHAR)
I have understood what it was!
ld.ldap_login values in my ( legacy :-D ) table have a tailing spaces. After minor editing of my sql statement it works. I just added TRIM() on this column.
"select ld.LDAP_EMAIL1 from IPS.ldap ld where TRIM(ld.ldap_login) = ?"
So, it seems if it is usual sql statement then when I execute query then oracle database does TRIM() automatically and in case of PreparedStatement doesn't.
List<String> email = jdbcTemplate.queryForList(GET_EMAIL_BY_LDAP, String.class, userId.toUpperCase());
This line is fully correct so it seems to be either a bad userID or your sql query is not correct.
Best way is to paste your sql query with an existing user id in your query browser and check if you get more than an empty result.
then use the jdbc template again and pass hardcoded previously working user id and check if you get the same results.
or: delete the userid clause and select all not specific to the user id.
Also make sure the ld.LDAP_EMAIL is String representation e.g varchar/text
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.
I have follwinig code for search data.
public void advanceSearchMethod(String advanceName, int advanceTpNumber, String advanceAddress, String advanceDescription){
Connection connection=null;
try{
//for connect to database.
connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost/contactbook","root","time1");
//for communicate with database.
Statement stmt=(Statement)connection.createStatement();
String searchQuery="SELECT * FROM Contacts WHERE Name LIKE '%'"+advanceName+"'%' AND TelePhoneNumber LIKE '"+advanceTpNumber+"%' OR Address LIKE '%'"+advanceAddress+"'%' OR Description LIKE '%'"+advanceDescription+"'%'";
rs=stmt.executeQuery(searchQuery);
contactTableInDefaultForm.setModel(DbUtils.resultSetToTableModel(rs));
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Sorry! Connection Failed");
}
}
No errors in this code.but work catch block. I cannot imagine what I should do. How can I search them?
You have a major bug -- when you build the WHERE clause, you have spurious ' apostrophes after '% opening-quote & wildcard and before %' closing-wildcard & quote.
Your broken code: "WHERE Name LIKE '%'"+advanceName+"'%'"
Corrected: "WHERE Name LIKE '%"+advanceName+"%'"
But the whole code is not good code, at all -- every single thing is wrong with it.
WHERE clauses should be built up only with the conditions you actually need to search on. And should use PreparedStatement and ? bound parameters, rather than building string-literals into the SQL. (You have built a well-known security flaw.)
PhoneNumbers are strings, not integers. The LIKE pattern for TelePhoneNumber doesn't have a starting %.
DB connection should be provided from one class & method, rather than in every method in your application.
Errors in separate operations (getting the connection/ vs. executing the query and reading results) should be checked & reported separately. Exceptions and stacktraces should always be logged (use Log4J) or, at the worst case, output to the console.
The single only thing you got right here, was the variable & parameter naming.
To be honest, you ought to be using Hibernate rather than writing this rickety nonsense.
String searchQuery="SELECT * FROM Contacts WHERE Name LIKE '%'"+advanceName+"'%' AND TelePhoneNumber LIKE '"+advanceTpNumber+"%' OR Address LIKE '%"+advanceAddress+"%' OR Description LIKE '%"+advanceDescription+"%'";
U have added addition single quatation..
Hope this is right answer..