Error setting mysql primary key field with preparedStatement - java

This is my code for inserting a row. The columns are: primary id, name, and artist.
Am I passing the primary id correctly because it keeps on giving me an error? It is set to one and it increments every time a row is added.
try {
//Database
String query = "INSERT INTO lyrics1(lyrics1_id, name, artist) values(?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(2, nameOfSong.getText()); // set input parameter 2
statement.setString(3, artist.getText());
statement.setLong(i, i);
ResultSet rs = statement.executeQuery("SELECT * FROM lyrics1");
while (rs.next()){
System.out.println(rs.getString(1));
}
statement.execute();
rs.close();
statement.close();
connection.close();
i++;
} catch (SQLException insertException) {
displaySQLError(insertException);
}
The error is:
SQLException: No value specified for parameter 1 SQLState: 07001 VendorError: 0

If your primary key is AUTO_INCREMENT, which it sounds like it is, you do not pass it with the INSERT statement, it is handled automatically for you. This would be what you want to do:
INSERT INTO lyrics1(name, artist)
VALUES(?, ?)

(This assumes your primary key isn't AUTO_INCREMENT and that you're passing it for a reason.)
I think you have a simple typo:
statement.setLong(i, i);
should probably be
statement.setLong(1, i);
// ^-- 1, not i
Being an old fuddy-duddy, I'd also probably move that statement above the other two so you're doing them in order.

If you have auto_increment in primary key:
String query = "INSERT INTO lyrics1(name, artist) values(?, ?)";

Don't forget to add the quotes when inserting a TEXT or VARCHAR value, like "INSERT INTO lyrics1(lyrics1_id, name, artist) VALUES ("id","name","artist").
Also, if the key is auto-incremental, do not pass it, the SQL will do it by itself. The query should then be "INSERT INTO lyrics1(name, artist) VALUES ("name","artist")."

As far as I know, you should have a ; in the string at the end like so:
String query = "INSERT INTO lyrics1(lyrics1_id, name, artist) values(?, ?, ?)";
however, it may work anyway.

You have a typo on the line you setting a value for primary key:
statement.setLong(i, i);
Here, did you see the first argument, it is i instead of 1. So it has to be changed to
statement.setLong(1, i);
But, if you ran the program for a second time, if the value of your i is initialized to a constant, you will get a primary key violation exception. Since, you are using MySQL, and if you used AUTO_INCREMENT for primary key column, then you can avoid that field in INSERT query. MySQL will automatically assign a value for the field. So you may use something like this:
INSERT INTO lyrics1(name, artist) values(?, ?)

Related

Duplicate entry for primary key - registration form

I have one simple registraton form with jsp, servlet and mysql. But, I can register only one user, then i got this error:
Severe: Message: Duplicate entry '1' for key 'PRIMARY'. Of course, when I delete that user from database I can create again but just one user. Also, I put auto increment on that column:
CREATE TABLE user (id int(3) NOT NULL AUTO_INCREMENT ...
This is also my method for insert in db:
public class UserDAO {
public int registerUser(User User) throws ClassNotFoundException, SQLException {
String INSERT_USERS_SQL = "INSERT INTO user"
+ " (id, firstName, lastName, username, password, email) VALUES "
+ " (?, ?, ?, ?, ?, ?)";
int result = 0;
Class.forName("com.mysql.jdbc.Driver");
try (Connection connection = DriverManager
.getConnection("jdbc:mysql://localhost:3306/cs230projekat","root","");
// Step 2:Create a statement using connection object
PreparedStatement preparedStatement = connection.prepareStatement(INSERT_USERS_SQL)) {
preparedStatement.setInt(1, 1);
preparedStatement.setString(2, User.getFirstName());
preparedStatement.setString(3, User.getLastName());
preparedStatement.setString(4, User.getUsername());
preparedStatement.setString(5, User.getPassword());
preparedStatement.setString(6, User.getEmail());
System.out.println(preparedStatement);
// Step 3: Execute the query or update query
result = preparedStatement.executeUpdate();
} catch (SQLException e) {
// process sql exception
printSQLException(e);
}
return result;
}
Thank you.
You are always setting the value of your id column to 1 via preparedStatement.setInt(1, 1). Since you say you have an auto-increment on the id column, remove id from your SQL, remove the aforementioned line and adjust the column indexes (first arguments) for all the other setString() method calls.
With auto increment set you don’t have to specify the ‘id’ column in your sql insert statements.
Here’s some information on the auto increment from MySQL’s website: https://dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html
From your code it looks like you are inserting the value 1 always for the id column, try implementing the autoGenerate properly. For more help, you can have a look on similar implementation

Prepared statement and serial data type

This is my PostgreSQL code:
CREATE TABLE "user" (
id serial UNIQUE,
username varchar,
password varchar,
email varchar,
);
I want to create Java method, which adds new user to my table user:
public static void addUser(Connection con) throws SQLException {
String sql = "INSERT INTO user VALUES (?, ?, ?)";
try(PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, "test");
ps.setString(2, "test");
ps.setString(3, "test#email.com");
ps.executeUpdate();
}
}
}
Because column id is serial, I don't create prepared statement for this column (even without java, I would make insert only with remaining values, since id would be generated automatically). Hovewer, when I run this code, I get the following error:
ERROR: column "id" is of type integer but expression is of type character varying
What am I doing wrong?
Always specify the target columns in an INSERT statement. And as user is a reserved keyword, you have to quote it (but it would be better if you found a different name)
String sql = "INSERT INTO \"user\" (username, password, email) VALUES (?, ?, ?)";

Java JDBC Error Insert into

Here is the code:
String sqlstatment = "INSERT INTO order (orderedBy, totalItems, totalPrice) "+
"VALUES (?, ?, ?);";
ResultSet keys = null;
try (
PreparedStatement stmt = conn.prepareStatement(sqlstatment, Statement.RETURN_GENERATED_KEYS);
){
stmt.setInt(1, 1);
stmt.setInt(2, 3);
stmt.setInt(3, 5);
int affected = stmt.executeUpdate();
if (affected == 1){
keys = stmt.getGeneratedKeys();
keys.next();
int newKey = keys.getInt(1);
orderBean.setOrderID(newKey);
}else{
System.out.println("An Error has ocurred while creating the Order.");
}
}catch (SQLException e){
System.err.println(e.getMessage());
}finally{
if (keys != null) keys.close();
}
And when I run the code I get this error:
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 'order (orderedBy, totalItems, totalPrice) VALUES (1, 3, 5)' at line 1
I'm not entirely sure why I get the error so if you know that would be great.
order is a reserved word, try
String sqlstatment = "INSERT INTO \"order\" (orderedBy, totalItems, totalPrice) "+
"VALUES (?, ?, ?);";
Your query contains a RESERVED KEYWORD order as your table name. MySQL documentation clearly suggests that use of such keywords should always be avoided, if they need to be used then it has to be with the use of backticks as shown below '`'.
Certain objects within MySQL, including database, table, index, column, alias, view, stored procedure, partition, tablespace, and other object names are known as identifiers.
If an identifier contains special characters or is a reserved word, you must quote it whenever you refer to it.
Your query that gets assigned to a String in turn should be changed to the following to resolve this error!
"INSERT INTO \"order\" (orderedBy, totalItems, totalPrice) VALUES (?, ?, ?);"
The following is a documentation link to the reserved keywords for MySQL -> Documentation
Hope this helps!

General error in JDBC(updating database)

private void sUpdateBtnActionPerformed(java.awt.event.ActionEvent evt) {
String query = "UPDATE Student SET lastname = ?, firstname = ?, course = ?, yearlvl = ?, username = ?, password = ?";
dbConn = DbConnection.dbConnect();
prepState = dbConn.prepareStatement(query);
prepState.setString(1, sLnTf.getText());
prepState.setString(2, sFnTf.getText());
prepState.setString(3, courseTf.getText());
prepState.setInt(4, Integer.parseInt(yearLvlTf.getText()));
prepState.setString(5, sUserTf.getText());
prepState.setString(6, sPassTf.getText());
prepState.executeUpdate();
}catch(Exception e){
appendEvent(sdf.format(new Date()) + " Error: " + e);
}
}
Method for connecting to the database:
import java.sql.*;
import javax.swing.*;
public class DbConnection {
Connection dbConn = null;
public static Connection dbConnect(){
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection dbConn = DriverManager.getConnection("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)}; DBQ=H:/Integ Ongoing Project/_Midterm Project/Server/src/database/Database.accdb");
return dbConn;
}catch(Exception e){
System.out.println(e.getMessage());
return null;
}
}
}
Password is a reserved word. If you must keep that as your field name, enclose it in brackets in your query to reduce the likelihood of confusing the database engine.
UPDATE Student
SET
lastname = ?,
firstname = ?,
course = ?,
yearlvl = ?,
username = ?,
[password] = ?
WHERE student_id = ?
Note I included a WHERE clause, as Stephen suggested, because it seems unlikely you would want those same field values applied to every row in the Student table. I used student_id as a placeholder name for the table's primary key ... the field which uniquely identifies each row. My intention is that you revise the WHERE clause to reference the primary key for the student whose record you want to alter.
If you're actually trying to add a new record, instead of update an existing record (or records), use an INSERT statement.
INSERT INTO Student (
lastname,
firstname,
course,
yearlvl,
username,
[password]
)
VALUES (
?,
?,
?,
?,
?,
?
)
And if you have autonumber as the data type of your primary key, the db engine will manage it for you.
I think that the problem is that your SQL statement is missing a WHERE clause. (I know that WHERE is optional in some dialects of SQL ... but a missing WHERE makes no sense to me here.)
The reason I think this is wrong is that even if the SQL dialect allows this, it is not clear which row of the table you are "setting". Even if the SQL engine can figure it out, a WHERE clause makes it a lot clearer. (And the fact that it "works" in the other case, doesn't mean that it is necessarily correct.)
Another thing that is potentially the cause of the problem is that "password" is a reserved word in some SQL dialects. Change the column name, or escape it.
Finally, the actual SQL error message should be in the exception stacktrace, or failing that in the log files. Those should be the first places to look if you are trying to find a problem in your database code. Look for the evidence ... rather than hoping someone else guess the right answer for you.

Using Oracle sequence to insert log id into 2 tables from jdbc?

I am using oracle sequence for inserting log id into tableA as follows,
String SQL_PREP_INSERT = "INSERT INTO tableA (LOG_ID,USER_ID,EXEC_TIME) VALUES"
+ " (logid_seq.nextval, ?, ?)";
Then getting the recently inserted value,
String SQL_PREP_SEL = "SELECT max(LOG_ID) FROM tableA ";
stmt = con.prepareStatement(SQL_PREP_SEL);
stmt.execute();
ResultSet rs = stmt.getResultSet();
if (rs.next()) {
logid = rs.getInt(1);
}
And inserting it into tableB,
String SQL_PREP_INSERT_DETAIL = "INSERT INTO tableB (LOG_ID, RESPONSE_CODE, RESPONSE_MSG) VALUES"
+ " (?, ?)";
stmt = con.prepareStatement(SQL_PREP_INSERT_DETAIL);
stmt.setInt(1, logid);
stmt.setString(2, respCode);
stmt.setString(3, respMsg);
stmt.execute();
Is there a way to generate sequence in Java instead of Oracle and insert into both tables at once, instead of selecting from tableA and inserting into tableB?
In general, selecting the MAX(log_id) is not going to give you the same value that logid_seq.nextval provided. Assuming that this is a multi-user system, some other user could have inserted another row with a larger log_id value than the row you just inserted before your query is executed.
Assuming that both INSERT statements are run in the same session, the simplest option is probably to use the logid_seq.currval in the second INSERT statement. currval will return the last value of the sequence that was returned to the current session so it will always return the same value that was generated by the nextval call in the first statement.
INSERT INTO tableB (LOG_ID, RESPONSE_CODE, RESPONSE_MSG)
VALUES( logid_seq.currval, ?, ? )
Alternatively, you could use the RETURNING clause in your first statement to fetch the sequence value into a local variable and use that in the second INSERT statement. But that is probably more work than simply using the currval.
String QUERY = "INSERT INTO students "+
" VALUES (student_seq.NEXTVAL,"+
" 'Harry', 'harry#hogwarts.edu', '31-July-1980')";
// load oracle driver
Class.forName("oracle.jdbc.driver.OracleDriver");
// get database connection from connection string
Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:sample", "scott", "tiger");
// prepare statement to execute insert query
// note the 2nd argument passed to prepareStatement() method
// pass name of primary key column, in this case student_id is
// generated from sequence
PreparedStatement ps = connection.prepareStatement(QUERY,
new String[] { "student_id" });
// local variable to hold auto generated student id
Long studentId = null;
// execute the insert statement, if success get the primary key value
if (ps.executeUpdate() > 0) {
// getGeneratedKeys() returns result set of keys that were auto
// generated
// in our case student_id column
ResultSet generatedKeys = ps.getGeneratedKeys();
// if resultset has data, get the primary key value
// of last inserted record
if (null != generatedKeys && generatedKeys.next()) {
// voila! we got student id which was generated from sequence
studentId = generatedKeys.getLong(1);
}
}

Categories