Could anyone find out what i did wrong in this prepared statement? - java

I made a prepared statement for DB access, it dosent work though.. I'm not really sure what the problem is.
What it should do is take a integer and a string and update the DB according to this.
Here is the code.
The connection to the DB itself works, this i know cause i can execute "normal" statements.
public void updateShipment(int shipmentNumber, String currentLocation)
throws SQLException {
String sql = "UPDATE shipments SET current_node=? WHERE shipment_id=?";
con.setAutoCommit(false);
pre = con.prepareStatement(sql);
pre.setInt(1, shipmentNumber);
pre.setString(2, currentLocation);
pre.executeUpdate();
con.commit();
pre.close();
con.setAutoCommit(true);
}

Looks like you get parameter 1 and 2 mixed up when you set them. Did you mean:
pre.setString(1, currentLocation);
pre.setInt(2, shipmentNumber);

you mixed the parameters, this should be the right code
pre.setInt(2, shipmentNumber);
pre.setString(1, currentLocation);

Related

How to use PreparedStatement with JDBC

I'm new to JDBC and Java.
I'm coming from Javascript and Typescript background. I decided to learn JDBC with Oracle by creating a small basic project.
I'm using JDK 8. I'm following this study material: TutorialsPoint-PreparedStatement. I figured out that problem is with my DataService.
Here's my DataService class:
import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DataService {
Connection con;
PreparedStatement pstmt;
static String branch_name="";
static LocalDate branch_created_on;
static String branch_pulled_from="";
DataService() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe","system","scott");
}
catch(Exception e){
System.out.println(e);
}
}
public void getValue() {
branch_name=AddNewBranchRecord.branchNameTextField.getText();
branch_created_on=AddNewBranchRecord.datePicker1.getValue();
branch_pulled_from=(String) AddNewBranchRecord.combo_box_1.getValue();
}
public void putValue() {
System.out.println("Branch name: "+branch_name);
System.out.println("Branch created on: "+branch_created_on);
System.out.println("Branch pulled from: "+branch_pulled_from);
}
public void insertRecord() {
System.out.println("Adding a record...");
getValue();
try {
String sql;
sql = "insert into mybranches values (branch_name, branch_created_on, branch_pulled_from);";
pstmt = con.prepareStatement(sql);
} catch (SQLException ex) {
Logger.getLogger(DataService.class.getName()).log(Level.SEVERE, null, ex);
}
pstmt .close();
}
}
I'm sure there's something that I missed out.
I'm not getting any error or exception but no row is inserted in the database.
I cross checked with select * from mybranches.
However, the same code works perfectly if I use the normal Statement.
You create the PreparedStatement but you don't use it.
A prepared statement is there to e.g. insert different values into a table multiple times.
You create the PreparedStatement once like you would execute a normal Statement and include ? instead of the values that differ.
If you want to execute it, you have to set the values (the ?s will be replaced with them) by using the setXXX(int,Type) methods and then execute it with .execute().
As pointed out in the comments of the question, the SQL code is not valid. The sql code prepared statement is just like the sql code of a regular statement but the values that change all the time are replaced by ?.
The SQL code of the prepared statement would be something like that:
INSERT INTO mybranches VALUES (?,?,?)
If you want to use the PreparedStatement, you could set the values like that:
pstmt.setString(1,branch_name);
pstmt.setObject(2,branch_created_from);
pstmt.setString(3,branch_pulled_from);
Finally, execute it with
pstmt.execute();
Note that (as I already said) you should create the PreparedStatement once and not every time you execute the insertRecord() method and in that method, you should just call the setXXX methods and the execute() method.
The PreparedStatement (and the Connection object) should be closed when you don't need it anymore.
Also, as #TT. suggests in the comments, you should specify the columns in an INSERT statement. It would be something like
INSERT INTO mybranches (name,createdFrom,pulledFrom) VALUES (?,?,?)

Placeholders not working when using SQL statement in Java (JDBC) [duplicate]

This question already has answers here:
Variable column names using prepared statements
(7 answers)
Using Prepared Statements to set Table Name
(8 answers)
Closed 4 years ago.
Very first question here so I apologize for any mistakes and imperfections.
Basically there are three files, my main method tech_supportv1, login_controller containing a class used to store a bunch of methods, and login.java, a javabean.
The point is to check if a certain row exists on the tech_support database. To do so I'm trying to use the code below. (db_util and type are classes containing connection data, they are tested and they work).
ISSUE: the data from the main method seems not be pasted into the string in the appropriate placeholders, and an error is returned. (Of course if I manually enter the strings instead of using placeholders, everything works just fine.)
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''technicians' WHERE 'techID' LIKE 16' at line 1
I tired to look at the mariaDB docs but all the other syntax provided yields the same results.
So this the main method.
public class Tech_support_v1 {
public static void main(String[] args) {
System.out.println("Start.");
login bean = new login();
bean.setTable("technicians");
bean.setColumn("techID");
bean.setID(16);
login_controller.select(bean);
}
}
This is the select method (with bean as argument, login is the Javabean class).
public static boolean select(login bean) {
String sql = "SELECT * FROM ? WHERE ? LIKE ?";
ResultSet rs;
try (
Connection conn = db_util.getConn(db_type.MYSQL);
PreparedStatement stmt = conn.prepareStatement(sql);
) {
stmt.setString(1, bean.getTable());
stmt.setString(2, bean.getColumn());
stmt.setInt(3, bean.getID());
rs = stmt.executeQuery();
if (rs.next()) {
System.out.println("Y");
return true;
} else {
System.err.println("N");
return false;
}
} catch (Exception e) {
System.err.println(e);
return false;
}
}
I won't include the bean class because it's literally only three variables with the relative set/get methods. Also the database runs with MariaDB, and is MySQL.
Thanks to everyone in advance.
You have multiple problems with your code :-)
First, you can't set table or column names with "setString" in a Prepared Statement!
See this Question: How to use a tablename variable for a java prepared statement insert
Second, as Daniel Pereira pointed out: You are trying to use a "like" Statement with "setInt"! See: https://dev.mysql.com/doc/refman/8.0/en/pattern-matching.html
You are comparing with LIKE but you are setting an Int. Change the LIKE to = and see if it works.
Try doing something like this:
String sql="SELECT * FROM :table ";
try (
Connection conn = db_util.getConn(db_type.MYSQL);
PreparedStatement stmt = conn.prepareStatement(sql);
)
{
String query = StringUtils.replace(sql, ":table", bean.getTable());
stmt.executeQuery(query);
}

Java Preparedstatement error when reading from MySql Database

I'm working on a simple application that pulls data from a local database. The below code works fine when I use a string for the SQL query, but I can not get it to work with PreparedStatement. I have reviewed similar problems posted here but most of those were caused by doing this, preparedStmt.executeQuery(query); instead of this preparedStmt.executeQuery(); Here is the code,
private final String POSTTITLE= "posttitle"; // DB Column name
private final String POSTCONTENT= "content"; // DB Column name
public String getDbContent(){
try{
String query ="select values(?, ?) from blog";
PreparedStatement preparedStmt = this.connect.prepareStatement(query);
preparedStmt.setString (1,POSTTITLE);
preparedStmt.setString (2,POSTCONTENT);
ResultSet rs = preparedStmt.executeQuery();
rs.next();
return(rs.getString(this.POSTCONTENT)); //Will replace with loop to get all content
} catch(Exception e) {
System.err.println("Error Reading database!");
System.err.println(e);
return("Error: "+e);
}
}
This is the error I get:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''posttitle', 'content') from blog' at line 1
Parameters in prepared statements are for values - you're trying to use them to select fields. They just don't work that way.
In this very specific instance, you'll need to make the SQL dynamic. However, you'll want to make sure that whatever code you have to allow your columns to be specified is tightly constrained to avoid SQL injection attacks. (For example, you could have an enum with the columns in, or a whitelist of allowed values.)
Try concatenating select query:
String query ="select "+POSTTITLE+","+POSTCONTENT+" from blog";
Remember that prepared statements are for values, not query parameters, for them we use simply concatenations.
Try this:
String query ="select POSTTITLE, POSTCONTENT from blog";
PreparedStatement preparedStmt = this.connect.prepareStatement(query);
ResultSet rs = preparedStmt.executeQuery();
rs.next();
There is no need to use field names as parameter.

Delete query working in PgAdmin 3 but not working on Java JDBC

I am trying to delete a list of times saved in a database where the date (end_time - timestamp) is bigger that my reference day for a specific employee (employeeId - integer).
The query works perfectly on pgAdmin III. However I cannot make it work in JDBC.
It works, but it deletes everything from that particular employee and not just the dates I want. I looks like it ignores the date in the Where clause. Also, I do not get any exception.
The variable nextDayTimestamp comes out like: '2017-03-31 12:00:00.0'
Could anybody please help?
public void deleteBigListOfPeriodOfWorkFutureOnly(int employeeId, LocalDate referenceDate) {
Connection myConn = null;
PreparedStatement myStmt = null;
try {
myConn = dataSource.getConnection();
LocalDate nextDay = referenceDate.plusDays(1);
Timestamp nextDayTimestamp = Timestamp.valueOf(LocalDateTime.of(nextDay, LocalTime.NOON));
String sql = "delete from working_time where working_time.end_time > ? and employee_id = ?";
myStmt = myConn.prepareStatement(sql);
myStmt.setTimestamp(1, nextDayTimestamp);
myStmt.setInt(2, employeeId);
myStmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
CloseConnection.close(myConn, myStmt, null);
}
}
}
I think First where condition is always true you should:
First: print the nextDayTimestamp and make sure it is valid
Second: If it is valid try the condition on postgresql sql query
If the Connection coming out of that dataSource doesn't have AutoCommit turned on, your update will succeed, but the "transaction" never commits, so in the database won't reflect your changes. Maybe put an explicit myConn.commit(); after that executeUpdate and see if your updates now show up in the database.
I found out the answer! I made a mistake calling "delete from employee where employeeId=?" from another method that I was not taking notice. It was at a higher level. That is why it was deleting every employee.
I just removed that method and THE CODE MENTIONED IN MY QUESTION ABOVE DO WORKS!
Thanks a lot for the effort and time trying to help me! THANK YOU!

Strange problem with JDBC, select returns null

I am trying to use JDBC and my query is working in some cases but not working in others.
I would really appreciate any help.
Some of my code:
public Result getSpecificTopic()
{
String query = "Select msg_body, msg_author from lawers_topic_msg";// where msg_id=2 order by msg_id desc";
try
{
con = mysql.getConnection();
//Statement stmt = con.createStatement();
PreparedStatement stmt = con.prepareStatement(query);
//stmt.setInt(1, topicId);
ResultSet rs = stmt.executeQuery(query);
int rowCount = rs.getRow();
specificTopic = ResultSupport.toResult(rs);
con.close();
stmt.close();
}
catch(Exception e)
{
}
return this.specificTopic;
}
public void setTopicId(String num)
{
this.topicId = Integer.parseInt(num);
}
public int getTopicId()
{
return this.topicId;
}
However if i change
String query = "Select msg_body, msg_author from lawers_topic_msg";
to the
String query = "Select msg_body, msg_author from lawers_topic_msg where msg_id = " + topicId;
Then the resultset retunrs nothing....
I am breaking my head here and still cannot figure out what is the problem
You still aren't closing your resources properly. That should be done in a finally block:
http://www.java-blog.com/correct-closing-jdbc-resources
As a first step, it'd be worth making sure an exception's not being thrown - at the very least log something in your catch() block.
Also be worth logging the SQL generated, and making sure that actually returns what you expect from the database when running it directly.
If you have multiple databases, it'd be worth confirming you're running against the one you think you are - I'm embarrassed to admit I've been caught out that way before.
several issues with your code, i'll keep it short:
don't encapuslate with try / catch at this layer, aspecially not since you're doing no error management. this.specificTopic looks global, so if your query fails it will return whatever was stored in this.specificTopic.
also try what BobbyShaftoe said. print in console or use your debugger. This should give you a good indication on what is wrong.
my first guess would be Integer.parseInt(num) could throw an exception. if so, the sql statement will be broken.
secondly, as Makach pointed out, there are several issues. first the catch-all
you should not use string concatenation, like
....where msg_id = " + topicId;
but rather
....where msg_id = ?"
stmt.set Int(1,topicId)
edit: it seems thats what you were trying anyways, SO sucks in some characters.

Categories

Resources