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 (?,?,?)
Related
I try to create a connection between JDBC and MS Access.
I follow the instruction as per this link. I am using IntelliJ Idea. Here I am sharing some snaps to describe my problem.
This is the code that I write down to make a connection with Database Database2. But as you can see there is no error neither any output. Now I am sharing the table structure and content on the table.
2nd picture is
My code is:
import java.sql.*;
public class Connection_sample {
public static void main(String[] args) {
try {
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
Connection conn= DriverManager.getConnection("jdbc:ucanaccess://D://tutorial/Database2.accdb");
Statement s = conn.createStatement();
s.executeQuery("select * from Student");
ResultSet rset = s.getResultSet();
while (rset.next()) {
System.out.println(rset.getInt(1)+""+rset.getInt(2));
}
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Can anyone help me to find the error?
Your problem is the result of using getResultSet() instead of using the result set returned by executeQuery(). You should only use getResultSet() in combination with execute().
A result set should only be obtained once, and it was already returned from executeQuery (which you ignored). When you called getResultSet, you - apparently - got an empty one (which technically violates the contract).
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);
}
Code snippet:
On a button click, actionevent will be called
public void actionPerformed(ActionEvent e)
{
Function f = new Function();
Function is a nested class which i have used to establish the connection with the database.
The code snippet for function class is also provided in the end.
ResultSet rs = null;
String Cid ="cust_id";
String Pno="cust_phone";
String cat="cust_cat";
String start_date="st_date";
String Adv_amt="adv";
String Adv_end="end_date";
String Address="addr";
t2 is the Textfield name which i have used to get entry of customer name. I want to use this customer name as a PK to fetch all the other data about that customer from DB.
rs=f.find(t2.getText());
try{
if(rs.next())
{
t1.setText(rs.getString("cust_id"));
t3.setText(rs.getString("cust_phone"));
t4.setText(rs.getString("cust_cat"));
t5.setText(rs.getString("st_date"));
t6.setText(rs.getString("adv"));
t7.setText(rs.getString("end_date"));
t8.setText(rs.getString("addr"));
}
else
JOptionPane.showMessageDialog(null,"No data for this name");
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null,ex.getMessage());
}
}
Here is the code snippet for nested class Function which is inside the main class:
class Function{
Connection con=null;
ResultSet rs= null;
PreparedStatement ps = null;
public ResultSet find(String s)
{
try
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
con = DriverManager.getConnection("jdbc:oracle:thin:#Localhost:1521:xe","system","qwerty");
ps= con.prepareStatement("Select * from gkkdb where cust_name='?'");
ps.setString(1,s);
rs= ps.executeQuery();
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
return rs;
}
}
Please help figure out the problem.
Don't put the parameter placeholder ? in single quotes.
This:
ps = con.prepareStatement("Select * from gkkdb where cust_name='?'");
should be
ps = con.prepareStatement("Select * from gkkdb where cust_name = ?");
The ? is not recognized as a placeholder if you enclose it in single quotes.
Sorting out the bind variable will fix your immediate issue.
You should explicitly specify what columns you want selected and that way you'll only get what you need (someone might add a BLOB column later) and you'll get them in the right order (someone might change the table create script before running on another DB instance, although you are looking up the columns by name, a different order would only impact if you were using positional indexes).
Ditto on the other answer re: bind variables (i.e. no quotes)
Plus, "select * from" is never a good idea, ask your DBA.
Obviously your code is for example, but you should make sure you free up any resources (Connection, Statement, ResultSet) as soon as they are done with. Use Java 7 try-with-resources.
I am looking for some way how to access MySQL database more dynamically.
For example, I want to insert some text to my table.
I have some method called insert() which is called approximately every half of the second and does the insert stuff.
The code looks like this:
public void insert(String string) {
Class.forName("com.mysql.jdbc.Driver").newInstance();
java.sql.Connection conn = java.sql.DriverManager.getConnection(...);
java.sql.Statement stat = conn.createStatement();
stat.executeUpdate("INSERT INTO mytable (mytext) VALUES ('"+ string +"')");
conn.close();
}
But I really think this could cause many problems because it is opening and closing connections too often.
So isn't there any way to open some "MySQLStream" to the database and print the data to it without opening and closing the connection again and again?
Thanks for your replies.
Create a Connection object at the beginning of the program, and use it for every query. Close it only at the end of the program.
Oftentimes one Connection is good, so you may declare it as static.
public static java.sql.Connection conn;
public static void buildConnection()
{
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = java.sql.DriverManager.getConnection(...);
}
public void insert(String string)
{
java.sql.Statement stat = conn.createStatement();
stat.executeUpdate("INSERT INTO mytable (mytext) VALUES ('"+ string +"')");
}
In the program, you may do the following:
buildConnection();
...
insert("....");
insert("....");
...
conn.close();
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);