Update a single value inside a table with java using MySQL - java

Currently I have this code:
PreparedStatement prepCust = connection.prepareStatement("insert into Customer values (?, ?, ?, ?, ?, ?);");
ResultSet results = connection.createStatement()
.executeQuery("SELECT phonenumber FROM customer WHERE phonenumber = " + cust.getPhoneNumber());
results.next();
try {
if (results.getString(1).equals(cust.getPhoneNumber())) {
System.out.println("User already exist in database, adding one to order count");
results = connection.createStatement().executeQuery(
"SELECT numberoforders FROM customer WHERE phonenumber = " + cust.getPhoneNumber());
results.next();
int updated = results.getInt(1) + 1;
System.out.println(updated);
results = connection.createStatement()
.executeQuery("SELECT * FROM customer WHERE phonenumber = " + cust.getPhoneNumber());
results.next();
prepCust.setString(1, results.getString(1));
prepCust.setString(2, results.getString(2));
prepCust.setString(3, results.getString(3));
prepCust.setString(4, results.getString(4));
prepCust.setInt(5, updated);
prepCust.setInt(6, results.getInt(6));
prepCust.executeUpdate();
}
} catch (SQLException sql) {
sql.printStackTrace();
prepCust.setString(1, cust.getfName());
prepCust.setString(2, cust.getlName());
prepCust.setString(3, cust.getAddress());
prepCust.setString(4, cust.getPhoneNumber());
prepCust.setInt(5, 1);
prepCust.setInt(6, 0);
prepCust.executeUpdate();
}
And the table it is accessing is:
create table customer(
firstname varchar(50) NOT NULL,
lastname varchar(50) NOT NULL,
streetaddress varchar(150) NOT NULL,
phonenumber varchar(10) NOT NULL,
numberoforders int(11) default 1;
customer_id int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY(customer_id,phonenumber)
UNIQUE KEY customer_id (customer_id)
);
My issue is, when I tried to just update a single value using prepCust.setInt(5, someInt);, and then attempt to execute the update, I would get an exception saying that I never input anything for prepCust.setString(1,whatever); and so on. My thoughts for surrounding the code with a trycatch was if the code throws an exception, then that must mean that field does not exist inside the table, and to create a new field that contains all the entered data. If the code doesn't throw an exception, that means that the phone number does exist inside the table, and to find what row that phonenumber is on, and add one to the amount of orders that customer has. My issue now with this code is that it will add an entire new column of information to the table, even if it has the same phonenumber and customer id, throw an exception telling me that, and then I'm stuck with values of the exact same where the value doesn't increment that I need to. How can I just update a single value in a column? Is there anyway to do that with a prepared statement?

The problem is because you are using an INSERT statement when you are looking to do an UPDATE statement. Since the entry already exists, you want to update that one value that exists with the same phone number. When it doesn't exist you put your prepCust insert statement in your catch block to make the new entry.
String phonenumber = cust.getPhoneNumber();
Statement s = connection.createStatement();
ResultSet results = s.executeQuery("SELECT phonenumber, numberoforders FROM customer WHERE phonenumber = " + phonenumber);
results.next();
try {
if (results.getString(1).equals(phonenumber)) {
System.out.println("User already exist in database, adding one to order count");
int updated = results.getInt(2) + 1;
System.out.println(updated);
PreparedStatement updateCust = connection.prepareStatement("UPDATE customer SET numberoforders = ? WHERE phonenumber = ?");
updateCust.setInt(1, updated);
updateCust.setString(2, phonenumber);
updateCust.executeUpdate();
}
} catch (SQLException sql) {
sql.printStackTrace();
try {
PreparedStatement prepCust = connection.prepareStatement("insert into Customer values (?, ?, ?, ?, ?, ?);");
prepCust.setString(1, cust.getfName());
prepCust.setString(2, cust.getlName());
prepCust.setString(3, cust.getAddress());
prepCust.setString(4, cust.getPhoneNumber());
prepCust.setInt(5, 1);
prepCust.setInt(6, 0);
prepCust.executeUpdate();
} catch (SQLException sql2) {
sql2.printStackTrace();
}
}

Related

SQLEXCEPTION : Bad value for type long

EDIT: I fixed the insert off by one mistake so I deleted that part of the question but still have the Bad value for type long error.
EDIT: the create statement for the small company table
create table small_company
(
first_name varchar(20),
last_name varchar(30),
address text,
emp_id serial not null
)
;
Created from:
create table company
(
first_name varchar(20),
last_name varchar(30),
company_name text,
address text,
city varchar(30),
province text,
postal varchar(7),
phone1 text,
phone2 text,
email text,
web text
)
;
create index name_priority
on company (first_name)
;
I'm getting this error saying "Bad value for type long :"
// insert values into the "small_company" table
long insertEmp(String first_name, String last_name, String address) {
String sql = "insert into small_company values (?,?,?)";
long id = 0;
try {
Connection conn = connect();
PreparedStatement pstmt = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1,first_name);
pstmt.setString(2,last_name);
pstmt.setString(3,address);
int affectedRows = pstmt.executeUpdate(); // returns number of affected rows
if (affectedRows > 0) { // means a row was affected so get the ID
try {
ResultSet rs = pstmt.getGeneratedKeys();
if (rs.next()) {
id = rs.getLong(1); // if cursor finds row with id, return it
}
}
catch (SQLException e) {
System.out.println(e.getMessage());
}
}
}
catch (SQLException e){
System.out.println(e.getMessage());
}
return id;
}
public static void main(String[] args) {
Queries q1 = new Queries();
//q1.getRowCount("company");
//q1.displayTable();
//q1.displayCompany(); // <- what I use to display table!
//q1.findEmployee(10);
q1.insertEmp("Laura","Lane","Daily St. Planet co. NE"); //<-what I use to insert!
}
All help is greatly appreciated!
The first column in small_company is first_name and you can't use getLong() on a varchar column. You have to use getLong("emp_id") instead.
Alternatively you can tell the JDBC driver to only return the emp_id:
PreparedStatement pstmt = conn.prepareStatement(sql,new String[]{"emp_id"});
Then getLong(1) should work as well as only one column is returned (at least with an up-to-date JDBC driver).

How to get generated ID after inserting new record in database table using Spring JDBCTemplate?

I know that this is an duplicated question but the other solutions on the other pages isn't working for me.
I have a Oracle database and I want to fetch inserted record ID (primary key) but I'm unable to do so. Below is the error and my code.
org.springframework.dao.DataRetrievalFailureException: The generated
key is not of a supported numeric type. Unable to cast
[oracle.sql.ROWID] to [java.lang.Number]
String query = "INSERT INTO JOBS (USERNAME, CREATED_ON, STATUS, JOBTYPE, DATA) " + "VALUES (?, ?, ?, ?, ?)";
try {
KeyHolder holder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
#Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement ps = con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, "username");
ps.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
ps.setString(3, "status");
ps.setString(4, "jobtype");
ps.setString(5, "job-data");
return ps;
}
}, holder);
System.out.println("Holder tostring: " + holder.toString());
System.out.println("Ran an update statement and got generated key. Key = " + holder.getKey().intValue());
System.out.println("Key: " + holder.getKey().longValue());
return true;
} catch (DataAccessException e) {
System.err.println("Exception thrown inserting record into table. Error: " + e.getMessage());
e.printStackTrace();
}
When I run the app in debug mode I'm seeing holder variable keyList value is: [{ROWID=AAAKy2AAAAALRgdAAD}] I'm not getting the inserted record Id.
Create table script is:
CREATE TABLE JOBS (
ID INTEGER GENERATED ALWAYS AS IDENTITY(START WITH 1 INCREMENT BY 1),
USERNAME VARCHAR2(20) NOT NULL,
CREATEDON TIMESTAMP NOT NULL,
STATUS VARCHAR2(10) NOT NULL,
JOBTYPE VARCHAR2(15) NOT NULL,
DATA VARCHAR2(1000 CHAR) NOT NULL,
PRIMARY KEY(ID)
);
When you use con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS), the Oracle JDBC driver will not return the value of the id column, but instead it will return the ROW_ID (a pseudo column that identifies a specific row), to allow you to retrieve the value yourself.
Historically the Oracle driver did it this way, because previous Oracle versions didn't have identity columns.
Instead you should use:
con.prepareStatement(query, new String[] { "ID" });
Which instructs Oracle to return the value of the specified column.

java sqlite autocommit slow

Background: I'm working with Java in Netbeans.
I'm reading rows from a CSV file and inserting them into a SQLite database. Very basic stuff I would think. From examples found at this site and elsewhere I've constructed the following code. It works but I'm surprised to see how slow it is. It takes 3.95 seconds to load 46 lines into the db! Using the Netbeans Profiler I can see it's the autoCommit() that's taking the bulk of the time, 3.7 seconds.
What am I doing wrong? Or, is this just the penalty for using SQLite instead of MySQL?
public static void LoadJCNAClassesTable(Connection aConn, String strPath) throws SQLException{
String [] nextLine;
String strDivision;
String strClass;
String strNotes;
String strDescription;
Statement stat = aConn.createStatement();
stat.executeUpdate("drop table if exists JCNAClasses;");
String q = "create table JCNAClasses ('ID' INTEGER PRIMARY KEY AUTOINCREMENT, 'division' TEXT NOT NULL, 'class' TEXT NOT NULL UNIQUE, 'description' TEXT NOT NULL, 'note' TEXT NOT NULL, 'node' INTEGER NOT NULL);";
stat.executeUpdate(q);
CSVReader reader;
int iLine;
String JCNAClassesCSV = strPath + "\\JCNAClassesCsv.txt" ;
try {
reader = new CSVReader(new FileReader(JCNAClassesCSV ));
iLine = 0;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
// System.out.println(nextLine[0] + nextLine[1] );
if (iLine > 0){
strDivision = nextLine[0];
strClass = nextLine[1];
strDescription= nextLine[2];
strNotes= nextLine[3];
PreparedStatement prep = aConn.prepareStatement( "insert into JCNAClasses ('division', 'class', 'description', 'note', 'node') values ( ?, ?, ?, ?, ?);");
prep.setString(1, strDivision); // note that the comma seems not to be a problem
prep.setString(2,strClass);
prep.setString(3,strDescription);
prep.setString(4,strNotes);
prep.setInt(5,iLine);
prep.addBatch();
aConn.setAutoCommit(false);
prep.executeBatch();
aConn.setAutoCommit(true);
}
iLine++;
}
} catch (FileNotFoundException ex) {
Logger.getLogger(Entries.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex) {
Logger.getLogger(Entries.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(LoadSQLiteConcoursDatabase.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void LoadConcoursEntriesTable(Connection aConn, String strPath) throws SQLException{
String [] nextLine;
String strEntryName;
String strClass;
Integer intYear;
String strDescription;
String strOwnerFirst;
String strOwnerLast;
Integer intJCNA;
String strColor;
String strPlate;
Integer intNode;
Long intPersonnel_id;
Long intJaguar_id;
ResultSet generatedKeys;
String strStatus;
int intPersonnelNode;
ResultSet r;
CSVReader reader;
String q;
int iLine;
PreparedStatement prep;
ResultSet rs;
Statement stat = aConn.createStatement();
//
// Concourse Personnel Table: Owners, Judges, & Interested parties
//
stat.executeUpdate("drop table if exists ConcoursPersonnel");
// status: Owner = "O"; "J" = Judge; "OJ" = Owner & Judge; "IP" = Interested party, e.g., spouse, restorer
q = "create table ConcoursPersonnel ('personnel_id' INTEGER PRIMARY KEY AUTOINCREMENT , 'ownerfirst' TEXT NOT NULL, 'ownerlast' TEXT NOT NULL, 'jcna' INTEGER NOT NULL UNIQUE ON CONFLICT IGNORE, 'status' TEXT NOT NULL, 'node' INTEGER NOT NULL UNIQUE)";
stat.executeUpdate(q);
//
// Concours Jaguar Table
//
stat.executeUpdate("drop table if exists ConcoursJaguars");
q = "create table ConcoursJaguars ('jaguar_id' INTEGER PRIMARY KEY AUTOINCREMENT , 'class' TEXT NOT NULL, 'year' TEXT NOT NULL, 'description' TEXT NOT NULL, 'Color' TEXT, 'plate' TEXT, 'node' INTEGER NOT NULL UNIQUE)";
stat.executeUpdate(q);
//
// Entry Table ( a Relationship or "link" between Personnel & Jaguars
//
stat.executeUpdate("drop table if exists ConcoursEntries");
q = "create table ConcoursEntries (entry_name TEXT NOT NULL, personnel_id INTEGER NOT NULL, jaguar_id INTEGER NOT NULL, UNIQUE (personnel_id, jaguar_id), FOREIGN KEY (personnel_id) REFERENCES ConcoursPersonnel (Personnel_ID), FOREIGN KEY (jaguar_id) REFERENCES ConcoursPersonnel (jaguar_id))";
stat.executeUpdate(q);
String EntriesCSV = strPath + "\\EntriesCsv.txt" ;
strStatus = "O"; // not in the CSV data so set to Owner
try {
reader = new CSVReader(new FileReader(EntriesCSV ));
iLine = 0;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
// System.out.println(nextLine[0] + nextLine[1] );
if (iLine > 0){
strEntryName = nextLine[0];
strClass = nextLine[1];
intYear= Integer.parseInt(nextLine[2]);
strDescription= nextLine[3];
strOwnerFirst= nextLine[4];
strOwnerLast= nextLine[5];
intJCNA = Integer.parseInt(nextLine[6]) ;
strColor= nextLine[7];
strPlate= nextLine[8];
intNode= Integer.parseInt(nextLine[9]); // Since Jaguars are 1-to-1 with Entries this is used as Node number for both. However, it can't be used for Personnel Node
//
// Load Owners into Personnel Table
//
Statement s = aConn.createStatement();
r = s.executeQuery("SELECT COUNT(*) AS rowcount FROM ConcoursPersonnel");
r.next();
intPersonnelNode = r.getInt("rowcount") +1 ; // Assignes Personnel node numbers as a continuous sequence
prep = aConn.prepareStatement( "insert into ConcoursPersonnel ('ownerfirst', 'ownerlast', 'jcna', 'status', 'node' ) values ( ?, ?, ?, ?, ?);");
//prep.setString(1, strEntryName); // note that the comma seems not to be a problem
prep.setString(1,strOwnerFirst);
prep.setString(2,strOwnerLast);
prep.setInt(3,intJCNA);
prep.setString(4,strStatus);
prep.setInt(5,intPersonnelNode);
prep.addBatch();
aConn.setAutoCommit(false); // starts transaction
prep.executeBatch();
aConn.setAutoCommit(true); // ends transaction
aConn.setAutoCommit(false); // starts transaction
stat = aConn.createStatement();
generatedKeys = stat.executeQuery("SELECT last_insert_rowid()");
intPersonnel_id = 0L; // won't be used
if (generatedKeys.next()) {
intPersonnel_id = generatedKeys.getLong(1);
}
else{
System.out.println("No Personnel ID found in LoadConcoursEntriesTable");
System.exit(-1);
}
aConn.setAutoCommit(true); // Commits transaction.
//
// Load Entry cars into the ConcoursJaguars table
//
prep = aConn.prepareStatement( "insert into ConcoursJaguars ('class', 'year', 'description', 'color', 'plate', 'node' ) values ( ?, ?, ?, ?, ?, ?);");
prep.setString(1,strClass);
prep.setInt(2,intYear);
prep.setString(3,strDescription);
prep.setString(4,strColor);
prep.setString(5,strPlate);
prep.setInt(6,intNode); //
prep.addBatch();
aConn.setAutoCommit(false);
prep.executeBatch();
aConn.setAutoCommit(true);
q = "select jaguar_id from ConcoursJaguars where node == " + intNode + ";";
rs = stat.executeQuery(q);
intJaguar_id = rs.getLong("jaguar_id");
prep = aConn.prepareStatement( "insert into ConcoursEntries (entry_name, personnel_id, jaguar_id) values ( ?, ?, ?);");
//prep.setString(1, strEntryName); // note that the comma seems not to be a problem
prep.setString(1,strEntryName);
prep.setLong(2,intPersonnel_id);
prep.setLong(3,intJaguar_id);
prep.addBatch();
aConn.setAutoCommit(false);
prep.executeBatch();
aConn.setAutoCommit(true);
}
iLine++;
}
} catch (FileNotFoundException ex) {
Logger.getLogger(Entries.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex) {
Logger.getLogger(Entries.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(LoadSQLiteConcoursDatabase.class.getName()).log(Level.SEVERE, null, ex);
}
}
Setting autoCommit to true is actually executes commit within the loop. Thus, there is no batch operation running: you commit every time you iterate through the loop. To have a batch operation you need to:
add aConn.setAutoCommit(false); before your while operator
remove lines wrapping prep.executeBatch(); (i.e., aConn.setAutoCommit(false); and aConn.setAutoCommit(true);)
move prep.executeBatch(); out of your loop
add line with aConn.commit(); right after your while loop
aConn.setAutoCommit(false);
PreparedStatement prep = aConn.prepareStatement( "insert into JCNAClasses ('division', 'class', 'description', 'note', 'node') values ( ?, ?, ?, ?, ?);");
while ((nextLine = reader.readNext()) != null) {
if (iLine > 0){
// some preparations go here
prep.addBatch();
}
iLine++;
}
prep.executeBatch();
aConn.commit();
You are recreating your PreparedStatement everytime you go through your loop. This should be moved to just before the while loop.
Also the setAutoCommit option should be set once outside the loop, and then you commit your statements when you hit a reasonable ceiling or when you are done.
You can see an example posted here: Java: Insert multiple rows into MySQL with PreparedStatement

Why do I get ORA-01438 error

I have an EMPLOYEE table with column(primary key) EMPLOYEE_ID NUMBER(6)
And the following method to check whether an employee record exists in the table
public boolean exists(int employeeId) {
Connection con = ConnectionManager.getConnection();
boolean exists = false;
String stmt = "select EMPLOYEE_ID , FIRST_NAME , LAST_NAME , EMAIL , PHONE_NUMBER ,"
+ "HIRE_DATE , JOB_ID , SALARY , COMMISSION_PCT , MANAGER_ID , DEPARTMENT_ID "
+ " FROM EMPLOYEES where cast (EMPLOYEE_ID as Number(2)) = ?";
PreparedStatement pstmt = null;
try {
pstmt = con.prepareStatement(stmt);
pstmt.setInt(1, employeeId);
pstmt.execute(); //Returns true if the first object that the query returns is a ResultSet object
exists = pstmt.getResultSet().next();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
pstmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return exists;
}
Now, in the SQL statement when I use cast (EMPLOYEE_ID as Number(2)) = ? and call the exists method with input 2 employeeOperations.exists(2); I get the following error
ORA-01438: value larger than specified precision allowed for this column
Why does this error occur, even when the size of the column is large enough?
It works well with input of 4 digits or more(maximum length of employee_id present in table is 4) i.e. cast (EMPLOYEE_ID as Number(4)) = ? works.
When casting from NUMBER(6) to NUMBER(2), the records having EMPLOYEE_ID greater than 99 are causing the error (for example Oracle cannot put 100 in \d{2}).
Quick fix, use this request:
SELECT COUNT(1) FROM EMPLOYEES WHERE EMPLOYEE_ID = ?

How to insert reference values in database using JDBC?

I am trying to insert values into Oracle 10g database using the code below but its giving an error of "Missing Expression" on execution. I have to pass reference values into the insert clause but do not know the exact syntax or way of doing it.
Please help me through this.
Thanks.
Student Table:-
Sid VARCHAR2(200) PRIMARY KEY CHECK(Sid>0),
Pass_word VARCHAR2(10) NOT NULL,
S_name VARCHAR2(20) NOT NULL,
G_name VARCHAR2(20) ,
Branch VARCHAR2(10) NOT NULL,
D_company VARCHAR2(20) ,
B_Percent INT NOT NULL CHECK(B_Percent<100),
twelth_percent INT NOT NULL CHECK(twelth_percent<100),
tenth_percent INT NOT NULL CHECK(tenth_percent<100),
Certify VARCHAR2(30),
Semester INT NOT NULL CHECK(Semester<9),
D_Birth DATE NOT NULL,
Sex VARCHAR2(6) NOT NULL
CODE:
Connection connection = null;
try
{
// Load the JDBC driver
String driverName = "sun.jdbc.odbc.JdbcOdbcDriver";
Class.forName(driverName);
connection = DriverManager.getConnection("jdbc:odbc:placement","siddharth","sid");
studentID = StudentID.getText();
spassword = PasswordField.getPassword();
studentname = NameField.getText();
Gname = GuardianField.getText();
branch = BranchField.getText();
dcompany = DcompanyField.getText();
bpercent = BtechField1.getText();
twelthpercent = TwelthField.getText();
tenthpercent = TenthField.getText();
semester = SemesterField.getText();
certify = CertificationField.getText();
sex = SexCombo.getActionCommand();
date = (Date) DateTextField1.getValue();
Statement stmt = connection.createStatement();
stmt.executeUpdate("insert into student " +"(sid,pass_word,s_name,g_name,branch,d_company,b_percent,twelth_percent,tenth_percent,certify,semester,d_birth,sex)"+
"values(studentID, spassword,studentname,Gname,branch,dcompany,bpercent,twelthpercent,tenthpercent,certify,semester,date,sex)" );
stmt.close();
connection.close();
}
catch (ClassNotFoundException e) {
// Could not find the database driver
JOptionPane.showMessageDialog(null,e);
}
catch (SQLException e) {
// Could not connect to the database
JOptionPane.showMessageDialog(null,e);
}
Currently your SQL statement looks like:
insert into student (sid, pass_word, ...) values (studentID, spassword, ...)
The variable names mean nothing to the SQL itself.
You should use a prepared statement. For example, your SQL should look like this:
insert into student (sid, pass_word, ...) values (?, ?, ...)
and then you use:
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, studentID);
stmt.setString(2, spassword);
// etc
See the JDBC tutorial on prepared statements for more information.
To be on the safe side you should use prepared statements.
Prepare the Query String
String updateString = "update " + dbName + ".COFFEES " +
"set SALES = ? where COF_NAME = ?";
Create a PrepartedStatement with this query:
updateSales = connnection.prepareStatement(updateString);
Fill the ? spaceholders with you values:
updateSales.setInt(1, myVariable1);
updateSales.setString(2, myVariable2);
execute the Query
updateSales.executeUpdate();

Categories